Fractal Softworks Forum

Please login or register.

Login with username, password and session length
Pages: 1 ... 619 620 [621] 622 623 ... 710

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

Alex

  • Administrator
  • Admiral
  • *****
  • Posts: 24123
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #9300 on: October 28, 2022, 09:49:21 AM »

Just theory-crafting for a ship system that makes the ship unable to be hit. Was hypothesizing NONE might make the AI not target it and thought of point bounds. 0 collision radius is also a good idea.

Ah! Not sure offhand if that'll change what the AI is doing or not, actually; it might indeed affect it.


How can I access the every WeaponSpecAPI corresponding to a weapon_data.csv row containing the SYSTEM tag, wherefore Global.getSettings().getAllWeaponSpecs() excludes every such WeaponSpecAPI?

Hmm, I don't think you can, actually. Let me add:

List<WeaponSpecAPI> getSystemWeaponSpecs();

To SettingsAPI.


cargo.getMothballedShips()

(Javadoc mentions that initMothballedShips(String factionId) needs to be called first, not sure if game automatically does this already)

(It does not, but in the specific case for a submkarket, the getCargo() method does this.)


common issue is we have to point out the ShipAPI.setCustomData method that actually modifies the underlying map and not a copy returned by ShipAPI.getCustomData. is it possible to make getCustomData return the original custom data map?

I don't think ShipAPI has either of these methods.
Logged

presidentmattdamon

  • Commander
  • ***
  • Posts: 249
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #9301 on: October 28, 2022, 09:53:20 AM »

common issue is we have to point out the ShipAPI.setCustomData method that actually modifies the underlying map and not a copy returned by ShipAPI.getCustomData. is it possible to make getCustomData return the original custom data map?

I don't think ShipAPI has either of these methods.

sorry, it's CombatEntityAPI
Logged

Alex

  • Administrator
  • Admiral
  • *****
  • Posts: 24123
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #9302 on: October 28, 2022, 02:09:05 PM »

common issue is we have to point out the ShipAPI.setCustomData method that actually modifies the underlying map and not a copy returned by ShipAPI.getCustomData. is it possible to make getCustomData return the original custom data map?

I don't think ShipAPI has either of these methods.

sorry, it's CombatEntityAPI

Ah, ok. I don't understand what the issue is, then - getCustomData() already does not return a copy.

... ahh. One thing that happens is if you removeCustomData() the last entry in the map, the underlying map will be set to null and re-allocated next time you call either getCustomData() or setCustomData(). So if you're hanging on to the reference to an older map - pre it being cleared by removeCustomData() - then it might look like getCustomData() is returning a "copy" (it'd be reallocating a new map because the old one was cleared out and null'ed).

So if you're holding on to a reference like that, I'd suggest ... not doing that :) It's not a great idea to hang on to some internals of a class precisely because things like this can and will happen.
Logged

Liral

  • Admiral
  • *****
  • Posts: 718
  • Realistic Combat Mod Author
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #9303 on: October 28, 2022, 03:02:15 PM »

Hmm, I don't think you can, actually. Let me add:

List<WeaponSpecAPI> getSystemWeaponSpecs();

To SettingsAPI.

Yaaaaaay! :D

presidentmattdamon

  • Commander
  • ***
  • Posts: 249
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #9304 on: October 28, 2022, 11:04:00 PM »

common issue is we have to point out the ShipAPI.setCustomData method that actually modifies the underlying map and not a copy returned by ShipAPI.getCustomData. is it possible to make getCustomData return the original custom data map?

I don't think ShipAPI has either of these methods.

sorry, it's CombatEntityAPI

Ah, ok. I don't understand what the issue is, then - getCustomData() already does not return a copy.

... ahh. One thing that happens is if you removeCustomData() the last entry in the map, the underlying map will be set to null and re-allocated next time you call either getCustomData() or setCustomData(). So if you're hanging on to the reference to an older map - pre it being cleared by removeCustomData() - then it might look like getCustomData() is returning a "copy" (it'd be reallocating a new map because the old one was cleared out and null'ed).

So if you're holding on to a reference like that, I'd suggest ... not doing that :) It's not a great idea to hang on to some internals of a class precisely because things like this can and will happen.

ok. there's been some weird behavior people have been seeing where using
Code
ship.getCustomData().put("key", value)
and then trying to retrieve the value
Code
ship.getCustomData().get("key")
will return false.


