Fractal Softworks Forum

Please login or register.

Login with username, password and session length
Advanced search  

News:

Starsector 0.9.1a is out! (05/10/19); Blog post: Painting the Stars (02/07/20); Updated the Forum Rules and Guidelines (02/29/20)

Pages: 1 ... 4 5 [6] 7 8 9

Author Topic: The Radioactive Code Dump  (Read 63327 times)

xenoargh

  • Admiral
  • *****
  • Posts: 4856
  • naively breaking things!
    • View Profile
Re: The Radioactive Code Dump
« Reply #75 on: March 19, 2014, 08:44:28 PM »

Are you one of those slightly... compulsive people who wants your asymmetric weapons designs, with their ultra-cool looks, to be properly mirrored on your ship, so that symmetrical ships look symmetrical and orderly, even if the weapon sprites aren't?

This script is for you :)

Code: java
package data.scripts.sfx;
import com.fs.starfarer.api.combat.CombatEngineAPI;
import com.fs.starfarer.api.combat.EveryFrameWeaponEffectPlugin;
import com.fs.starfarer.api.combat.WeaponAPI;
import com.fs.starfarer.api.graphics.SpriteAPI;

public class weaponSide implements EveryFrameWeaponEffectPlugin {
    private boolean runOnce = false;
    
    @Override
    public void advance(float amount, CombatEngineAPI engine, WeaponAPI weapon) {
        
        if (engine.isPaused()) return;
        if(runOnce == false){
            if (weapon.getShip().getOwner() == 0 && weapon.getLocation().getX() < weapon.getShip().getLocation().getX()
                || weapon.getShip().getOwner() == 1 && weapon.getLocation().getX() > weapon.getShip().getLocation().getX()){
                SpriteAPI theSprite = weapon.getSprite();
                theSprite.setWidth(-theSprite.getWidth());
                theSprite.setCenter(-theSprite.getCenterX(),theSprite.getCenterY());
            }
            runOnce = true;
        }
    }
}

Warning: it works only for weapons that have one barrel, centered on the X axis, or two, four, six eight, etc where the barrels are symmetrical XY from the center, or odd-numbered barrels where the right and left barrels are mirrored XY... or, yeah.  Basically, the weapon's barrels and glows need to be symmetrical, even if the sprite isn't.

Will bork with practically anything else, I suspect.  I will probably make an API request to do this engine-side, but for now...
« Last Edit: March 19, 2014, 08:58:22 PM by xenoargh »
Logged
Please check out my SS projects :)
Xeno's Mod Pack

dmaiski

  • Captain
  • ****
  • Posts: 422
  • resistance is futile
    • View Profile
Re: The Radioactive Code Dump
« Reply #76 on: March 22, 2014, 04:03:43 PM »

Highly Radioactive Code

BEWARE

all my old stuff from way back when(v0.61a) it should all be working (i think) and comented (again, i think)
contains all the stuff i posted here plus alot of experimental stuff i never released/got to work properly/left till later/was just testing/(ect...)

