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: Simulator Enhancements (03/13/24)

Pages: 1 ... 313 314 [315] 316 317 ... 706

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

Alex

  • Administrator
  • Admiral
  • *****
  • Posts: 23988
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #4710 on: July 21, 2019, 08:00:15 AM »

What method are you calling this in? applyEffectsBeforeShipCreation() or applyEffectsAfterShipCreation()? The former has a chance of working (not 100% sure on how the order of operations works out); the latter has no chance since at that point the modules will have already been spawned.
Logged

AxleMC131

  • Admiral
  • *****
  • Posts: 1722
  • Amateur World-Builder
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #4711 on: July 21, 2019, 11:17:41 PM »

What method are you calling this in? applyEffectsBeforeShipCreation() or applyEffectsAfterShipCreation()? The former has a chance of working (not 100% sure on how the order of operations works out); the latter has no chance since at that point the modules will have already been spawned.

Ahhh, that would explain it. Yes I've been calling this in applyEffectsAfter...() and scratching my head. I'll try it in applyEffectsBefore...() and see if that works, thank you!
Logged

xenoargh

  • Admiral
  • *****
  • Posts: 5078
  • naively breaking things!
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #4712 on: July 22, 2019, 03:20:27 PM »

Please let us know; that's an interesting one, in terms of where it's meant to be applied; if I'm reading that code correctly, it was designed largely for CampaignFleetAPI manipulations.
Logged
Please check out my SS projects :)
Xeno's Mod Pack

AxleMC131

  • Admiral
  • *****
  • Posts: 1722
  • Amateur World-Builder
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #4713 on: July 23, 2019, 12:24:19 AM »

Hum. Problem: Trying to use "setModuleVariant()" in applyEffectsBefore...() is giving me a null warning because it's a method I'm applying to the ship's variant - and in applyEffectsBefore...(), the variant API instance doesn't necessarily exist yet.  ???

Code: java
@Override
public void applyEffectsBeforeShipCreation(HullSize hullSize, MutableShipStatsAPI stats, String id) {

    ShipAPI ship = null;
    if (stats.getEntity() instanceof ShipAPI) {
        ship = (ShipAPI) stats.getEntity();
    }

    if (SAVED_DATA.get(id) != null) {
        SAVED_DATA.put(id, "dara_unity_module0_Standard");
    }

    String variantId = SAVED_DATA.get(id);
    ShipVariantAPI thisModuleVariant = Global.getSettings().getVariant(variantId);

--> ship.getVariant().setModuleVariant("WS0001", thisModuleVariant);
    // This last line is causing a null warn. Netbeans is underlining the ".getVariant" bit, saying it's dereferencing a possible null pointer.
}
(SAVED_DATA is storing the variant ID of the module from elsewhere, don't worry about that.)

Any ways to get around this? Is it possible to make the last line only run once the variant has been created? I've tried putting it inside a "if (ship.getVariant() != null) {}" check, but it did the same thing on the if check.
Logged

Alex

  • Administrator
  • Admiral
  • *****
  • Posts: 23988
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #4714 on: July 23, 2019, 08:48:27 AM »

Hmm. Try stats.getVariant(), perhaps?

The ship might not actually be null at this point, I'm not 100% sure. Netbeans is just giving you a warning; that doesn't mean the code wouldn't work.

The "correct" way to code something like this would be, say:

ShipAPI ship = null;
if (stats.getEntity() instanceof ShipAPI) {
    ship = (ShipAPI) stats.getEntity();
} else {
    return;
}

But mainly that would just make it fail without crashing. If ship is null at that point and you're relying on it not being null to retrieve the vairant...
Logged

xenoargh

  • Admiral
  • *****
  • Posts: 5078
  • naively breaking things!
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #4715 on: July 23, 2019, 04:59:14 PM »

In general, when NetBeans gives that warning, I address it; you just don't know when it'll be bye-bye, gamestate.

But it should be clean:

   @Override
   public void applyEffectsBeforeShipCreation(HullSize hullSize, MutableShipStatsAPI stats, String id) {
      ShipVariantAPI thisVariant = stats.getVariant();
      ShipVariantAPI thisModuleVariant = Global.getSettings().getVariant("variant_we_want");
      thisVariant.setModuleVariant("WS0001", thisModuleVariant);
        }

Logged
Please check out my SS projects :)
Xeno's Mod Pack

AxleMC131

  • Admiral
  • *****
  • Posts: 1722
  • Amateur World-Builder
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #4716 on: July 23, 2019, 11:14:17 PM »

Netbeans is just giving you a warning; that doesn't mean the code wouldn't work.

