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)

Author Topic: Please help with new weapon using AdvanceableListener nd BeamEffectPlugin  (Read 456 times)

rogerbacon

  • Commander
  • ***
  • Posts: 142
    • View Profile

I'm trying to make a weapon that abosrbs flux over time and then , when it fires, does bonus damage equal to the flux it has absorbed.
My code is below. I have a class implementing BeamEffectPlugin and a listener class. The listener is adding teh flux to the battery but when I fire the weapon the check for this.ML.fluxBattery > 0  always fails. It knows what the listener is because if I print some other value like FLUX_PER_SECOND_CHARGE_RATE  from this.ML, it knows what that is.
I hope someone can tell me what I'm doing wrong here.

Code
package data.scripts.weapons;
import java.lang.Math;
import com.fs.starfarer.api.combat.*;
import com.fs.starfarer.api.combat.BeamAPI;
import com.fs.starfarer.api.combat.BeamEffectPlugin;
import com.fs.starfarer.api.combat.CombatEngineAPI;
import com.fs.starfarer.api.combat.CombatEntityAPI;
import com.fs.starfarer.api.combat.DamageType;
import com.fs.starfarer.api.combat.ShipAPI;
import com.fs.starfarer.api.util.IntervalUtil;
import org.lazywizard.lazylib.combat.CombatUtils;
import com.fs.starfarer.api.combat.listeners.AdvanceableListener;
import org.lazywizard.lazylib.VectorUtils;
import org.lazywizard.lazylib.MathUtils;
import org.lazywizard.console.Console;
import org.lazywizard.lazylib.CollisionUtils;
import com.fs.starfarer.api.combat.FluxTrackerAPI;
import com.fs.starfarer.api.loading.DamagingExplosionSpec;
import java.awt.Color;
import java.util.*;
import org.lwjgl.util.vector.Vector2f;
import static com.fs.starfarer.api.util.Misc.ZERO;

public class PlasmaMaulerEffect implements BeamEffectPlugin
{
public boolean listenerAttached = false;
public MaulerListenerScript ML = null;
public ShipAPI firer = null;

    @Override
    public void advance(float amount, CombatEngineAPI engine, BeamAPI beam)
    {
if (!listenerAttached) {
listenerAttached = true;
this.firer = beam.getSource();
this.ML  = new MaulerListenerScript(this.firer);
if (!beam.getSource().hasListenerOfClass(ML.getClass())) {
this.firer.addListener(ML);
}
}

if (this.ML == null) {
Console.showMessage("ML is null");
}
CombatEntityAPI target = beam.getDamageTarget();
if (this.ML.fluxBattery > 0 /* && beam.getBrightness() >= 1f && target instanceof ShipAPI */) {

Console.showMessage("*Flux battery*: " + this.ML.fluxBattery);

// TODO: add damage here
                        // Drain the batteries
//
this.ML.fluxBattery = 0;
}

    }

public class MaulerListenerScript implements AdvanceableListener {
private ShipAPI ship;
private FluxTrackerAPI fluxTracker = null;
public float fluxBattery = 0f;
private float time;
public float FLUX_PER_SECOND_CHARGE_RATE = 400f;
private float MAX_BATTERY_CAPACITY = 8000f;

public MaulerListenerScript(ShipAPI ship) {
this.ship = ship;
this.fluxTracker = ship.getFluxTracker();
}

public void advance(float amount) {
// increment our timer to collect fluxBattery
time += amount;
if (time > 1f)
{


// move flux into the battery
float amountOfFluxToRemove = FLUX_PER_SECOND_CHARGE_RATE * time;
float currentFlux = fluxTracker.getCurrFlux();
if (amountOfFluxToRemove > currentFlux) {
amountOfFluxToRemove = currentFlux;
}
this.fluxBattery += amountOfFluxToRemove;
if (this.fluxBattery > MAX_BATTERY_CAPACITY)
{
this.fluxBattery = MAX_BATTERY_CAPACITY;
}

//Console.showMessage("Flux battery: " + this.fluxBattery);
//Console.showMessage("Current flux level: " + fluxTracker.getFluxLevel());
fluxTracker.decreaseFlux(amountOfFluxToRemove);
time = 0f;
}
}
}

}
Logged

Ruddygreat

  • Admiral
  • *****
  • Posts: 524
  • Seals :^)
    • View Profile
Re: Please help with new weapon using AdvanceableListener nd BeamEffectPlugin
« Reply #1 on: December 24, 2022, 04:43:05 PM »

beamEffects get re-instantiated every time the beam fires, so every time it fires you're getting a new listener and not actually doing anything with it.

if you replace your listenerAttached check with this
Code

    public class beemeffect implements beamEffectPlugin {

    (YourListener) listener = getFirstListenerOfClass(source, YourListener.Class);
    if (listener == null) {
            source.addListener(new YourListener())
        }

    /*
    yada yada, the rest of your code looks correct at a glance
    */

    }


    public static <T> T getFirstListenerOfClass(ShipAPI ship, Class listenerClass) {

        if (!ship.hasListenerOfClass(listenerClass)) {
            return null;
        }

        Object listener = ship.getListeners(listenerClass).get(0);

        return (T) listener;
    }
it should work, I use this method in place of stuff like customData & most hullmods advance() methods

rogerbacon

  • Commander
  • ***
  • Posts: 142
    • View Profile
Re: Please help with new weapon using AdvanceableListener nd BeamEffectPlugin
« Reply #2 on: December 26, 2022, 06:53:52 AM »

Thank you. This helped a lot. I still had a few problesm you finally got it to work.

One final issue remains: The listener isn't attached until I fire the weapon the first time. I can live with that but, for teh AI's sake, it would be nice if I could initialize it at the start of combat. Is tehre any method I can implement to trigger something at the start of combat?
Logged

Ruddygreat

  • Admiral
  • *****
  • Posts: 524
  • Seals :^)
    • View Profile
Re: Please help with new weapon using AdvanceableListener nd BeamEffectPlugin
« Reply #3 on: December 26, 2022, 12:25:19 PM »

if you use the weapon's everyFrameEffect, that runs every frame from the start of a battle & checking a boolean every frame shouldn't be too intensive

or if you used a combatEveryFramePlugin, you could use that to check every ship & add the listeners then (etc etc, you have a lot of options for this)