(what i think should be in there)
4 whole mods:
hell crab: contains a bunch of experimental stuff that i was fiddling with (weeapon slot mountable ship systems, armor regeneration)
rusters: testbed for even more experimental stuff i was playing with (all the missile AI i ever made, weird weapons, stuff)
biso test: pre release version of the BISO mod (alot of weapon systems that did intresting stuff)
biso branch: scraps that was branched off of test then abandoned (old outdated, just there for posterity)
Logged
BISO
(WIP) lots of shiny new weapons ( :-[ i have more weapons then sprites :-[ )

i got a cat pad
its like a mouse pad but better!

Foxer360

  • Admiral
  • *****
  • Posts: 637
  • Recursion; See Recursion (n)
    • View Profile
    • Email
Re: The Radioactive Code Dump
« Reply #77 on: March 22, 2014, 05:05:08 PM »

Ambershit, you make no sense. #Bot?
Logged

Lcu

  • Commander
  • ***
  • Posts: 213
    • View Profile
Re: The Radioactive Code Dump
« Reply #78 on: March 23, 2014, 03:45:59 AM »

Why do people call him Ambershit?
Logged
Spoiler
66766766
66766766
66666766
66766766
66766766
Ctrl+F, type 6
[close]

dmaiski

  • Captain
  • ****
  • Posts: 422
  • resistance is futile
    • View Profile
Re: The Radioactive Code Dump
« Reply #79 on: March 23, 2014, 03:56:44 AM »

various stuff(some of it uses the utility kit i posted here earlier)

armor regenerator
1st cycle: damaged cells take armor from healthy cells to repair themselves
2nd cycle: "alive" cells repair themselves based on the amount of HP they have
Spoiler
Code: java
package data.scripts.plugins;



import com.fs.starfarer.api.Global;
import com.fs.starfarer.api.combat.*;
import com.fs.starfarer.api.util.IntervalUtil;

import java.awt.*;

/*
to be put on a weapon that will execute script on a ship
multiple weapons will increase the efficiency
 */
public class AbsorptionArmor implements EveryFrameWeaponEffectPlugin
{
    //engine
    private CombatEngineAPI engine= Global.getCombatEngine();

    //////////////////////////////////////////////////////////////////////////////////////////////

    //timers
    private IntervalUtil fasttimer = new IntervalUtil(.1f, .11f);
    private IntervalUtil slowtimer = new IntervalUtil(.15f, .16f);

    //////////////////////////////////////////////////////////////////////////////////////////////



    //main armor effect
    float lastcycle=0;
    @Override
    public void advance(float v, CombatEngineAPI engineAPI, WeaponAPI weaponAPI)
    {
        //ship
        ShipAPI ship;
        ship=weaponAPI.getShip();

        //////////////////////////////////////////////////////////////////////////////////////////////

        //stats of system
        float FluPerAPoint = 10;    //how much 1 armor point is worth in terms of flux
        //float ReBaArmRate = .005f;  //how fast armor rebalanced  max 1 for instant
        float MaxFlux = .8f;        //cap for this system being active
        float RegenRate = .002f;    //rate armor regenerates as a decimal
        float activeRate = .005f;    //how fast active armor balancer works
        float MinHealthActive = .4f;//minimum health for active armor sharing
        float weaponsizemult = 1f;
        //weapon size multiplier
        WeaponAPI.WeaponSize weapsize = weaponAPI.getSize();
        if (weapsize.equals(WeaponAPI.WeaponSize.SMALL)) {weaponsizemult=.5f;}
        if (weapsize.equals(WeaponAPI.WeaponSize.MEDIUM)){weaponsizemult=1f;}
        if (weapsize.equals(WeaponAPI.WeaponSize.LARGE)) {weaponsizemult=2f;}

        //////////////////////////////////////////////////////////////////////////////////////////////

        //game is paused dont do anything  //weapon is disabled ""
        if (engine.isPaused() || weaponAPI.isDisabled())
        {
            return;
        }

        //////////////////////////////////////////////////////////////////////////////////////////////

        //if(ship.getSystem().isActive()) optional link to ship system
        {
            //advance timers
            slowtimer.advance(v);
            fasttimer.advance(v);

            //////////////////////////////////////////////////////////////////////////////////////////////

            //main code
            if (fasttimer.intervalElapsed())
            {
                //stuff that is used alot
                ArmorGridAPI armorgrid = ship.getArmorGrid();
                float armorrating = armorgrid.getArmorRating();
                float MaxCell = armorgrid.getMaxArmorInCell();

                //////////////////////////////////////////////////////////////////////////////////////////

                //armor grid stats
                int maxX = armorgrid.getLeftOf()+armorgrid.getRightOf();
                int maxY = armorgrid.getAbove()+armorgrid.getBelow();

                //////////////////////////////////////////////////////////////////////////////////////////

                //avarage armor of ship hull
                float armorcells = 0;               //number of cells ship has
                for (int X=0; X<maxX; X++){for (int Y=0; Y<maxY; Y++){armorcells++;}}
                //float ReBalArmor = curarmor/armorcells;

                //////////////////////////////////////////////////////////////////////////////////////////

                //adjusted stats
                float adjust = weaponsizemult*Math.min(125 / armorcells, 4); //max increase of rate (prevents 100x rate on small ship)
                FluPerAPoint = 10;    //how much 1 armor point is worth in terms of flux
                //float ReBaArmRate = .005f;  //how fast armor rebalanced  max 1 for instant
                MaxFlux = .8f;        //cap for this system being active
                RegenRate = .002f*adjust;    //rate armor regenerates as a decimal
                activeRate = .005f*adjust;    //how fast active armor balancer works
                MinHealthActive = .4f*adjust;//minimum health for active armor sharing

                //////////////////////////////////////////////////////////////////////////////////////////

                //basic armor state of ship
                float curarmor = getTotalArmor(ship);
                //float ArmLost = armorgrid.getArmorRating()-curarmor;  //how much armor was damaged

                //////////////////////////////////////////////////////////////////////////////////////////

                //calculate regen rate based on flux (prevents cells from filling up sequentially at low flux)
                float FluxRemaining = (ship.getFluxTracker().getMaxFlux()*MaxFlux) - ship.getFluxTracker().getCurrFlux();
                //float FluxToRepairMax = ArmLost * FluPerAPoint;
                float NormRepPerFrame = (MaxCell * RegenRate)
                        *((MaxFlux-ship.getFluxTracker().getFluxLevel())/MaxFlux);//aditional level of repair decrease
                //float FluxToRepairNorm = NormRepPerFrame * FluPerAPoint * armorcells;
                //float FluxForRep = (FluxToRepairMax < FluxToRepairNorm ? FluxToRepairMax : FluxToRepairNorm);

                //easier, more accurate  (compares the cost to repair in last cycle to amount of flux left)
                if (lastcycle==0) {lastcycle=NormRepPerFrame*armorcells*FluPerAPoint;}
                float FluxForRep = lastcycle;
                float FluxToRepairNorm = lastcycle;
                float RepRate = (FluxForRep<FluxRemaining ? NormRepPerFrame:NormRepPerFrame*(FluxRemaining/FluxToRepairNorm));

                //////////////////////////////////////////////////////////////////////////////////////////


                //armor manager
                float next=0;
                lastcycle=0; //clears lastcycle
                //active cycle (needs to be separate)
                //lets damaged cells take armor from nearby healthy cells
                for (int X=0; X<maxX; X++)       //
                {                                //cycle through all armor cells on ship
                    for (int Y=0; Y<maxY; Y++)   //
                    {
                        float cur = armorgrid.getArmorValue(X, Y); //health of current cell
                        //Active ReBalArmor
                        //mover armor from nearby cells to damaged ones
                        //can be tied to an if statement
                        {
                            //take armor from nearby healthy cells
                            float Forwardsum=0;
                            for (int Xa=(X==0? X:X-1); Xa<maxX && Xa>=0 && Xa<=X+1; Xa++)
                            {
                                for (int Ya=(Y==0? Y:Y-1); Ya<maxY && Ya>=0 && Ya<=Y+1; Ya++)
                                {
                                    float cell = armorgrid.getArmorValue(Xa, Ya);
                                    if (cell>cur && armorgrid.getArmorFraction(Xa, Ya)>MinHealthActive)
                                    {
                                        float diff = (cell - cur)*activeRate;
                                        next = (cell-diff);
                                        armorgrid.setArmorValue(Xa, Ya, next>0? next:0);
                                        cur+=diff;
                                        //ship.getFluxTracker().increaseFlux(diff*FluPerAPoint*.1f, true);
                                        //uses 1/10th of the normal flux to move armor around (too costly in flux)
                                    }
                                }
                            }
                            next = cur;
                            armorgrid.setArmorValue(X, Y, next<MaxCell? next:MaxCell); //add it to cell
                        }
                    }
                }

                /////////////////////////////////////////////////////////////////////////////////////


                //passive cycle
                for (int X=0; X<maxX; X++)       //
                {                                //cycle through all armor cells on ship
                    for (int Y=0; Y<maxY; Y++)   //
                    {
                        float cur = armorgrid.getArmorValue(X, Y); //health of current cell

                        //only do repair if cell health is more then 0 prevents immortal ship syndrome
                        if (cur>0)
                        {
                            //regen armor
                            if (cur<MaxCell)
                            {
                                next = cur + (cur/MaxCell)*RepRate;          //how much armor should be regenerated


                                armorgrid.setArmorValue(X, Y, next<MaxCell? next:MaxCell);
                                float fluxuse = (next - cur) * FluPerAPoint;
                                ship.getFluxTracker().increaseFlux(fluxuse, true);
                                lastcycle+=fluxuse;
                            }
                        }

                    }
                }


                /////////////////////////////////////////////////////////////////////////////////////

                //test
                if (slowtimer.intervalElapsed())
                {
                engine.addFloatingText(ship.getLocation(), "armorcells  " + armorcells + " armorrating  " + armorrating + " curentarmor  " + curarmor +" MaxCell  "+ MaxCell +"  waeposizemult  "+weaponsizemult, 20f, Color.RED, ship, 1f, .5f);
                }

            }
        }
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////

    //gets total armor of a ship
    public static float getTotalArmor(ShipAPI ship)
    {
        ArmorGridAPI armorgrid = ship.getArmorGrid();
        float sum=0;
        int maxX = armorgrid.getLeftOf()+armorgrid.getRightOf();
        int maxY = armorgrid.getAbove()+armorgrid.getBelow();

        for (int X=0; X<maxX; X++)
        {
            for (int Y=0; Y<maxY; Y++)
            {
                sum += armorgrid.getArmorValue(X, Y);
            }
        }
        return sum;
    }

}
[close]

Auxilary flux vents
can be mounted into weapon slots on a ship
use ammo to disperse flux
highly experimental (broken, more or less)
Spoiler
Code: java
package data.scripts.plugins;



import com.fs.starfarer.api.Global;
import com.fs.starfarer.api.combat.*;
import com.fs.starfarer.api.util.IntervalUtil;

import java.awt.*;

/*
to be put on a weapon that will execute script on a ship
multiple weapons will increase the efficiency
 */
public class AuxilaryFluxVents implements EveryFrameWeaponEffectPlugin
{
    //engine
    private CombatEngineAPI engine= Global.getCombatEngine();

    //////////////////////////////////////////////////////////////////////////////////////////////

    //timers
    private IntervalUtil fasttimer = new IntervalUtil(.05f, .06f);
    private IntervalUtil slowtimer = new IntervalUtil(.15f, .16f);

    //////////////////////////////////////////////////////////////////////////////////////////////



    //main armor effect
    boolean fired=false;
    @Override
    public void advance(float v, CombatEngineAPI engineAPI, WeaponAPI weaponAPI)
    {
        //ship
        ShipAPI ship;
        ship=weaponAPI.getShip();

        //////////////////////////////////////////////////////////////////////////////////////////////


        //weapon size multiplier
        float weaponsizemult = 1;
        WeaponAPI.WeaponSize weapsize = weaponAPI.getSize();
        if (weapsize.equals(WeaponAPI.WeaponSize.SMALL)) {weaponsizemult=.5f;}
        if (weapsize.equals(WeaponAPI.WeaponSize.MEDIUM)){weaponsizemult=1f;}
        if (weapsize.equals(WeaponAPI.WeaponSize.LARGE)) {weaponsizemult=2f;}
        //stats of system
        float rate = .01f*weaponsizemult; //how fast vent happens (20x this number)
        float minflux = .1f; //lowest value of flux it can get to
        float maxflux = .95f;
        FluxTrackerAPI flux = ship.getFluxTracker();

        //////////////////////////////////////////////////////////////////////////////////////////////

        //game is paused dont do anything
        if (engine.isPaused())
        {
            return;
        }

        //////////////////////////////////////////////////////////////////////////////////////////////

        //if(ship.getSystem().isActive()) optional link to ship system
        {
            //advance timers
            //slowtimer.advance(v);
            fasttimer.advance(v);
            if (fasttimer.intervalElapsed())
            {
                //////////////////////////////////////////////////////////////////////////////////////////////

                //controls for flux vent
                if (!fired)  //if weapon has not fired
                {
                    //if flux is to high fire

                    if ((ship.getFluxTracker().getFluxLevel()>maxflux && weaponAPI.getAmmo()>0))
                    {weaponAPI.isFiring();fired=true;
                        weaponAPI.setRemainingCooldownTo(100);
                        weaponAPI.setAmmo(weaponAPI.getAmmo()-1);
                        flux.setCurrFlux(flux.getMaxFlux());}//forces all other systems on ship on
                    //record that you fired
                    if (weaponAPI.isFiring()){fired=true;}
                }

                //////////////////////////////////////////////////////////////////////////////////////////////


                //main vent code
                float FVsec = (flux.getMaxFlux()*.05f)*rate;
                if (fired && ship.getFluxTracker().getFluxLevel()>minflux)
                {
                    //prevents firing
                    weaponAPI.setRemainingCooldownTo(100);
                    {
                        flux.decreaseFlux(FVsec);
                    }
                }

                //////////////////////////////////////////////////////////////////////////////////////////////


                //if venting done
                if (fired && ship.getFluxTracker().getFluxLevel()<minflux)
                {
                    fired=false;
                    weaponAPI.setRemainingCooldownTo(0); //if now at minflux firing is allowed
                }

                //test
                slowtimer.advance(v);
                if (slowtimer.intervalElapsed())
                {
                    engine.addFloatingText(ship.getLocation(), "FVsec  " + FVsec + "rate  " + rate, 20f, Color.RED, ship, 1f, .5f);
            }
            }
        }
    }
}
[close]

Grovotron 3000
gravaton modifier beam
send anything that is not bolted to the ground flying in the direction the beam is pointing (at great speeds)
great if your ship has slow weapons like reapers
Spoiler
Code: java
package data.scripts.plugins;

import com.fs.starfarer.api.combat.*;
import com.fs.starfarer.api.util.IntervalUtil;
import org.lazywizard.lazylib.MathUtils;
import org.lazywizard.lazylib.combat.AIUtils;
import org.lwjgl.util.vector.Vector2f;

import java.awt.*;
import java.util.ArrayList;

import static jar.UtilityKit.V2fPerpendicularDisc;
import static jar.UtilityKit.V2fReSize;
import static org.lwjgl.util.vector.Vector2f.add;
import static org.lwjgl.util.vector.Vector2f.sub;


public class Gravotron implements BeamEffectPlugin {

    private IntervalUtil Interval = new IntervalUtil(0.02f, 0.01f);
    float MaxPoint=400;

    public void advance(float amount, CombatEngineAPI engine, BeamAPI beam)
    {
        if (beam.getBrightness() >= .5f) {
            Interval.advance(amount);

            if (Interval.intervalElapsed()) {
                Vector2f from = beam.getFrom();
                Vector2f to = beam.getTo();
                Vector2f dir = sub(to, from, null);
                float Bang = MathUtils.getFacing(dir);

                ArrayList<CombatEntityAPI> PQueries = new ArrayList<CombatEntityAPI>();
                PQueries.addAll(engine.getAsteroids());
                PQueries.addAll(engine.getProjectiles());

                for (CombatEntityAPI query : PQueries)
                {
                    Vector2f QLoc = query.getLocation();
                    float DtoL = V2fDistanceToLine(from, to, QLoc, true);
                    float AbDtoL = Math.abs(DtoL);
                    if (AbDtoL<MaxPoint
                            && (!(query instanceof DamagingProjectileAPI)        //catch for just launched weapons
                            || (((DamagingProjectileAPI) query).getWeapon()!=null
                            && MathUtils.getDistance(((DamagingProjectileAPI) query).getWeapon().getLocation(), QLoc)>40)))
                    {
                        float PSadj = (MaxPoint-AbDtoL)/40;
                        float Sadj = PSadj*PSadj;

                        Vector2f QVel = query.getVelocity();
                        engine.addFloatingText(QLoc, "Av-> "+QVel, 20f, Color.RED, beam.getSource(), 1f, .5f);
                        //towards line
                        Vector2f ToL = V2fPerpendicularDisc(dir, (Sadj < 100 ? Sadj : 100), (DtoL<0? 1:0));

                        //towards end
                        Vector2f ToE = V2fReSize(dir, (Sadj < 100 ? Sadj : 100));

                        //adjust the velocity
                        Vector2f Qre = new Vector2f(QVel.getX()+ToE.getX()/*+ToL.getX()*/,
                                QVel.getY()+ToE.getY()/*+ToL.getY()*/);

                        QVel.set(Qre);
                        query.setFacing(query.getFacing()+((MathUtils.getFacing(Qre)-query.getFacing())/2));

                        /*
                        //collide with everything
                        if (query instanceof DamagingProjectileAPI) {
                            ShipAPI Ne = ((DamagingProjectileAPI) query).getSource();
                            if (Ne!=null && MathUtils.getDistance(Ne,query.getLocation())>10) {
                                query.setCollisionClass(CollisionClass.HITS_SHIPS_AND_ASTEROIDS);}}
                        */


                        //engine.addHitParticle(QLoc, ToE, 30f, .5f, 1, new Color(235, 157, 43,120));
                    }

                }

                //sparkly beam
                while (Math.random()>.3)
                {
                    Vector2f AdjDir = V2fReSize(dir, (float) (Math.hypot(dir.getX(), dir.getY())*Math.random()));
                    Vector2f Adj2Dir = V2fPerpendicularDisc(dir, (float)(30*Math.random()), .5f);
                    Vector2f RX = add(add(from,Adj2Dir,null), AdjDir, null);
                    engine.addHitParticle(RX, V2fReSize(dir,50), 30f, .5f, 1, new Color(40, 136, 235,120));
                }
            }
        }
    }

    private static double[] V2ftoArray(Vector2f point)
    {
        double[] array = new double[2];
        array[0] = point.getX();
        array[1] = point.getY();
        return array;
    }

    private static Vector2f  ArraytoV2f(double[] point)
    {
        return new Vector2f((float)point[0],(float)point[1]);
    }

    private static double DotProduct(double[] pointA, double[] pointB, double[] pointC)
    {
        double[] AB = new double[2];
        double[] BC = new double[2];
        AB[0] = pointB[0] - pointA[0];
        AB[1] = pointB[1] - pointA[1];
        BC[0] = pointC[0] - pointB[0];
        BC[1] = pointC[1] - pointB[1];
        double dot = AB[0] * BC[0] + AB[1] * BC[1];
        return dot;
    }

    private static double CrossProduct(double[] pointA, double[] pointB, double[] pointC)
    {
        double[] AB = new double[2];
        double[] AC = new double[2];
        AB[0] = pointB[0] - pointA[0];
        AB[1] = pointB[1] - pointA[1];
        AC[0] = pointC[0] - pointA[0];
        AC[1] = pointC[1] - pointA[1];
        double cross = AB[0] * AC[1] - AB[1] * AC[0];
        return cross;
    }
    //Compute the distance from A to B
    private static double ToLineDistance(double[] pointA, double[] pointB)
    {
        double d1 = pointA[0] - pointB[0];
        double d2 = pointA[1] - pointB[1];
        return Math.sqrt(d1 * d1 + d2 * d2);
    }

    private static double[] ToLineVector(double[] pointA, double[] pointB)
    {
        double[] ABC = new double[2];
        ABC[0] = pointA[0] - pointB[0];
        ABC[1] = pointA[1] - pointB[1];
        return ABC;
    }

    //Compute the distance from AB to C
    //if isSegment is true, AB is a segment, not a line.
    private static double LineToPointDistance2D(double[] pointA, double[] pointB, double[] pointC, boolean isSegment)
    {
        double dist = CrossProduct(pointA, pointB, pointC) / ToLineDistance(pointA, pointB);
        if (isSegment)
        {
            double dot1 = DotProduct(pointA, pointB, pointC);
            if (dot1 > 0)
                return ToLineDistance(pointB, pointC);
            double dot2 = DotProduct(pointB, pointA, pointC);
            if (dot2 > 0)
                return ToLineDistance(pointA, pointC);
        }
        return dist;
    }

    public static float V2fDistanceToLine(Vector2f from, Vector2f to, Vector2f point, boolean segment)
    {
        return (float)LineToPointDistance2D(V2ftoArray(from),V2ftoArray(to),V2ftoArray(point), segment);
    }

    // use reverse perpendicular calculation to get vector to line!!!
}

[close]

Lightning Drone missile
when missile is launched, it moves away from ship and then fires a lightning bots at the mouse target
onse it has fired it moved back into the launcher and reloads itself
then waits for the next target to be given to it
Spoiler
Code: java
package data.scripts.MissileAI;


import com.fs.starfarer.api.Global;
import com.fs.starfarer.api.combat.*;
import com.fs.starfarer.api.util.IntervalUtil;
import org.lazywizard.lazylib.MathUtils;
import org.lazywizard.lazylib.combat.AIUtils;
import org.lwjgl.util.vector.Vector2f;

import java.awt.*;

import static jar.UtilityKit.V2fAdjust;
import static jar.UtilityKit.getNearestMissileToPoint;


public class BalundirLightningAI implements MissileAIPlugin{

    private final MissileAPI missile;
    private ShipAPI launchingShip;

    private IntervalUtil MainTimer = new IntervalUtil(2f, 0.5f);
    private IntervalUtil ShortTimer = new IntervalUtil(.5f, 0.4f);
    private IntervalUtil LongTimer = new IntervalUtil(5f, 0.5f);

    private boolean Fire=false;
    private boolean Fire2=false;
    private boolean FireStop=false;

    public BalundirLightningAI(MissileAPI missile, ShipAPI launchingShip)
    {
        this.missile = missile;
        this.launchingShip = launchingShip;
        missile.setCollisionClass(CollisionClass.FIGHTER);
    }

    //main missile AI
    private Vector2f MouseT=new Vector2f(0,0);
    @Override
    public void advance(float amount)
    {
        CombatEngineAPI engine = Global.getCombatEngine();
        /*
        // pause when you are not needed
        if (missile.isFading() || missile.isFizzling() || engine.isPaused())
        {
            return;
        }
        */

        if (MouseT.lengthSquared()==0)
        {
            MouseT = new Vector2f(launchingShip.getMouseTarget());
            if (MouseT.lengthSquared()==0)
            {
                missile.setSource(AIUtils.getNearestAlly(missile));
            }
        }

        LongTimer.advance(amount);

        Vector2f MLoc = missile.getLocation();

        if (!FireStop)
        {
            ShortTimer.advance(amount);
            MainTimer.advance(amount);


            if (MainTimer.intervalElapsed())
            {
                Fire = true;
            }

            if (ShortTimer.intervalElapsed()){
                Fire2 = true;
            }

            if (Fire && Fire2) {
                Fire2=false;
                engine.spawnProjectile(
                        launchingShip,
                        null,
                        "targetdot",
                        MouseT,
                        0,
                        new Vector2f(0,0));

                MissileAPI target = getNearestMissileToPoint(MouseT);

                engine.spawnEmpArc(
                        launchingShip,
                        missile.getLocation(),
                        target, target,
                        DamageType.ENERGY,
                        0f, //real
                        0,   //emp
                        10000f, // max range
                        "tachyon_lance_emp_impact",
                        5f, // thickness
                        new Color(255,10,15,255),
                        new Color(31, 214,255,255)
                );
            }
        }
        else
        {
            Vector2f WLoc = missile.getWeapon().getLocation();
            Vector2f DVec = MathUtils.getDirectionalVector(MLoc, WLoc);
            //engine.addHitParticle(WLoc, new Vector2f(0,0), 70f, .5f, 1, new Color(235, 157, 43,120));
            missile.getVelocity().set(V2fAdjust(DVec, 200, 0, 0));
            if (MathUtils.getDistance(MLoc,WLoc)<5)
            {
                missile.getWeapon().setAmmo(missile.getWeapon().getAmmo()+1);
                engine.removeEntity(missile);
            }
        }


        if (LongTimer.intervalElapsed()) {
            FireStop=true;
        }
    }
}
[close]

@Lcu
cause that was his name till the admins slaped him silly

also: plz try and stay on topic
« Last Edit: March 23, 2014, 04:05:41 AM by dmaiski »
Logged
BISO
(WIP) lots of shiny new weapons ( :-[ i have more weapons then sprites :-[ )

i got a cat pad
its like a mouse pad but better!

Sabaton

  • Captain
  • ****
  • Posts: 478
    • View Profile
Re: The Radioactive Code Dump
« Reply #80 on: March 23, 2014, 04:48:56 AM »

When he lifts his face to the people, I will ban them orderly from the ship, and we aren't even talking about radios the last time I checked, anyway what are the only sprites?

 Hi Cleverbot!
Logged

Lcu

  • Commander
  • ***
  • Posts: 213
    • View Profile
Re: The Radioactive Code Dump
« Reply #81 on: March 24, 2014, 03:57:37 AM »

Does these code need to be implemented into a mod are just a plugin for it to work?
Logged
Spoiler
66766766
66766766
66666766
66766766
66766766
Ctrl+F, type 6
[close]

dmaiski

  • Captain
  • ****
  • Posts: 422
  • resistance is futile
    • View Profile
Re: The Radioactive Code Dump
« Reply #82 on: March 24, 2014, 05:51:01 AM »

all the code here is for mods, you can use them in various ways like attaching them to weapons, ships, projectiles, ship mods... it just depends how you pick to implement them :P

if you have a specific thing you want to know how to implement xeno, LazyWizzard or me will probably have some idea how to do it  ;D
Logged
BISO
(WIP) lots of shiny new weapons ( :-[ i have more weapons then sprites :-[ )

i got a cat pad
its like a mouse pad but better!

Nanao-kun

  • Admiral
  • *****
  • Posts: 822
    • View Profile
    • Email
Re: The Radioactive Code Dump
« Reply #83 on: March 24, 2014, 11:38:40 AM »

Is there any way for me to add Uomoz's Random Variants to Exerelin for my personal use?
Logged

xenoargh

  • Admiral
  • *****
  • Posts: 4856
  • naively breaking things!
    • View Profile
Re: The Radioactive Code Dump
« Reply #84 on: March 24, 2014, 11:52:09 AM »

Well, that's kind of outside the scope of this thread; this isn't the thread for asking general "how to" questions, beyond how to get a chunk of code released here to work, but basically, it should be possible and not terribly hard, if you know what you're doing. 

I doubt it's just drag-and-drop ready, though; anything integrated into a main Campaign-level timer loop like that will require porting over to Exerelin's implementation.
Logged
Please check out my SS projects :)
Xeno's Mod Pack

Dark.Revenant

  • Admiral
  • *****
  • Posts: 2551
    • View Profile
    • Sc2Mafia
    • Email
Re: The Radioactive Code Dump
« Reply #85 on: April 07, 2014, 05:20:35 PM »

I bring you an improved automatic weapon group generator.  Designed for the variant randomizer system used by SS+ and UsS, but can be hooked into other things when needed.  This works better than the vanilla weapon group generator nearly 100% of the time and can support unusual ship configurations, even ones with large numbers of missiles or a huge variety of weapons.  Examples for vanilla, SS+, and Exigency overrides are included.

Note: This is an extremely long piece of code that might not load properly in your browser.  Go here to see it all: http://pastebin.com/8Sfm3vR5

Spoiler
Code: java
    public enum WeaponGroupConfig {

        STANDARD, MISSILE, BROADSIDE, MISSILE_BROADSIDE, ALPHA_STRIKE
    }

    public static final Map weaponTypeOverride;

    static {
        Map weaponTypeOverrideTemp = new HashMap();

        weaponTypeOverrideTemp.put("Missile",
                createWeaponList(new String[]{
                    "annihilator", "annihilatorpod", "swarmer", "pilum",
                    "exigency_mmm", "exigency_mmm_f"
                }));
        weaponTypeOverrideTemp.put("No Aim",
                createWeaponList(new String[]{
                    "swarmer", "pilum", "exigency_mmm", "exigency_mmm_f",
                    "exigency_drumlauncher"
                }));
        weaponTypeOverrideTemp.put("Anti-Fighter",
                createWeaponList(new String[]{
                    "swarmer", "phasecl"
                }));
        weaponTypeOverrideTemp.put("Point Defense",
                createWeaponList(new String[]{
                    "phasecl"
                }));
        weaponTypeOverrideTemp.put("Strike",
                createWeaponList(new String[]{
                    "x"
                }));
        weaponTypeOverrideTemp.put("Assault",
                createWeaponList(new String[]{
                    "annihilator", "annihilatorpod", "phasecl", "exigency_mmm",
                    "exigency_mmm_f"
                }));
        weaponTypeOverrideTemp.put("Close Support",
                createWeaponList(new String[]{
                    "exigency_drumlauncher"
                }));
        weaponTypeOverrideTemp.put("Fire Support",
                createWeaponList(new String[]{
                    "ssp_redeemer", "pilum"
                }));
        weaponTypeOverrideTemp.put("Special",
                createWeaponList(new String[]{
                    "x"
                }));
        weaponTypeOverrideTemp.put("Low Flux", // Cannot be autodetected
                createWeaponList(new String[]{
                    "lightmg", "lightdualmg", "lightmortar", "vulcan",
                    "fragbomb", "clusterbomb", "bomb", "flak",
                    "heavymg", "dualflak", "mininglaser", "pdlaser",
                    "taclaser", "lrpdlaser", "pdburst", "gravitonbeam",
                    "heavyburst", "guardian", "ssp_tpc", "annihilator",
                    "annihilatorpod", "swarmer", "phasecl", "pilum",
                    "exigency_mmm", "exigency_mmm_f"
                }));
        weaponTypeOverrideTemp.put("High Flux", // Cannot be autodetected
                createWeaponList(new String[]{
                    "mjolnir", "miningblaster", "heavyblaster", "plasma",
                    "exigency_rr", "exigency_cigenrepeater", "exipirated_rr_p"
                }));
        weaponTypeOverrideTemp.put("Sustained Beam", // Cannot be autodetected
                createWeaponList(new String[]{
                    "hil", "gravitonbeam", "lrpdlaser", "pdlaser",
                    "mininglaser", "phasebeam", "taclaser", "exigency_repulsor_beam",
                    "exigency_lightning_gun"
                }));
        weaponTypeOverrideTemp.put("Limited Ammo", // Cannot be autodetected
                createWeaponList(new String[]{
                    "amblaster"
                }));
        weaponTypeOverrideTemp.put("Override", // Disables autodetection
                createWeaponList(new String[]{
                    "ssp_redeemer", "annihilator", "annihilatorpod", "swarmer",
                    "phasecl", "pilum", "exigency_mmm", "exigency_mmm_f",
                    "exigency_drumlauncher"
                }));

        weaponTypeOverride = Collections.unmodifiableMap(weaponTypeOverrideTemp);
    }

    private static List<String> createWeaponList(String[] variants) {
        return Collections.unmodifiableList(Arrays.asList(variants));
    }

    private static List<String> getWeaponList(String key) {
        return (List<String>) weaponTypeOverride.get(key);
    }

    private static void integrateGroup(WeaponGroupSpec source, WeaponGroupSpec destination) {
        for (String slot : source.getSlots()) {
            destination.addSlot(slot);
        }
        destination.setType(source.getType());
        destination.setAutofireOnByDefault(source.isAutofireOnByDefault());
    }

    public static void generateWeaponGroups(ShipVariantAPI variant, WeaponGroupConfig config) {
        // Clean up the existing groups
        // We go through this whole song and dance rather than just flushing and making new groups for reasons of maximum compatability
        for (WeaponGroupSpec group : variant.getWeaponGroups()) {
            WeaponGroupSpec clone = group.clone();
            for (String slot : clone.getSlots()) {
                group.removeSlot(slot);
            }
        }

        // These are programmable variables passed from the WeaponGroupConfig
        // This will change how the algorithm will behave
        boolean splitMissiles = false;
        boolean enforceSides = false;
        boolean linkedStrike = false;

        if (config == WeaponGroupConfig.MISSILE) {
            splitMissiles = true;
        } else if (config == WeaponGroupConfig.BROADSIDE) {
            enforceSides = true;
        } else if (config == WeaponGroupConfig.MISSILE_BROADSIDE) {
            splitMissiles = true;
            enforceSides = true;
        } else if (config == WeaponGroupConfig.ALPHA_STRIKE) {
            linkedStrike = true;
        }

        // Now we define all of the possible weapon groups that the variant can use
        List<WeaponGroupSpec> groupList = new ArrayList();

        WeaponGroupSpec PDGroup = new WeaponGroupSpec();
        PDGroup.setType(WeaponGroupType.LINKED);
        PDGroup.setAutofireOnByDefault(true);
        groupList.add(PDGroup);

        WeaponGroupSpec AFGroup = new WeaponGroupSpec();
        AFGroup.setType(WeaponGroupType.LINKED);
        AFGroup.setAutofireOnByDefault(true);
        groupList.add(AFGroup);

        WeaponGroupSpec AssGroup = new WeaponGroupSpec();
        AssGroup.setType(WeaponGroupType.LINKED);
        AssGroup.setAutofireOnByDefault(false);
        groupList.add(AssGroup);

        WeaponGroupSpec AssTGroup = new WeaponGroupSpec();
        AssTGroup.setType(WeaponGroupType.LINKED);
        AssTGroup.setAutofireOnByDefault(true);
        groupList.add(AssTGroup);

        WeaponGroupSpec CSGroup = new WeaponGroupSpec();
        CSGroup.setType(WeaponGroupType.LINKED);
        CSGroup.setAutofireOnByDefault(false);
        groupList.add(CSGroup);

        WeaponGroupSpec CSTGroup = new WeaponGroupSpec();
        CSTGroup.setType(WeaponGroupType.LINKED);
        CSTGroup.setAutofireOnByDefault(true);
        groupList.add(CSTGroup);

        WeaponGroupSpec SupGroup = new WeaponGroupSpec();
        SupGroup.setType(WeaponGroupType.LINKED);
        SupGroup.setAutofireOnByDefault(true);
        groupList.add(SupGroup);

        WeaponGroupSpec HvyGroup = new WeaponGroupSpec();
        if (linkedStrike) {
            HvyGroup.setType(WeaponGroupType.LINKED);
        } else {
            HvyGroup.setType(WeaponGroupType.ALTERNATING);
        }
        HvyGroup.setAutofireOnByDefault(false);
        groupList.add(HvyGroup);

        WeaponGroupSpec HvyTGroup = new WeaponGroupSpec();
        if (linkedStrike) {
            HvyTGroup.setType(WeaponGroupType.LINKED);
        } else {
            HvyTGroup.setType(WeaponGroupType.ALTERNATING);
        }
        HvyTGroup.setAutofireOnByDefault(false);
        groupList.add(HvyTGroup);

        WeaponGroupSpec BeaGroup = new WeaponGroupSpec();
        BeaGroup.setType(WeaponGroupType.LINKED);
        BeaGroup.setAutofireOnByDefault(false);
        groupList.add(BeaGroup);

        WeaponGroupSpec BeaTGroup = new WeaponGroupSpec();
        BeaTGroup.setType(WeaponGroupType.LINKED);
        BeaTGroup.setAutofireOnByDefault(false);
        groupList.add(BeaTGroup);

        WeaponGroupSpec StrGroup = new WeaponGroupSpec();
        if (linkedStrike) {
            StrGroup.setType(WeaponGroupType.LINKED);
        } else {
            StrGroup.setType(WeaponGroupType.ALTERNATING);
        }
        StrGroup.setAutofireOnByDefault(false);
        groupList.add(StrGroup);

        WeaponGroupSpec MisGroup = new WeaponGroupSpec();
        if (linkedStrike) {
            MisGroup.setType(WeaponGroupType.LINKED);
        } else {
            MisGroup.setType(WeaponGroupType.ALTERNATING);
        }
        MisGroup.setAutofireOnByDefault(false);
        groupList.add(MisGroup);

        WeaponGroupSpec SMisGroup = new WeaponGroupSpec();
        SMisGroup.setType(WeaponGroupType.LINKED);
        SMisGroup.setAutofireOnByDefault(true);
        groupList.add(SMisGroup);

        WeaponGroupSpec AMisGroup = new WeaponGroupSpec();
        if (linkedStrike) {
            AMisGroup.setType(WeaponGroupType.LINKED);
        } else {
            AMisGroup.setType(WeaponGroupType.ALTERNATING);
        }
        AMisGroup.setAutofireOnByDefault(false);
        groupList.add(AMisGroup);

        WeaponGroupSpec LGroup = new WeaponGroupSpec();
        LGroup.setType(WeaponGroupType.LINKED);
        LGroup.setAutofireOnByDefault(false);
        groupList.add(LGroup);

        WeaponGroupSpec RGroup = new WeaponGroupSpec();
        RGroup.setType(WeaponGroupType.LINKED);
        RGroup.setAutofireOnByDefault(false);
        groupList.add(RGroup);

        // This loops through all of the weapons and individually assigns them to initial groups
        // Most weapon groupings are auto-detected based on AI hints, weapon data, and description strings
        // The remaning groupings are enforced via overrides and configuration parameters
        List<WeaponSlotAPI> slots = variant.getHullSpec().getAllWeaponSlotsCopy();
        Collection<String> fittedSlots = variant.getFittedWeaponSlots();
        for (String fittedSlot : fittedSlots) {
            String weapon = variant.getWeaponId(fittedSlot);
            String type = Global.getSettings().getDescription(weapon, Description.Type.WEAPON).getText2();
            WeaponSlotAPI slot = null;
            for (WeaponSlotAPI slott : slots) {
                if (slott.getId().equals(fittedSlot)) {
                    slot = slott;
                }
            }

            // These are the various weapon properties that are checked when making the groupings
            boolean antiFighter = false;
            boolean pointDefense = false;
            boolean strike = false;
            boolean noAim = false;
            boolean assault = false;
            boolean closeSupport = false;
            boolean fireSupport = false;
            boolean missile = false;
            boolean lowFlux = false;
            boolean highFlux = false;
            boolean hardpoint = false;
            boolean limitedAmmo = false;
            boolean beam = false;
            boolean special = false;
            boolean front = false;
            boolean back = false;
            boolean left = false;
            boolean right = false;
            WeaponSize size = WeaponSize.SMALL;

            if (slot != null) {
                if (slot.isHardpoint() || slot.getArc() <= 5f) {
                    hardpoint = true;
                }
                if (slot.getAngle() <= 45f && slot.getAngle() >= -45f) {
                    front = true;
                } else if (slot.getAngle() >= 45f && slot.getAngle() <= 135f) {
                    left = true;
                } else if (slot.getAngle() > 135f || slot.getAngle() < -135f) {
                    back = true;
                } else {
                    right = true;
                }
                size = slot.getSlotSize();
            }
            if (getWeaponList("Missile").contains(weapon)) {
                missile = true;
            }
            if (getWeaponList("No Aim").contains(weapon)) {
                noAim = true;
            }
            if (getWeaponList("Anti-Fighter").contains(weapon)) {
                antiFighter = true;
            }
            if (getWeaponList("Point Defense").contains(weapon)) {
                pointDefense = true;
            }
            if (getWeaponList("Strike").contains(weapon)) {
                strike = true;
            }
            if (getWeaponList("Assault").contains(weapon)) {
                assault = true;
            }
            if (getWeaponList("Close Support").contains(weapon)) {
                closeSupport = true;
            }
            if (getWeaponList("Fire Support").contains(weapon)) {
                fireSupport = true;
            }
            if (getWeaponList("Special").contains(weapon)) {
                special = true;
            }
            if (getWeaponList("Low Flux").contains(weapon)) {
                lowFlux = true;
            }
            if (getWeaponList("High Flux").contains(weapon)) {
                highFlux = true;
            }
            if (getWeaponList("Sustained Beam").contains(weapon)) {
                beam = true;
            }
            if (getWeaponList("Limited Ammo").contains(weapon)) {
                limitedAmmo = true;
            }

            // If "Override" is set for the weapon, skip this auto-detection stuff and only use the overrides
            // Weapons without "Override" set will use both auto-detected stuff and overrides
            if (!getWeaponList("Override").contains(weapon)) {
                EnumSet<AIHints> hints = variant.getWeaponSpec(fittedSlot).getAIHints();
                for (AIHints hint : hints) {
                    if (hint == AIHints.ANTI_FTR) {
                        antiFighter = true;
                    }
                    if (hint == AIHints.PD || hint == AIHints.PD_ONLY) {
                        pointDefense = true;
                    }
                    if (hint == AIHints.STRIKE) {
                        strike = true;
                    }
                    if (hint == AIHints.DO_NOT_AIM || hint == AIHints.HEATSEEKER) {
                        noAim = true;
                    }
                }
                if (variant.getWeaponSpec(fittedSlot).getType() == WeaponType.MISSILE) {
                    missile = true;
                    lowFlux = true;
                    limitedAmmo = true;
                }
                if (type.equals("Anti-Fighter")) {
                    antiFighter = true;
                }
                if (type.equals("Point Defense")) {
                    pointDefense = true;
                }
                if (type.equals("Strike")) {
                    strike = true;
                }
                if (type.equals("Assault")) {
                    assault = true;
                }
                if (type.equals("Close Support")) {
                    closeSupport = true;
                }
                if (type.equals("Fire Support")) {
                    fireSupport = true;
                }
                if (type.equals("Special")) {
                    special = true;
                }
            }

            // This is the logic for assigning weapons to general groups
            // Make sure you know what you are doing before changing this stuff around
            // The order of operations is important!
            if (hardpoint && (highFlux || (size == WeaponSize.LARGE && (variant.getHullSize() == HullSize.FRIGATE || variant.getHullSize() == HullSize.DESTROYER || variant.getHullSize() == HullSize.DEFAULT)))) {
                if (!beam) {
                    HvyGroup.addSlot(fittedSlot);
                } else {
                    BeaGroup.addSlot(fittedSlot);
                }
            } else if (!hardpoint && (highFlux || (size == WeaponSize.LARGE && (variant.getHullSize() == HullSize.FRIGATE || variant.getHullSize() == HullSize.DESTROYER || variant.getHullSize() == HullSize.DEFAULT)))) {
                if (!beam) {
                    HvyTGroup.addSlot(fittedSlot);
                } else {
                    BeaTGroup.addSlot(fittedSlot);
                }
            } else if (missile && left && enforceSides && !noAim && !limitedAmmo) {
                LGroup.addSlot(fittedSlot);
            } else if (missile && right && enforceSides && !noAim && !limitedAmmo) {
                RGroup.addSlot(fittedSlot);
            } else if (missile && limitedAmmo && (noAim || !hardpoint) && !strike) {
                MisGroup.addSlot(fittedSlot);
            } else if (missile && !limitedAmmo && !strike) {
                SMisGroup.addSlot(fittedSlot);
            } else if (missile && limitedAmmo && !noAim && !strike) {
                AMisGroup.addSlot(fittedSlot);
            } else if (pointDefense && !hardpoint && !limitedAmmo) {
                PDGroup.addSlot(fittedSlot);
            } else if (antiFighter) {
                AFGroup.addSlot(fittedSlot);
            } else if (left && (hardpoint || enforceSides) && !lowFlux) {
                LGroup.addSlot(fittedSlot);
            } else if (right && (hardpoint || enforceSides) && !lowFlux) {
                RGroup.addSlot(fittedSlot);
            } else if (assault && hardpoint && !lowFlux) {
                AssGroup.addSlot(fittedSlot);
            } else if (assault && !hardpoint && !lowFlux) {
                AssTGroup.addSlot(fittedSlot);
            } else if (closeSupport && hardpoint && !lowFlux) {
                CSGroup.addSlot(fittedSlot);
            } else if (closeSupport && !hardpoint && !lowFlux) {
                CSTGroup.addSlot(fittedSlot);
            } else if (strike || limitedAmmo) {
                if (!beam) {
                    StrGroup.addSlot(fittedSlot);
                } else {
                    if (hardpoint) {
                        BeaGroup.addSlot(fittedSlot);
                    } else {
                        BeaTGroup.addSlot(fittedSlot);
                    }
                }
            } else if (fireSupport || lowFlux || special) {
                SupGroup.addSlot(fittedSlot);
            } else {
                SupGroup.addSlot(fittedSlot); // This should always be at the end
            }
        }

        // Now we consolidate the general weapon groups into five final weapon groups
        // This is only done if the number of general weapon groups is greater than 5
        // If Alex ever increases the maximum number of weapon groups, this number can be changed
        int groupCount = 0;
        for (WeaponGroupSpec group : groupList) {
            if (group.getSlots().isEmpty()) {
                groupCount++;
            }
        }

        // This section is the most difficult part of the algorithm and can make or break large ships like the Onslaught
        // Make sure you know what you are doing when adding logic here
        // Do not pass weapons into a group that may have already become null; NetBeans should warn you about this
        // Order of operations is extremely important
        if (!AFGroup.getSlots().isEmpty()) {
            if (groupCount > 5) {
                if (!PDGroup.getSlots().isEmpty()) {
                    groupCount--;
                }
                for (String toAdd : AFGroup.getSlots()) {
                    PDGroup.addSlot(toAdd);
                }
                AFGroup = null;
            }
        } else {
            AFGroup = null;
        }
        if (!AssGroup.getSlots().isEmpty()) {
            if (groupCount > 5) {
                if (!CSGroup.getSlots().isEmpty()) {
                    groupCount--;
                }
                for (String toAdd : AssGroup.getSlots()) {
                    CSGroup.addSlot(toAdd);
                }
                AssGroup = null;
            }
        } else {
            AssGroup = null;
        }
        if (!splitMissiles) {
            if (!AMisGroup.getSlots().isEmpty()) {
                if (groupCount > 5) {
                    if (!MisGroup.getSlots().isEmpty()) {
                        groupCount--;
                    }
                    for (String toAdd : AMisGroup.getSlots()) {
                        MisGroup.addSlot(toAdd);
                    }
                    AMisGroup = null;
                }
            } else {
                AMisGroup = null;
            }
        }
        if (!PDGroup.getSlots().isEmpty()) {
            if (groupCount > 5) {
                if (!SupGroup.getSlots().isEmpty()) {
                    groupCount--;
                }
                for (String toAdd : PDGroup.getSlots()) {
                    SupGroup.addSlot(toAdd);
                }
                PDGroup = null;
            }
        } else {
            PDGroup = null;
        }
        if (!splitMissiles) {
            if (!SMisGroup.getSlots().isEmpty()) {
                if (groupCount > 5) {
                    if (!AssTGroup.getSlots().isEmpty()) {
                        groupCount--;
                    }
                    for (String toAdd : SMisGroup.getSlots()) {
                        AssTGroup.addSlot(toAdd);
                    }
                    SMisGroup = null;
                }
            } else {
                SMisGroup = null;
            }
        }
        if (!AssTGroup.getSlots().isEmpty()) {
            if (groupCount > 5) {
                if (!CSTGroup.getSlots().isEmpty()) {
                    groupCount--;
                }
                for (String toAdd : AssTGroup.getSlots()) {
                    CSTGroup.addSlot(toAdd);
                }
                AssTGroup = null;
            }
        } else {
            AssTGroup = null;
        }
        if (!BeaTGroup.getSlots().isEmpty()) {
            if (groupCount > 5) {
                if (!CSTGroup.getSlots().isEmpty()) {
                    groupCount--;
                }
                for (String toAdd : BeaTGroup.getSlots()) {
                    CSTGroup.addSlot(toAdd);
                }
                BeaTGroup = null;
            }
        } else {
            BeaTGroup = null;
        }
        if (!BeaGroup.getSlots().isEmpty()) {
            if (groupCount > 5) {
                if (!CSGroup.getSlots().isEmpty()) {
                    groupCount--;
                }
                for (String toAdd : BeaGroup.getSlots()) {
                    CSGroup.addSlot(toAdd);
                }
                BeaGroup = null;
            }
        } else {
            BeaGroup = null;
        }
        if (!enforceSides) {
            if (!LGroup.getSlots().isEmpty()) {
                if (groupCount > 5) {
                    if (!RGroup.getSlots().isEmpty()) {
                        groupCount--;
                    }
                    for (String toAdd : LGroup.getSlots()) {
                        RGroup.addSlot(toAdd);
                    }
                    LGroup = null;
                }
            } else {
                LGroup = null;
            }
        }
        if (!CSTGroup.getSlots().isEmpty()) {
            if (groupCount > 5) {
                if (!SupGroup.getSlots().isEmpty()) {
                    groupCount--;
                }
                for (String toAdd : CSTGroup.getSlots()) {
                    SupGroup.addSlot(toAdd);
                }
                CSTGroup = null;
            }
        } else {
            CSTGroup = null;
        }
        if (!HvyTGroup.getSlots().isEmpty()) {
            if (groupCount > 5) {
                if (!HvyGroup.getSlots().isEmpty()) {
                    groupCount--;
                }
                for (String toAdd : HvyTGroup.getSlots()) {
                    HvyGroup.addSlot(toAdd);
                }
                HvyTGroup = null;
            }
        } else {
            HvyTGroup = null;
        }
        if (!HvyGroup.getSlots().isEmpty()) {
            if (groupCount > 5) {
                if (!StrGroup.getSlots().isEmpty()) {
                    groupCount--;
                }
                for (String toAdd : HvyGroup.getSlots()) {
                    StrGroup.addSlot(toAdd);
                }
                HvyGroup = null;
            }
        } else {
            HvyGroup = null;
        }
        if (splitMissiles && AMisGroup != null) {
            if (!AMisGroup.getSlots().isEmpty()) {
                if (groupCount > 5) {
                    if (!MisGroup.getSlots().isEmpty()) {
                        groupCount--;
                    }
                    for (String toAdd : AMisGroup.getSlots()) {
                        MisGroup.addSlot(toAdd);
                    }
                    AMisGroup = null;
                }
            } else {
                AMisGroup = null;
            }
        }
        if (splitMissiles && SMisGroup != null) {
            if (!SMisGroup.getSlots().isEmpty()) {
                if (groupCount > 5) {
                    if (!SupGroup.getSlots().isEmpty()) {
                        groupCount--;
                    }
                    for (String toAdd : SMisGroup.getSlots()) {
                        SupGroup.addSlot(toAdd);
                    }
                    SMisGroup = null;
                }
            } else {
                SMisGroup = null;
            }
        }
        if (enforceSides) {
            if (!CSGroup.getSlots().isEmpty()) {
                if (groupCount > 5) {
                    if (!SupGroup.getSlots().isEmpty()) {
                        groupCount--;
                    }
                    for (String toAdd : CSGroup.getSlots()) {
                        SupGroup.addSlot(toAdd);
                    }
                    CSGroup = null;
                }
            } else {
                CSGroup = null;
            }
        } else {
            if (CSGroup.getSlots().isEmpty()) {
                CSGroup = null;
            }
        }
        if (enforceSides && LGroup != null) {
            if (LGroup.getSlots().isEmpty()) {
                LGroup = null;
            }
        }
        if (RGroup.getSlots().isEmpty()) {
            RGroup = null;
        }
        if (StrGroup.getSlots().isEmpty()) {
            StrGroup = null;
        }
        if (SupGroup.getSlots().isEmpty()) {
            SupGroup = null;
        }
        if (MisGroup.getSlots().isEmpty()) {
            MisGroup = null;
        }

        if (variant.getWeaponGroups().size() < 5) {
            for (int i = variant.getWeaponGroups().size(); i < 5; i++) {
                variant.addWeaponGroup(new WeaponGroupSpec());
            }
        }

        // I didn't make a loop for this because the order in which you put these functions determines their order on the ship
        int currentGroup = 0;
        if (HvyGroup != null) {
            integrateGroup(HvyGroup, variant.getGroup(currentGroup));
            currentGroup++;
        }
        if (HvyTGroup != null) {
            integrateGroup(HvyTGroup, variant.getGroup(currentGroup));
            currentGroup++;
        }
        if (BeaGroup != null) {
            integrateGroup(BeaGroup, variant.getGroup(currentGroup));
            currentGroup++;
        }
        if (BeaTGroup != null) {
            integrateGroup(BeaTGroup, variant.getGroup(currentGroup));
            currentGroup++;
        }
        if (LGroup != null) {
            integrateGroup(LGroup, variant.getGroup(currentGroup));
            currentGroup++;
        }
        if (RGroup != null) {
            integrateGroup(RGroup, variant.getGroup(currentGroup));
            currentGroup++;
        }
        if (AssGroup != null) {
            integrateGroup(AssGroup, variant.getGroup(currentGroup));
            currentGroup++;
        }
        if (CSGroup != null) {
            integrateGroup(CSGroup, variant.getGroup(currentGroup));
            currentGroup++;
        }
        if (AssTGroup != null) {
            integrateGroup(AssTGroup, variant.getGroup(currentGroup));
            currentGroup++;
        }
        if (CSTGroup != null) {
            integrateGroup(CSTGroup, variant.getGroup(currentGroup));
            currentGroup++;
        }
        if (StrGroup != null) {
            integrateGroup(StrGroup, variant.getGroup(currentGroup));
            currentGroup++;
        }
        if (AMisGroup != null) {
            integrateGroup(AMisGroup, variant.getGroup(currentGroup));
            currentGroup++;
        }
        if (MisGroup != null) {
            integrateGroup(MisGroup, variant.getGroup(currentGroup));
            currentGroup++;
        }
        if (SMisGroup != null) {
            integrateGroup(SMisGroup, variant.getGroup(currentGroup));
            currentGroup++;
        }
        if (SupGroup != null) {
            integrateGroup(SupGroup, variant.getGroup(currentGroup));
            currentGroup++;
        }
        if (AFGroup != null) {
            integrateGroup(AFGroup, variant.getGroup(currentGroup));
            currentGroup++;
        }
        if (PDGroup != null) {
            integrateGroup(PDGroup, variant.getGroup(currentGroup));
            currentGroup++;
        }
    }
[close]
Logged

Tecrys

  • Captain
  • ****
  • Posts: 478
  • Creator of Biomancy Genetic Engineering
    • View Profile
Re: The Radioactive Code Dump
« Reply #86 on: April 12, 2014, 04:55:54 PM »

Hi everyone!

I thought this might be useful:

This script is a modification of Xenoarghs weapon mirror script. It mirrors asymmetrical weapons and their animation.

It's nothing more then 2 scripts bashed together:
Spoiler
Code
package data.scripts.weapons;

import com.fs.starfarer.api.AnimationAPI;
import com.fs.starfarer.api.combat.CombatEngineAPI;
import com.fs.starfarer.api.combat.EveryFrameWeaponEffectPlugin;
import com.fs.starfarer.api.combat.WeaponAPI;
import com.fs.starfarer.api.graphics.SpriteAPI;
import java.util.*;

public class BaseAnimateOnFireEffect2 implements EveryFrameWeaponEffectPlugin
{
    // Default to 15 frames per second
    private float timeSinceLastFrame, timeBetweenFrames = 1.0f / 140f;
    private Map pauseFrames = new HashMap();
    private int curFrame = 0, pausedFor = 0;
    private boolean isFiring = false;
private boolean runOnce2 = false;
private boolean runOnce3 = false;

    protected void setFramesPerSecond(float fps)
    {
        timeBetweenFrames = 1.0f / fps;
    }

    protected void pauseOnFrame(int frame, int pauseFor)
    {
        pauseFrames.put(frame, pauseFor);
    }


    private void incFrame(AnimationAPI anim)
    {

        if (pauseFrames.containsKey(curFrame))
        {
            if (pausedFor < (Integer) pauseFrames.get(curFrame))
            {
                pausedFor++;
                return;
            }
            else
            {
                pausedFor = 0;
            }
        }

        curFrame = Math.min(curFrame + 1, anim.getNumFrames() - 1);
    }

    @Override
    public void advance(float amount, CombatEngineAPI engine, WeaponAPI weapon)
    {
        if (engine.isPaused())
        {
            return;
        }

        AnimationAPI anim = weapon.getAnimation();
        anim.setFrame(curFrame);

        if (isFiring)
        {
            timeSinceLastFrame += amount;

            if (timeSinceLastFrame >= timeBetweenFrames)
            {
                timeSinceLastFrame = 0f;
               
                anim.setFrame(curFrame);
        if(runOnce2 == false){ 
            if (weapon.getShip().getOwner() == 0 && weapon.getLocation().getX() < weapon.getShip().getLocation().getX()   
                || weapon.getShip().getOwner() == 1 && weapon.getLocation().getX() > weapon.getShip().getLocation().getX()){ 
                SpriteAPI theSprite = weapon.getSprite(); 
                theSprite.setWidth(-theSprite.getWidth()); 
                theSprite.setCenter(-theSprite.getCenterX(),theSprite.getCenterY()); 
            } 
           
        } 
             incFrame(anim);

                if (curFrame == anim.getNumFrames() - 1)
                {
                    isFiring = false;
runOnce2 = true; 
                }
            }
        }
        else
        {
            if (weapon.isFiring() && weapon.getChargeLevel() == 1.0f)
            {
                isFiring = true;
                incFrame(anim);
                anim.setFrame(curFrame);
            }
            else
            {
                curFrame = 0;
                anim.setFrame(curFrame);
        if(runOnce3 == false){ 
            if (weapon.getShip().getOwner() == 0 && weapon.getLocation().getX() < weapon.getShip().getLocation().getX()   
                || weapon.getShip().getOwner() == 1 && weapon.getLocation().getX() > weapon.getShip().getLocation().getX()){ 
                SpriteAPI theSprite = weapon.getSprite(); 
                theSprite.setWidth(-theSprite.getWidth()); 
                theSprite.setCenter(-theSprite.getCenterX(),theSprite.getCenterY()); 
            } 
            runOnce3 = true; 
        }
            }
        }
    }
}
[close]

It looks soemtimes ugly in refit, the weapons are only mirrored in combat, after the first animation cycle all frames and the weapon sprite are mirrored.

Thought I should dump this here.
Logged
Bringing biological warfare to Stasector since 2014.
Let's say I'm the cave man type of a modder, I put the square through the triangle in kindergarten and even succeed.
Such a stupid thing to quote myself, oh well

Dark.Revenant

  • Admiral
  • *****
  • Posts: 2551
    • View Profile
    • Sc2Mafia
    • Email
Re: The Radioactive Code Dump
« Reply #87 on: April 15, 2014, 05:26:11 AM »

Less expensive Tow Cable code.  The trick is that it only runs *some* of the frames rather than *all* of the frames, and even runs all at once instead of going through once per Tow Cable.

Be warned: this is very hackish, but seems to work.  I tried a more elegant approach using onFleetSync but it kept producing infinite feedback loops (killing the framerate just as bad as before), and without some kind of event system I had no way of mitigating that.

At least in this version you can safely have hundreds of Oxen without killing the campaign framerate.  Enjoy.

Spoiler
Code: java
package data.scripts.hullmods;

import com.fs.starfarer.api.Global;
import java.util.*;

import com.fs.starfarer.api.campaign.BuffManagerAPI.Buff;
import com.fs.starfarer.api.campaign.CampaignFleetAPI;
import com.fs.starfarer.api.combat.HullModEffect;
import com.fs.starfarer.api.combat.HullModFleetEffect;
import com.fs.starfarer.api.combat.MutableShipStatsAPI;
import com.fs.starfarer.api.combat.MutableStat;
import com.fs.starfarer.api.combat.ShipAPI;
import com.fs.starfarer.api.combat.MutableStat.StatMod;
import com.fs.starfarer.api.combat.ShipAPI.HullSize;
import com.fs.starfarer.api.fleet.FleetMemberAPI;

public class TowCable implements HullModEffect, HullModFleetEffect {

    public static final String HULLMOD_ID = "tow_cable";

    public static class TowCableBuff implements Buff {

        public int buffAmount = 1;
        private final String buffId;

        public TowCableBuff(String buffId) {
            this.buffId = buffId;
        }

        @Override
        public boolean isExpired() {
            return false;
        }

        @Override
        public String getId() {
            return buffId;
        }

        @Override
        public void apply(FleetMemberAPI member) {
            member.getStats().getMaxBurnLevel().modifyFlat(buffId, buffAmount);
        }

        @Override
        public void advance(float days) {
        }
    };

    private final static float INTERVAL = 0.2f; // in days
    private long timestamp = 0;
    private long lastTimestamp = 0;

    // We only run this once in a while, since exact timing is not an issue in the campaign map
    @Override
    public void advanceInCampaign(CampaignFleetAPI fleet) {
        if (fleet == null) {
            return;
        }

        if (timestamp == 0) {
            timestamp = Global.getSector().getClock().getTimestamp();
            lastTimestamp = timestamp;
        }

        if (Global.getSector().getClock().getElapsedDaysSince(timestamp) < INTERVAL && Global.getSector().getClock().getTimestamp() != lastTimestamp) {
            return;
        }

        timestamp = Global.getSector().getClock().getTimestamp();
        lastTimestamp = timestamp;
        List<FleetMemberAPI> all = fleet.getFleetData().getMembersListCopy();

        int numCables = 0;
        float towSpeed = Float.MAX_VALUE; // We make an assumption that all Oxen have the same burn speed
        for (FleetMemberAPI curr : all) {
            if (!curr.canBeDeployedForCombat()) {
                continue;
            }

            if (curr.getVariant().getHullMods().contains(HULLMOD_ID)) {
                numCables++;
                towSpeed = Math.min(towSpeed, getMaxBurnWithoutCables(curr));
            }
        }
        if (numCables <= 0) {
            cleanUpTowCableBuffs(fleet);
            return;
        }

        Map<FleetMemberAPI, Integer> cables = new HashMap();

        for (int cableIndex = 0; cableIndex < numCables; cableIndex++) {
            FleetMemberAPI slowest = getSlowest(all, towSpeed, cables);
            if (slowest == null) {
                break;
            }
            Integer bonus = cables.get(slowest);
            if (bonus == null) {
                bonus = Integer.valueOf(0);
            }
            bonus = bonus + 1;
            cables.put(slowest, bonus);
        }

        for (FleetMemberAPI curr : all) {
            if (!cables.containsKey(curr)) {
                curr.getBuffManager().removeBuff(TOW_CABLE_KEY);
                continue;
            }

            if (cables.get(curr) <= 0) {
                curr.getBuffManager().removeBuff(TOW_CABLE_KEY);
                continue;
            }

            boolean renew = true;
            for (StatMod mod : curr.getStats().getMaxBurnLevel().getFlatMods().values()) {
                if (mod.getSource().equals(TOW_CABLE_KEY)) {
                    if (mod.value == cables.get(curr)) {
                        renew = false;
                    }
                }
            }

            if (renew) {
                TowCableBuff buff = new TowCableBuff(TOW_CABLE_KEY);
                buff.buffAmount = cables.get(curr);
                curr.getBuffManager().addBuff(buff);
            }
        }
    }

    @Override
    public void onFleetSync(CampaignFleetAPI fleet) {
    }

    public TowCable() {

    }

    @Override
    public void advanceInCampaign(FleetMemberAPI member, float amount) {
    }

    private FleetMemberAPI getSlowest(List<FleetMemberAPI> all, float speedCutoff, Map<FleetMemberAPI, Integer> cables) {
        FleetMemberAPI slowest = null;
        float minLevel = Float.MAX_VALUE;
        for (FleetMemberAPI curr : all) {
            if (!isSuitable(curr)) {
                continue;
            }

            float baseBurn = getMaxBurnWithoutCables(curr);
            Integer bonus = cables.get(curr);
            if (bonus == null) {
                bonus = Integer.valueOf(0);
            }

            if (bonus >= getMaxCablesFor(curr)) {
                continue;
            }

            float burnLevel = baseBurn + bonus;

            if (burnLevel >= speedCutoff) {
                continue;
            }

            if (burnLevel < minLevel) {
                minLevel = burnLevel;
                slowest = curr;
            }
        }
        return slowest;
    }

    private int getMaxCablesFor(FleetMemberAPI member) {
        switch (member.getHullSpec().getHullSize()) {
            case CAPITAL_SHIP:
                return 4;
            case CRUISER:
                return 3;
            case DESTROYER:
                return 2;
            case FRIGATE:
                return 1;
        }
        return 1;
    }

    private static float getMaxBurnWithoutCables(FleetMemberAPI member) {
        MutableStat burn = member.getStats().getMaxBurnLevel();
        float val = burn.getModifiedValue();
        float sub = 0;
        for (StatMod mod : burn.getFlatMods().values()) {
            if (mod.getSource().equals(TOW_CABLE_KEY)) {
                sub = mod.getValue();
                break;
            }
        }
        return Math.max(0, val - sub);
    }

    private boolean isSuitable(FleetMemberAPI member) {
        return !member.isFighterWing();
    }

    private void cleanUpTowCableBuffs(CampaignFleetAPI fleet) {
        if (fleet == null) {
            return;
        }
        for (FleetMemberAPI curr : fleet.getFleetData().getMembersListCopy()) {
            curr.getBuffManager().removeBuff(TOW_CABLE_KEY);
        }
    }

    /**
     * One instance of the buff object per ship with a Tow Cable.
     */
    public static final String TOW_CABLE_KEY = "TowCable_PersistentBuffs";

    @Override
    public void advanceInCombat(ShipAPI ship, float amount) {
    }

    @Override
    public void applyEffectsAfterShipCreation(ShipAPI ship, String id) {
    }

    @Override
    public void applyEffectsBeforeShipCreation(HullSize hullSize, MutableShipStatsAPI stats, String id) {
    }

    @Override
    public boolean isApplicableToShip(ShipAPI ship) {
        return true;
    }

    @Override
    public String getDescriptionParam(int index, HullSize hullSize) {
        return null;
    }

}
[close]
« Last Edit: April 16, 2014, 03:39:50 AM by Dark.Revenant »
Logged

Sundog

  • Global Moderator
  • Admiral
  • *****
  • Posts: 1051
    • View Profile
    • Email
Re: The Radioactive Code Dump
« Reply #88 on: April 27, 2014, 01:42:23 PM »

A hull mod for stationary structures/buildings/sentry guns/stations with predefined locations.

Spoiler
To use it, create a hullmod that uses the following script:
Code: java
package data.hullmods;

import com.fs.starfarer.api.combat.CombatEntityAPI;
import com.fs.starfarer.api.combat.ShipAPI;
import com.fs.starfarer.api.fleet.FleetMemberAPI;
import java.util.WeakHashMap;
import org.lwjgl.util.vector.Vector2f;

public class GravityAnchor extends BaseHullMod {
    static WeakHashMap locations = new WeakHashMap();
    static WeakHashMap facings = new WeakHashMap();
    
    public static void anchorShip(FleetMemberAPI ship, Vector2f location, float angle) {
        locations.put(ship.getId(), location);
        facings.put(ship.getId(), angle);
    }
    public static void anchorShip(FleetMemberAPI ship, Vector2f location) {
        locations.put(ship.getId(), location);
    }
    public static void anchorShip(ShipAPI ship, Vector2f location, float angle) {
        locations.put(ship.getFleetMemberId(), location);
        facings.put(ship.getFleetMemberId(), angle);
    }
    public static void anchorShip(ShipAPI ship, Vector2f location) {
        locations.put(ship.getFleetMemberId(), location);
    }

    public void setLocation(CombatEntityAPI entity, Vector2f location) {
        Vector2f dif = new Vector2f(location);
        Vector2f.sub(location, entity.getLocation(), dif);
        Vector2f.add(entity.getLocation(), dif, entity.getLocation());
    }

    @Override
    public void advanceInCombat(ShipAPI ship, float amount) {
        super.advanceInCombat(ship, amount);
        
        String id = ship.getFleetMemberId();
        
        if(!locations.containsKey(id)) return;
        else setLocation(ship, (Vector2f)locations.get(id));
        
        if(!facings.containsKey(id)) return;
        else ship.setFacing((Float)facings.get(id));
    }

    @Override
    public boolean isApplicableToShip(ShipAPI ship){
        return false;
    }
}

Add the hullmod to the .ship file of the ship you want to remain stationary.

Use GravityAnchor.anchorShip() to assign a location and optional facing to the ship.
In a mission definition, that would look something like this;
Code: java
FleetMemberAPI member = api.addToFleet(side, variantID, FleetMemberType.SHIP, false);
GravityAnchor.anchorShip(member, new Vector2f(100, -100), 360);

Disclaimer: this isn't tested thoroughly at all, and I'm sure it causes issues with collision resolution.
[close]
« Last Edit: April 27, 2014, 01:45:53 PM by Sundog »
Logged

xenoargh

  • Admiral
  • *****
  • Posts: 4856
  • naively breaking things!
    • View Profile
Re: The Radioactive Code Dump
« Reply #89 on: April 29, 2014, 08:51:46 AM »

Caveat:  it's considerably better (imo) to do the above through custom EveryFrameCombatScript plugins invoked when the battle is constructed.  Just been down that road while writing up an Admiral AI :)
Logged
Please check out my SS projects :)
Xeno's Mod Pack
Pages: 1 ... 4 5 [6] 7 8 9