Oh, no it definitely didn't work. :-[ I usually ignore Netbeans' yellow underlines, but in this case it was actually right - the mission with the test ship failed to load, and the "WARN" info in the game log pointed my to the line highlighted in my previous comment.

Hmm. Try stats.getVariant(), perhaps?

...

The "correct" way to code something like this would be, say:

ShipAPI ship = null;
if (stats.getEntity() instanceof ShipAPI) {
    ship = (ShipAPI) stats.getEntity();
} else {
    return;
}

But mainly that would just make it fail without crashing. If ship is null at that point and you're relying on it not being null to retrieve the vairant...

... I didn't know you could get a variant directly from the MutableStats instance. ??? That's funky.

I'll try that check, but I've gotta ask: If an instance of ShipAPI exists, must it have a variant? I assumed that the ship existed but its variant didn't, is that not the case? Is it actually that during my check the ship itself doesn't exist yet?
« Last Edit: July 23, 2019, 11:18:39 PM by AxleMC131 »
Logged

AxleMC131

  • Admiral
  • *****
  • Posts: 1722
  • Amateur World-Builder
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #4717 on: July 24, 2019, 01:10:03 AM »

Update: Wow, so yeah I can get the variant from the stats instance ("wat"), however I'm so far unable to change the module using this method. I'm not really sure if I've got it set up right, but either way the advice so far appears to have helped, so thanks muchly for that.



Further update: Yeah I think the function just straight-up isn't working. I've taken out a bunch of the mutable/dynamic bits and am now simply trying to force the module to change to a different one in applyEffectsBefore...(), and nothing is happening.  :-\ Might be a lost cause unfortunately.
« Last Edit: July 24, 2019, 02:05:22 AM by AxleMC131 »
Logged

Histidine

  • Admiral
  • *****
  • Posts: 4661
    • View Profile
    • GitHub profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #4718 on: July 24, 2019, 04:56:52 AM »

The NetBeans warning is indeed because ship might be null.
In the displayed code, it's assigned to null at start and only gets assigned to something else if a certain check passes. The IDE thus sees that it can't count on ship not being null when the code tries to use it.
Logged

lethargie

  • Commander
  • ***
  • Posts: 183
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #4719 on: July 24, 2019, 06:32:11 AM »

I am really bad at moding, but I do have a question.

I can add a .faction file with only the "portrait" (variable?, property? i dont know how to name it) defined to append custom portrait to the hegemony. But if I wanted to replace existing portrait (so the old one wouldnt show up) how would I do it?

At least it was my understanding that a mod hegemony.faction only appended to the existing one.
Logged

Alex

  • Administrator
  • Admiral
  • *****
  • Posts: 23988
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #4720 on: July 24, 2019, 09:28:21 AM »

Oh, no it definitely didn't work. :-[ I usually ignore Netbeans' yellow underlines, but in this case it was actually right - the mission with the test ship failed to load, and the "WARN" info in the game log pointed my to the line highlighted in my previous comment.

I was just saying that this doesn't *necessarily* mean it won't work. It could be, for example, that the conditions of the if statement that assign a value to it are always met, but Netbeans might not know about that depending on what the conditions are.

I'll try that check, but I've gotta ask: If an instance of ShipAPI exists, must it have a variant? I assumed that the ship existed but its variant didn't, is that not the case? Is it actually that during my check the ship itself doesn't exist yet?

Yeah, a ship is going to have a variant. (Unless bugs / some kind of weird edge case / etc, of course.)


I am really bad at moding, but I do have a question.

I can add a .faction file with only the "portrait" (variable?, property? i dont know how to name it) defined to append custom portrait to the hegemony. But if I wanted to replace existing portrait (so the old one wouldnt show up) how would I do it?

At least it was my understanding that a mod hegemony.faction only appended to the existing one.

You could have the portrait .pngs be named the same as the ones in the faction (which may not be desirable as I think some portraits are used across multiple factions). You could also add the .faction file to a "replace" section in your mod_info.json file, though that means you'd need to provide the full faction file, not just the portraits section.
Logged

xenoargh

  • Admiral
  • *****
  • Posts: 5078
  • naively breaking things!
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #4721 on: July 24, 2019, 09:52:54 AM »

Rats, I thought that would be clean and "just work", Axle.

So, let's look at the case where it's invoked.  The only place in the API where that occurs is for Stations in CoreAutoFitPlugin, specifically this function:

Code
	protected Set<String> availableMods;