this is a specific example from someone earlier today where the key they set was immediately gone
Logged

Whittle

  • Ensign
  • *
  • Posts: 2
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #9305 on: October 29, 2022, 01:37:11 PM »

Where is the script that calculates accessibility? I would like to create a version that takes active rings into account when calculating distance from core / distance to other colonies.
Logged

Alex

  • Administrator
  • Admiral
  • *****
  • Posts: 24123
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #9306 on: October 30, 2022, 02:56:13 PM »

this is a specific example from someone earlier today where the key they set was immediately gone

That code is using "ship" and "weapon.getShip()", so possibly the two aren't the same in that context?


Where is the script that calculates accessibility? I would like to create a version that takes active rings into account when calculating distance from core / distance to other colonies.

It's modified in a number of places, check the references to MarketAPI.getAccessibilityMod() to see where.
Logged

SteelSirokos

  • Ensign
  • *
  • Posts: 30
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #9307 on: October 30, 2022, 03:14:19 PM »

So, I went ahead and wrote an entire mod that allows the player to insure unique ships and, in the event of said ship's destruction, receive a fresh hull. The problem is, I didn't account for the fact that my references to each of the FleetMemberAPIs prevent the garbage collector from actually cleaning the objects up. I'm now left with no actual way to check if a ship has truly been obliterated or not since my current code relies on checking if the stored FleetMemberAPI being null (which it never will be while a reference to it is stored.)

My question is whether there's still any way for me to check if a ship is truly gone given these circumstances. If possible I'd like to avoid the "check the game world, markets, storage etc for the ship to see if it exists" approach because there are a number of mods that utilize their own storage systems that the base game API doesn't touch, so anyone using those mods could trick my mod into allowing them to duplicate unique ships.

Thanks!

Alex

  • Administrator
  • Admiral
  • *****
  • Posts: 24123
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #9308 on: October 30, 2022, 03:19:23 PM »

An excellent question :)

Take a look at com.fs.starfarer.api.impl.campaign.plog.SModRecord, in particular its use of WeakReference<FleetMemberAPI>, it's an approach (about the only one I could think of) to solving this exact problem.

Short of, yes, trying to search through everything and then still not accounting for whatever random way some mod might be storing a fleet member.
Logged

tsallast

  • Ensign
  • *
  • Posts: 1
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #9309 on: October 30, 2022, 03:38:48 PM »

I believe this is impossible, but is there any way to display "Heat" instead of "Flux" for a specific ship for the little combat indicator next to it?
Logged

SteelSirokos

  • Ensign
  • *
  • Posts: 30
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #9310 on: October 30, 2022, 07:43:26 PM »

An excellent question :)

Take a look at com.fs.starfarer.api.impl.campaign.plog.SModRecord, in particular its use of WeakReference<FleetMemberAPI>, it's an approach (about the only one I could think of) to solving this exact problem.

Short of, yes, trying to search through everything and then still not accounting for whatever random way some mod might be storing a fleet member.

It worked!!!

...Kind of. By changing all memory references of FleetMemberAPI to WeakReference<FleetMemberAPI> I was able to to get garbage collection to acknowledge that the FleetMemberAPI in question was due to be annihilated. The one problem I'm having is that garbage collection seems to happen on a completely arbitrary basis, so I may have to add a sentence or two in the upcoming forum post about how players need to save and load to force garbage collection if the station isn't recognizing that they have a redeemable ship hull. If you know a way to force garbage collection without saving and loading I'm all ears, but otherwise I'm pretty happy with how this turned out.

EDIT: saving/loading only seems to force garbage collection in dev mode, so it looks like I'll have to find a way around this unfortunately. See reply
« Last Edit: October 30, 2022, 08:10:07 PM by SteelSirokos »
Logged

Liral

  • Admiral
  • *****
  • Posts: 718
  • Realistic Combat Mod Author
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #9311 on: October 30, 2022, 08:05:21 PM »

Oops, duplicate post!  :o
« Last Edit: October 30, 2022, 08:26:15 PM by Liral »
Logged

SteelSirokos

  • Ensign
  • *
  • Posts: 30
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #9312 on: October 30, 2022, 08:08:54 PM »

An excellent question :)

Take a look at com.fs.starfarer.api.impl.campaign.plog.SModRecord, in particular its use of WeakReference<FleetMemberAPI>, it's an approach (about the only one I could think of) to solving this exact problem.

Short of, yes, trying to search through everything and then still not accounting for whatever random way some mod might be storing a fleet member.

It worked!!!

...Kind of. By changing all memory references of FleetMemberAPI to WeakReference<FleetMemberAPI> I was able to to get garbage collection to acknowledge that the FleetMemberAPI in question was due to be annihilated. The one problem I'm having is that garbage collection seems to happen on a completely arbitrary basis, so I may have to add a sentence or two in the upcoming forum post about how players need to save and load to force garbage collection if the station isn't recognizing that they have a redeemable ship hull. If you know a way to force garbage collection without saving and loading I'm all ears, but otherwise I'm pretty happy with how this turned out.

EDIT: saving/loading only seems to force garbage collection in dev mode, so it looks like I'll have to find a way around this unfortunately. See reply
It turns out regular old saving forces garbage collection, so it seems like telling players to do that might just be my solution. If there's an easy way to force garbage collection via the API (which there doesn't seem to be) I will be happy to implement it, but otherwise I'm very happy to just tell people to save their game since that doesn't seem like it requires a lot of effort on their part.

EDIT: I set up a script to run System.gc() when the player interacts with my station. This has completely solved all of my issues and eliminated the need for the player to save. Unless there's some sort of hidden consequences for doing this, I'm going to keep it this way.
« Last Edit: October 31, 2022, 10:02:28 AM by SteelSirokos »
Logged

Liral

  • Admiral
  • *****
  • Posts: 718
  • Realistic Combat Mod Author
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #9313 on: October 30, 2022, 08:24:07 PM »

A user has reported that my mod Realistic Combat yields this crash-to-desktop error

com.fs.starfarer.loading.specs.C cannot be cast to com.fs.starfarer.loading.specs.N

which I have traced this Realistic Combat method
Code
    private static void spawnRicochetProjectile(final DamagingProjectileAPI projectile,
                                                final Vector2f location,
                                                final float ricochetFacing,
                                                final ShipAPI ship)
    {
        Global.getCombatEngine().spawnProjectile(projectile.getSource(), projectile.getWeapon(),
                projectile.getWeapon().getId(), location, ricochetFacing, ship.getVelocity());
    }
with the Scy mod installed.