protected Set<String> slotsToSkip = new HashSet<String>();
protected Set<Integer> baysToSkip = new HashSet<Integer>();
protected boolean fittingModule = false;
protected int missilesWithAmmoOnCurrent = 0;
public void doFit(ShipVariantAPI current, ShipVariantAPI target, AutofitPluginDelegate delegate) {
if (!fittingModule) {
fittedWeapons.clear();
fittedFighters.clear();

randomize = isChecked(RANDOMIZE);

availableMods = new LinkedHashSet<String>(delegate.getAvailableHullmods());
}

current.getStationModules().putAll(target.getStationModules());

int index = 0;
for (String slotId : current.getStationModules().keySet()) {
ShipVariantAPI moduleCurrent = current.getModuleVariant(slotId);
if (moduleCurrent == null) continue;
if (moduleCurrent.isStockVariant()) {
moduleCurrent = moduleCurrent.clone();
moduleCurrent.setSource(VariantSource.REFIT);
moduleCurrent.setHullVariantId(moduleCurrent.getHullVariantId() + "_" + index);
}
index++;

// String variantId = current.getStationModules().get(slotId);
// ShipVariantAPI moduleTarget = Global.getSettings().getVariant(variantId);
ShipVariantAPI moduleTarget = target.getModuleVariant(slotId);
if (moduleTarget == null) continue;

fittingModule = true;
doFit(moduleCurrent, moduleTarget, delegate);
fittingModule = false;

current.setModuleVariant(slotId, moduleCurrent);
}
current.setSource(VariantSource.REFIT);

weaponFilterSeed = random.nextLong();

emptyWingTarget = null;
if (delegate.getAvailableFighters().size() > 0) {
emptyWingTarget = delegate.getAvailableFighters().get(random.nextInt(delegate.getAvailableFighters().size())).getId();
}

altWeaponCats.clear();
altFighterCats.clear();

slotsToSkip.clear();
baysToSkip.clear();

missilesWithAmmoOnCurrent = 0;

boolean strip = isChecked(STRIP);
if (strip) {
stripWeapons(current, delegate);
stripFighters(current, delegate);

current.setNumFluxCapacitors(0);
current.setNumFluxVents(0);
if (delegate.isPlayerCampaignRefit()) {
for (String modId : current.getNonBuiltInHullmods()) {
boolean canRemove = delegate.canAddRemoveHullmodInPlayerCampaignRefit(modId);
if (canRemove) {
current.removeMod(modId);
}
}
} else {
current.clearHullMods();
}
} else {
slotsToSkip.addAll(current.getFittedWeaponSlots());
for (int i = 0; i < 20; i++) {
String wingId = current.getWingId(i);
if (wingId != null && !wingId.isEmpty()) {
baysToSkip.add(i);
}
}
}

//boolean randomize = isChecked(RANDOMIZE);


boolean reinforcedHull = isChecked(ALWAYS_REINFORCED_HULL);
boolean blastDoors = isChecked(ALWAYS_BLAST_DOORS);

if (reinforcedHull) {
addHullmods(current, delegate, HullMods.REINFORCEDHULL);
}
if (blastDoors) {
addHullmods(current, delegate, HullMods.BLAST_DOORS);
}

addHullmods(current, delegate, target.getNonBuiltInHullmods().toArray(new String[0]));

int addedRandomHullmodPts = 0;
if (randomize) {
addedRandomHullmodPts = addRandomizedHullmodsPre(current, delegate);
}


fitFighters(current, target, false, delegate);
fitWeapons(current, target, false, delegate);

if (current.hasHullMod(HullMods.FRAGILE_SUBSYSTEMS) &&
(current.getHullSize() == HullSize.FRIGATE || current.getHullSize() == HullSize.DESTROYER)) {
addHullmods(current, delegate, HullMods.HARDENED_SUBSYSTEMS);
}


float addedMax = current.getHullSpec().getOrdnancePoints(stats) * 0.1f;
if (randomize && addedRandomHullmodPts <= addedMax) {
addRandomizedHullmodsPost(current, delegate);
}

float ventsCapsFraction = 1f;
boolean upgrade = isChecked(UPGRADE);
if (upgrade) {
ventsCapsFraction = 0.5f;
//ventsCapsFraction = 0f;
}

addVentsAndCaps(current, target, ventsCapsFraction);


// now that we're at the target level of vents and caps
// see if we can upgrade some weapons
if (upgrade) {
fitFighters(current, target, true, delegate);
fitWeapons(current, target, true, delegate);
addVentsAndCaps(current, target, 1f - ventsCapsFraction);
}

// float dissipation = current.getHullSpec().getFluxDissipation() + current.getNumFluxVents() * 10f;
// float generation = 0f;
// for (String slotId : current.getFittedWeaponSlots()) {
// WeaponSpecAPI spec = current.getWeaponSpec(slotId);
// generation += spec.getDerivedStats().getSustainedFluxPerSecond();
// }

addHullmods(current, delegate, HullMods.REINFORCEDHULL, HullMods.BLAST_DOORS, HullMods.HARDENED_SUBSYSTEMS);
addExtraVentsAndCaps(current, target);
addModsWithSpareOPIfAny(current, target, delegate);

current.setVariantDisplayName(target.getDisplayName());

current.getWeaponGroups().clear();
for (WeaponGroupSpec group : target.getWeaponGroups()) {
WeaponGroupSpec copy = new WeaponGroupSpec(group.getType());
copy.setAutofireOnByDefault(group.isAutofireOnByDefault());
for (String slotId : group.getSlots()) {
if (current.getWeaponId(slotId) != null) {
copy.addSlot(slotId);
}
}
if (!copy.getSlots().isEmpty()) {
current.addWeaponGroup(copy);
}
}

boolean player = fleetCommander != null && fleetCommander.isPlayer();

if (player) {
if (current.getWeaponGroups().isEmpty() || randomize || current.hasUnassignedWeapons()) {
current.autoGenerateWeaponGroups();
}
//current.assignUnassignedWeapons();
} else {
current.getWeaponGroups().clear(); // will get auto-assigned when deployed in combat; until then don't care
}

if (!fittingModule) {
delegate.syncUIWithVariant();
}
}


There's a lot going here; it'll take a me a little bit to unpack.  But we know it actually works here, if not in your context.

But it's calling for AutofitPluginDelegate, is in AutofitPlugin; it might be necessary to have that in this, since it appears there are some UI calls, etc. going on when a new Module is installed.

AutofitPluginDelegate:
Code
	public interface AutofitPluginDelegate {
void fitFighterInSlot(int index, AvailableFighter fighter, ShipVariantAPI variant);
void clearFighterSlot(int index, ShipVariantAPI variant);
void fitWeaponInSlot(WeaponSlotAPI slot, AvailableWeapon weapon, ShipVariantAPI variant);
void clearWeaponSlot(WeaponSlotAPI slot, ShipVariantAPI variant);

List<AvailableWeapon> getAvailableWeapons();
List<AvailableFighter> getAvailableFighters();

boolean isPriority(WeaponSpecAPI weapon);
boolean isPriority(FighterWingSpecAPI wing);

List<String> getAvailableHullmods();
void syncUIWithVariant();

ShipAPI getShip();

FactionAPI getFaction();

boolean isPlayerCampaignRefit();
boolean canAddRemoveHullmodInPlayerCampaignRefit(String modId);
}
Logged
Please check out my SS projects :)
Xeno's Mod Pack

xenoargh

  • Admiral
  • *****
  • Posts: 5078
  • naively breaking things!
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #4722 on: July 24, 2019, 10:04:07 AM »

Aha, here's Thing No. 1; in doFit, it presumes we're flipping Variants, not changing the internals of the Variant... I think?  Anyhow... here's one bit that appears to apply specifically to your problem:

Code
		int index = 0;
for (String slotId : current.getStationModules().keySet()) {
ShipVariantAPI moduleCurrent = current.getModuleVariant(slotId);
if (moduleCurrent == null) continue;
if (moduleCurrent.isStockVariant()) {
moduleCurrent = moduleCurrent.clone();
moduleCurrent.setSource(VariantSource.REFIT);
moduleCurrent.setHullVariantId(moduleCurrent.getHullVariantId() + "_" + index);
}
index++;

ShipVariantAPI moduleTarget = target.getModuleVariant(slotId);
if (moduleTarget == null) continue;

fittingModule = true;
doFit(moduleCurrent, moduleTarget, delegate);
fittingModule = false;

current.setModuleVariant(slotId, moduleCurrent);
}
current.setSource(VariantSource.REFIT);

Some of that isn't necessary, like the call to doFit(), etc., but current.setSource() looks relevant.

There's also the question of the last bit, here:

Code
		
if (!fittingModule) {
delegate.syncUIWithVariant();
}
Logged
Please check out my SS projects :)
Xeno's Mod Pack

lethargie

  • Commander
  • ***
  • Posts: 183
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #4723 on: July 24, 2019, 05:00:03 PM »

You could have the portrait .pngs be named the same as the ones in the faction (which may not be desirable as I think some portraits are used across multiple factions). You could also add the .faction file to a "replace" section in your mod_info.json file, though that means you'd need to provide the full faction file, not just the portraits section.

How does that interact with other mods that might add portrait by appending to the base file?
Logged

Alex

  • Administrator
  • Admiral
  • *****
  • Posts: 23988
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #4724 on: July 24, 2019, 05:08:35 PM »

How does that interact with other mods that might add portrait by appending to the base file?

It'll override whatever they're doing.
Logged
Pages: 1 ... 313 314 [315] 316 317 ... 706