I have searched the obfuscated code module com.fs.starfarer.loading.specs for both classes, finding com.fs.starfarer.loading.specs.N to be 'behind' WeaponSpecAPI, but have not found com.fs.starfarer.loading.specs.C.  Does this second obfuscated class exist, and if so, where?  I can only speculate about the ultimate cause of this bug: perhaps some consequence of my nigh-heretical meddling with dark magic to pursue unnatural ends has angered some hidden Power Behind the API.  :-[

Update: I have run my mod with Scy and received an almost identical error, which referred instead to
ooOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO.class, which I have found in the obfuscated code and know to be the spec class for BeamAPI.

I then wrapped a try-catch block around this method and found an involved weapon: Nano-needle minigun Mk. 2 (id: SCY_minigun2).  This weapon has a BeamEffect

BeamEffect
Code: BeamEffect
//by Tartiflette, this script allow for a beam weapon to spawn bouncing projectiles on impact
//feel free to use it, credit is appreciated but not mandatory
package data.scripts.weapons;

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.WeaponAPI.WeaponSize;
import com.fs.starfarer.api.util.IntervalUtil;
import data.scripts.util.MagicRender;
import java.awt.Color;
import org.lazywizard.lazylib.MathUtils;
import org.lazywizard.lazylib.VectorUtils;
import org.lwjgl.util.vector.Vector2f;

public class SCY_minigunEffect implements BeamEffectPlugin {
   
    private boolean runOnce=false, hasSmoke=false, large=false;
    private float TEXTURE_RANDOMNESS=2, GLOW_SIZE=40;
    private final IntervalUtil timer = new IntervalUtil (0.025f,0.075f);
    private final float M_TEXTURE_RANDOMNESS=5, M_GLOW_SIZE=60, L_TEXTURE_RANDOMNESS=30, L_GLOW_SIZE=80;
   
    @Override
    public void advance(float amount, CombatEngineAPI engine, BeamAPI beam) {               
        //game paused, no script
        if (engine.isPaused()) {return;}
       
        if (!runOnce){
            runOnce=true;
            if(beam.getWeapon().getSize()==WeaponSize.MEDIUM){
                hasSmoke=true;
                TEXTURE_RANDOMNESS=M_TEXTURE_RANDOMNESS;
                GLOW_SIZE=M_GLOW_SIZE;
            } else if(beam.getWeapon().getSize()==WeaponSize.LARGE){
                hasSmoke=true;
                large=true;
                TEXTURE_RANDOMNESS=L_TEXTURE_RANDOMNESS;
                GLOW_SIZE=L_GLOW_SIZE;
            }
            return;
        }       
       
        timer.advance(amount);
        if(timer.intervalElapsed() && beam.getBrightness()>0.8f && MagicRender.screenCheck(0.1f, beam.getFrom())){

            beam.setPixelsPerTexel(15 + MathUtils.getRandomNumberInRange(-TEXTURE_RANDOMNESS, TEXTURE_RANDOMNESS));

            Vector2f from = beam.getFrom();
            Vector2f vel = beam.getSource().getVelocity();
            if(hasSmoke){
                float grey = MathUtils.getRandomNumberInRange(0.3f, 0.6f);
                if (Math.random()>0.5){
                    engine.addSmoothParticle(
                            MathUtils.getRandomPointInCircle(
                                    from,
                                    5
                            ),
                            new Vector2f (
                                    vel.x/2+MathUtils.getRandomNumberInRange(-5f, 5f),
                                    vel.y/2+MathUtils.getRandomNumberInRange(-5f, 5f)
                            ), 
                            MathUtils.getRandomNumberInRange(10f, 25f),
                            0.5f,
                            MathUtils.getRandomNumberInRange(1f, 5f),
                            new Color(grey,grey,grey,MathUtils.getRandomNumberInRange(0.02f, 0.08f) )
                    );
                } else {
                    engine.addSmokeParticle(
                            MathUtils.getRandomPointInCircle(
                                    from,
                                    5
                            ),
                            new Vector2f (
                                    vel.x/2+MathUtils.getRandomNumberInRange(-5f, 5f),
                                    vel.y/2+MathUtils.getRandomNumberInRange(-5f, 5f)
                            ), 
                            MathUtils.getRandomNumberInRange(10f, 25f),
                            0.5f,
                            MathUtils.getRandomNumberInRange(1f, 5f),
                            new Color(grey,grey,grey,MathUtils.getRandomNumberInRange(0.02f, 0.08f) )
                    );
                }
            }       
            engine.addSmoothParticle(
                    from,
                    vel,
                    MathUtils.getRandomNumberInRange(GLOW_SIZE-15, GLOW_SIZE+15),
                    0.5f,
                    0.05f,
                    new Color(255,50,25,128)
            );     
        }

        //on Hit, create impact effect
        if (beam.didDamageThisFrame()){           
            Vector2f end = beam.getTo(); 

            //splinters             
            float dir = VectorUtils.getAngle(beam.getDamageTarget().getLocation(), end);
            if (hasSmoke){
                engine.spawnProjectile(
                    beam.getSource(),
                    beam.getWeapon(),
                    "SCY_splinter1",
                    MathUtils.getRandomPointOnCircumference(end, 5),
                    dir + MathUtils.getRandomNumberInRange(-90, 90),
                    null
                );
                engine.spawnProjectile(
                    beam.getSource(),
                    beam.getWeapon(),
                    "SCY_splinter2",
                    MathUtils.getRandomPointOnCircumference(end, 5),
                    dir + MathUtils.getRandomNumberInRange(-90, 90),
                    null
                );
                if(large){                   
                    engine.spawnProjectile(
                        beam.getSource(),
                        beam.getWeapon(),
                        "SCY_splinter2",
                        MathUtils.getRandomPointOnCircumference(end, 5),
                        dir + MathUtils.getRandomNumberInRange(-90, 90),
                        null
                    );
                }
            } else {               
                //spawn a single splinters
                if(Math.random()>0.66){
                    engine.spawnProjectile(
                        beam.getSource(),
                        beam.getWeapon(),
                        "SCY_splinter1",
                        MathUtils.getRandomPointOnCircumference(end, 5),
                        dir + MathUtils.getRandomNumberInRange(-90, 90),
                        null
                    );
                } else if(Math.random()>0.5){
                    engine.spawnProjectile(
                        beam.getSource(),
                        beam.getWeapon(),
                        "SCY_splinter2",
                        MathUtils.getRandomPointOnCircumference(end, 5),
                        dir + MathUtils.getRandomNumberInRange(-90, 90),
                        null
                    );
                } 
            }             
        }
    }
}
[close]

which I have included should you want to read it.  I notice an association—my error report mentions the hidden class BeamSpec class, and the weapon involved has a BeamEffect—and now wonder if some interaction between this BeamEffect and the Global.getCombatEngine().spawnProjectile method has instead of my irreverent occult tampering caused the error.

Update: see message below.
« Last Edit: October 31, 2022, 08:03:27 PM by Liral »
Logged

presidentmattdamon

  • Commander
  • ***
  • Posts: 249
    • View Profile
Re: Misc modding questions that are too minor to warrant their own thread
« Reply #9314 on: October 31, 2022, 09:52:43 AM »

A user has reported that my mod Realistic Combat yields this crash-to-desktop error

com.fs.starfarer.loading.specs.C cannot be cast to com.fs.starfarer.loading.specs.N

which I have traced this Realistic Combat method
Code
    private static void spawnRicochetProjectile(final DamagingProjectileAPI projectile,
                                                final Vector2f location,
                                                final float ricochetFacing,
                                                final ShipAPI ship)
    {
        Global.getCombatEngine().spawnProjectile(projectile.getSource(), projectile.getWeapon(),
                projectile.getWeapon().getId(), location, ricochetFacing, ship.getVelocity());
    }
with the Scy mod installed.

I have searched the obfuscated code module com.fs.starfarer.loading.specs for both classes, finding com.fs.starfarer.loading.specs.N to be 'behind' WeaponSpecAPI, but have not found com.fs.starfarer.loading.specs.C.  Does this second obfuscated class exist, and if so, where?  I can only speculate about the ultimate cause of this bug: perhaps some consequence of my nigh-heretical meddling with dark magic to pursue unnatural ends has angered some hidden Power Behind the API.  :-[

Update: I have run my mod with Scy and received an almost identical error, which referred instead to
ooOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO.class, which I have found in the obfuscated code and know to be the spec class for BeamAPI.

I then wrapped a try-catch block around this method and found an involved weapon: Nano-needle minigun Mk. 2 (id: SCY_minigun2).  This weapon has a BeamEffect

BeamEffect
Code: BeamEffect
//by Tartiflette, this script allow for a beam weapon to spawn bouncing projectiles on impact
//feel free to use it, credit is appreciated but not mandatory
package data.scripts.weapons;

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.WeaponAPI.WeaponSize;
import com.fs.starfarer.api.util.IntervalUtil;
import data.scripts.util.MagicRender;
import java.awt.Color;
import org.lazywizard.lazylib.MathUtils;
import org.lazywizard.lazylib.VectorUtils;
import org.lwjgl.util.vector.Vector2f;

public class SCY_minigunEffect implements BeamEffectPlugin {
   
    private boolean runOnce=false, hasSmoke=false, large=false;
    private float TEXTURE_RANDOMNESS=2, GLOW_SIZE=40;
    private final IntervalUtil timer = new IntervalUtil (0.025f,0.075f);
    private final float M_TEXTURE_RANDOMNESS=5, M_GLOW_SIZE=60, L_TEXTURE_RANDOMNESS=30, L_GLOW_SIZE=80;
   
    @Override
    public void advance(float amount, CombatEngineAPI engine, BeamAPI beam) {               
        //game paused, no script
        if (engine.isPaused()) {return;}
       
        if (!runOnce){
            runOnce=true;
            if(beam.getWeapon().getSize()==WeaponSize.MEDIUM){
                hasSmoke=true;
                TEXTURE_RANDOMNESS=M_TEXTURE_RANDOMNESS;
                GLOW_SIZE=M_GLOW_SIZE;
            } else if(beam.getWeapon().getSize()==WeaponSize.LARGE){
                hasSmoke=true;
                large=true;
                TEXTURE_RANDOMNESS=L_TEXTURE_RANDOMNESS;
                GLOW_SIZE=L_GLOW_SIZE;
            }
            return;
        }       
       
        timer.advance(amount);
        if(timer.intervalElapsed() && beam.getBrightness()>0.8f && MagicRender.screenCheck(0.1f, beam.getFrom())){

            beam.setPixelsPerTexel(15 + MathUtils.getRandomNumberInRange(-TEXTURE_RANDOMNESS, TEXTURE_RANDOMNESS));

            Vector2f from = beam.getFrom();
            Vector2f vel = beam.getSource().getVelocity();
            if(hasSmoke){
                float grey = MathUtils.getRandomNumberInRange(0.3f, 0.6f);
                if (Math.random()>0.5){
                    engine.addSmoothParticle(
                            MathUtils.getRandomPointInCircle(
                                    from,
                                    5
                            ),
                            new Vector2f (
                                    vel.x/2+MathUtils.getRandomNumberInRange(-5f, 5f),
                                    vel.y/2+MathUtils.getRandomNumberInRange(-5f, 5f)
                            ), 
                            MathUtils.getRandomNumberInRange(10f, 25f),
                            0.5f,
                            MathUtils.getRandomNumberInRange(1f, 5f),
                            new Color(grey,grey,grey,MathUtils.getRandomNumberInRange(0.02f, 0.08f) )
                    );
                } else {
                    engine.addSmokeParticle(
                            MathUtils.getRandomPointInCircle(
                                    from,
                                    5
                            ),
                            new Vector2f (
                                    vel.x/2+MathUtils.getRandomNumberInRange(-5f, 5f),
                                    vel.y/2+MathUtils.getRandomNumberInRange(-5f, 5f)
                            ), 
                            MathUtils.getRandomNumberInRange(10f, 25f),
                            0.5f,
                            MathUtils.getRandomNumberInRange(1f, 5f),
                            new Color(grey,grey,grey,MathUtils.getRandomNumberInRange(0.02f, 0.08f) )
                    );
                }
            }       
            engine.addSmoothParticle(
                    from,
                    vel,
                    MathUtils.getRandomNumberInRange(GLOW_SIZE-15, GLOW_SIZE+15),
                    0.5f,
                    0.05f,
                    new Color(255,50,25,128)
            );     
        }

        //on Hit, create impact effect
        if (beam.didDamageThisFrame()){           
            Vector2f end = beam.getTo(); 

            //splinters             
            float dir = VectorUtils.getAngle(beam.getDamageTarget().getLocation(), end);
            if (hasSmoke){
                engine.spawnProjectile(
                    beam.getSource(),
                    beam.getWeapon(),
                    "SCY_splinter1",
                    MathUtils.getRandomPointOnCircumference(end, 5),
                    dir + MathUtils.getRandomNumberInRange(-90, 90),
                    null
                );
                engine.spawnProjectile(
                    beam.getSource(),
                    beam.getWeapon(),
                    "SCY_splinter2",
                    MathUtils.getRandomPointOnCircumference(end, 5),
                    dir + MathUtils.getRandomNumberInRange(-90, 90),
                    null
                );
                if(large){                   
                    engine.spawnProjectile(
                        beam.getSource(),
                        beam.getWeapon(),
                        "SCY_splinter2",
                        MathUtils.getRandomPointOnCircumference(end, 5),
                        dir + MathUtils.getRandomNumberInRange(-90, 90),
                        null
                    );
                }
            } else {               
                //spawn a single splinters
                if(Math.random()>0.66){
                    engine.spawnProjectile(
                        beam.getSource(),
                        beam.getWeapon(),
                        "SCY_splinter1",
                        MathUtils.getRandomPointOnCircumference(end, 5),
                        dir + MathUtils.getRandomNumberInRange(-90, 90),
                        null
                    );
                } else if(Math.random()>0.5){
                    engine.spawnProjectile(
                        beam.getSource(),
                        beam.getWeapon(),
                        "SCY_splinter2",
                        MathUtils.getRandomPointOnCircumference(end, 5),
                        dir + MathUtils.getRandomNumberInRange(-90, 90),
                        null
                    );
                } 
            }             
        }
    }
}
[close]

which I have included should you want to read it.  I notice an association—my error report mentions the hidden class BeamSpec class, and the weapon involved has a BeamEffect—and now wonder if some interaction between this BeamEffect and the Global.getCombatEngine().spawnProjectile method has instead of my irreverent occult tampering caused the error.

wonder if your mod tries to spawn a BeamAPI as a projectile
Logged
Pages: 1 ... 619 620 [621] 622 623 ... 710