Fractal Softworks Forum

Please login or register.

Login with username, password and session length

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Messages - dmaiski

Pages: 1 [2] 3 4 ... 28
16
i have just had a weird game... 3 warthogs have just sucsessfully tanked the entire ammo suply of a conquest with vanilla gun setups :P


also bugs!

this battle:
Spoiler
[close]
ends exactly 1 second after it starts
(with no the killing/capturing of the noobs!!!)

17
Suggestions / Re: Spoiled goods/backstabs
« on: May 13, 2014, 01:09:51 PM »
personaly i think this is overcomplicated, and not really realistic. "FUN!" in a trading/economy sim is verry difrent from you avarage shoot em up or even most strategy games lack it entirely (excluding the original TA series, the spring BA, ZK, NOTA, and DF, Aurora)

FUN! is an eco/trading game comes mainly from "economic gain" not sabotage/espionage/warfare. it is far more fun to crush your enemies with a well planned trade embargo/piracy/buyout then it is to poison them, because poison is verry abstract, and limiting their access to goods through economic and subterfuge means is much more enjoyable and robust.


if you want to see a "serious" space economy game, look at the distant worlds series. Being able to set something like that up in starsector would be great
-vastly complex AI managed trade and construction economy
--mostly automated, and pretty "self sufficient"
---frees up the player to do what they want (or micro EVRYTHING)


another game to try would be starship tychoon, probably one of the best space trade/shipping games ever made
-"trade" is performed entirely through contracts,
--you cant "buy" goods, you simply bid on the contract to transport them from one place to another
--progression is done through aquisition of new ships and techs/crew(officers?) to make your fleet better


a third game is Factorio, a factory running game
-the player sets up production lines
--evrything can be made to autonamusly meet supply and demand as needed
--massive amounts of somponents and precursors for the player to make


and finaly there is a fourth: patrician trading/economy game series
-the AI trading capacity in that game is limmited and asymetric
--not all demand is met by the AI
-the player can thus "cotroll" the games economy simply through economic might
--being the sole producer of slat, or tar, or cloth, can be VERRY lucrative if you can restrict its production elswhere
---you can "influence" the world simply by excluding or including cities in your trade routes

also in patritian
-evry building can be bought and built
--city builder rent/income from properties you own
--great fun for those who want to own the world


this image aptly summs up what will get a econ, trading, city/country building, production loving players blood pumping
Spoiler
[close]
;D ;D ;D ;D ;D ;D ;D ;D ;D ;D ;D ;D ;D ;D ;D ;D ;D ;D ;D ;D ;D ;D ;D ;D ;D
to econ players that map means alot, its beutifull, its LOVE!
to non-econ players, its like the screen has suddenly been filled with white noise
:P :P :P :P :P :P :P :P :P :P :P :P :P :P :P :P :P :P :P :P :P :P :P :P :P

18
Suggestions / Re: Rapid Closure AI Change
« on: May 12, 2014, 02:10:35 PM »
heres the issue with that :P

just using the "strike" tag requires that all stuff be tagged with "strike" or it wont be recognized

then how do you solve issues where a ship is armed with both strike, and non-strike weaps

also strike has a verry limited scope, and is an artificial means of making an AI adapt to situation, it would be verry easy to abuse

if you are tracking aproching ships, this can give concrete values, they can also be used even for non-"strike" tracking components of the AI(making it faster).

19
Suggestions / Re: Rapid Closure AI Change
« on: May 11, 2014, 03:19:05 PM »
:P well you can allways track the delta flux, and if delta flux exceeds threshold make the ship play defencively

:P and making an array of enemy ships and tracking "main gun" ranges, and distance to ship can be used to determine what you wan't

ultra rough off the top of my head pseudocode :P
Spoiler
Code: java
list.ships
array shipstats[][]
for(i=1; i<=ships.size; i++;){

if(shipstats[i][1] = null){
shipstats[i][1] = AnalyseMainGuns(ships(i).getWeapons); //gets a "danger range" for the ship
}

DisDelt = GetDistatnce(self, ships(i));

if (shipstats[i][2] > 50+DisDelt && DisDelt < shipstats[i][1]){
retreat = true;
}

shipstats[i][2] = GetDistatnce(self, ships(i))
}
ect...
kinda thing
[close]

20
cant you add a component to the ship AI to map the local threat level
(nothing complex, just get locations of neary ships (in angles), check class, cheack who they belong to, +1 if your team -1 if enemy)

+1 for frig
+2 for dest
+4 for cruiser
ect...

then use this map to determine ship movment, ie a "bravery" threshold, so if the map indicates that theres -31 points in direction 0deg and +40 in direction -55deg, even if [target objective] is in direction 0deg, ship will travel in direction [(0 + -55)/2 = deg]

basicaly forcing ships to bunch up at the ship AI level

ofcource have tresholds for ignoring the map, or fuge factors if ship class>map level


also you could add another similar function to make unassigned ships automaticaly guard/support ships with definite asignments

21
Suggestions / Re: why is it that in starsector Losing != FUN!
« on: May 09, 2014, 04:21:41 PM »
:D this could be a valid use for tow ships!

you can only tow away as many hulks as you have tow cables for ^.^

22
Modding / Re: LeadVector
« on: May 09, 2014, 05:59:05 AM »
@Alex

using a slightly modified script:
Spoiler
Code: java
    //same as Lead vector, but returns lead time
    public static float LeadTime(Vector2f TLoc, Vector2f TVel, Vector2f MLoc, Vector2f MVel)
    {
        //get missiles speed
        float MSpeed = (float)Math.sqrt(MVel.lengthSquared());

        //separate out the vectors
        float Tx = TLoc.getX();
        float Ty = TLoc.getY();
        float Mx = MLoc.getX();
        float My = MLoc.getY();

        float TVx = TVel.getX();
        float TVy = TVel.getY();

        //subtract position vectors
        float x1 = Tx - Mx;
        float y1 = Ty - My;

        //quadratic fun
        float h1 = TVx*TVx + TVy*TVy - MSpeed*MSpeed;
        if (h1==0)
        {
            h1= (float) .0001;
        }

        float minusMHalf = -(x1*TVx + y1*TVy)/h1;  // h2/h1

        float discriminant = minusMHalf * minusMHalf - (x1*x1 + y1*y1)/h1; // (h2/h1)^2-h3/h1 (ie D)

        //can they intersect?
        if (discriminant < 0)
        {
            return 0;
        }


        double root = Math.sqrt(discriminant);

        double t1 = minusMHalf + root;
        double t2 = minusMHalf - root;

        double tMin = Math.min(t1, t2);
        double tMax = Math.max(t1, t2);
        //which of the 2 is smaller
        double time = tMin > 0 ? tMin : tMax;

        //can return -ve time (this is less then useful)
        if (time < 0)
        {
            return 0;
        }

        //calculate vector
        return (float)time;
    }
[close]

you can get the time component

to get a normal intercept point you would use
velocity(vector) * time

to get accelerating object intercept you would use
velocity(vector) * time +  acceleration(vector) * 0.5f *time

or even more fancy (if you want to be super accurate)
Spoiler
(MaxSpeed-CurSpeed)/acceleration = ATime

if(ATime<time)  //for cases when a ship can accelerate to max speed before missile hits
velocity(vector) * ATime +  acceleration(vector) * 0.5f *ATime + Norm.acceleration(vector) * MaxSpeed * (time- ATime)
else           //for cases when it cant
velocity(vector) * time + acceleration(vector) * 0.5f *Time = LeadLoc

then for super pointless levels of accuracy, perform a recursive calculation:
(warning : using recursive calculations is expencive... and kinda pointless unless you want missiles to be ably to track weaving talons or somesuch)
Spoiler
norm.LeadLoc * TSpeed = R1

LeadTime(Tloc, R1, MLoc, MVel) * norm.LeadLoc = LeadLoc
[close]

LeadLoc + TLoc = intercept coordinates

unless the ship actively changes direction this does not need to chage at all
so you can use a check weather the ship changed its end directional vector, and only recalculate if it has

[close]

there acceleration issue solved :P
(:P im glad my equasion gets time instead of angle, time is so much more usefull :P)

on missile strafing:
Spoiler
its not really required, my AIs can be set to no-strafe mode quite easily with no impact on performance

all that needs to be done is you calculate curent vector, the vector adjustment needed to be on target,
then calculate vector direction you need to go to perform the adjustment
then you turn the missile into that vector direction

...and presto, no need to strafe: the missile does look like it is flying crooked though
(thats why strafe is perfered, it simply looks better)

sidenote: VectorDirection is a normalized vector (i use them almost exclusively when writing AI)
i substitute these for all angles since the bulk of the AI prefers vector calculations instead of angles, makes coding faster
[close]

23
Modding / Re: LeadVector
« on: May 08, 2014, 02:34:22 PM »
actualy if missile can not catch target it will simply get a lead of Vector2f(0,0) - djinking wont have any effect

if it is already faster then the target, it will allways be aimed at the fastest route to the target - djinking will have no effect


for example, lets say missile is 2000AU away, and target is traveling at speed N in a perpendicular vector

the angle the missile holds is 20deg from DirectLineToTarget (ie. its lead point)

target does a 180deg turn
the missile only needs to do a 40deg turn to stay on target

the missile looses absolutley no speed in this manuver (asuming its acceleration is non-negligable compared to its max speed)
the target looses all its speed in this manuver

effectively by djinking you actualy make it MORE likley that the missile will hit you, not less
(:P as i said earlier evasive manuvers only work in the realms of movie magic, large turn arks, and bad targeting AI :P)

24
Suggestions / Re: Change conquest turret position
« on: May 08, 2014, 02:22:50 PM »
even in an AI ve AI fight, conquest pwns onslaught with these changes

having 1 more heavy balistic then onslaught, and the reapere does it (also stat wise conquest is a bit better then onslaught in speed and ordenance points/weapon mounts)

25
Modding / Re: LeadVector
« on: May 08, 2014, 02:13:40 PM »
@Alex

what the lead point looks like on a target with various velocity directions
(outer line is where the LeadPoint will aim you towards)


on dodging, PD, and accuracy:
i used a backwards aproach, i STARTED from perfectly accurate, then I added variables to intentionaly make the AI less accurate as needed into the rest of the code, but its true, undodgeable misiles are alot less fun if you are on the reciving end :P

26
Modding / Re: LeadVector
« on: May 08, 2014, 01:57:30 PM »
@xeno

time*TargetVelocity=location

location1 to location2 = angle

:P your code does this internaly, mine does it externaly :P

@Dark.Revenant
yea... its nasty enough to make harpoons hit... well... other harpoons(wich are chasing fighters) a la PD missiles
Much relevant post with pics:
Spoiler
im re-writing all my scripts from scratch using beter/more accurate/fixed methods

ill put them all in one post


(this is a new script(also the base for all the others))
basic long range point defence missile ai
it can hit a missile with a harpoon 99% of the time at 1000<range effectivness drops as missiles get too close
the primary point of this ai is to make and improve targeting and pathing of a missile
(it has an extreme level of tracking ability and accuracy)
Spoiler
pictures of it in action
Spoiler


yes that is a vanilla harpoon,
red dot(target lead),
green dot(nose of target (part targeting)),
white line(velocity vector of the missile),
streaking on dots indicates distance moved in last second
[close]

LRPDai
Spoiler
Code: java
package data.scripts.MissileAI;


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

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

//import static jar.CustomAPI.LeadVector;
import static jar.CustomAPI.getEnemyMissilesInArk;
import static org.lwjgl.util.vector.Vector2f.add;

public class LRPDai implements MissileAIPlugin
{
    // Our missile object
    private final MissileAPI missile;
    // Our current target (can be null)
    private MissileAPI target;

    public static float searchrange = 500; //500 range default

    public static float Ark = 30;          //60deg ark   default

    boolean newlaunch=true;                //only do mouse target once on a newly launched missile

    public LRPDai(MissileAPI missile)
    {
        this.missile = missile;
        searchrange=missile.getWeapon().getRange();     //based on weapon
        Ark=5+missile.getWeapon().getArc()/4;           //based on weapon

        // Support for 'fire at target by clicking on them' behavior
        if (newlaunch=true)
        {
            newlaunch=false;
            //get targets near mouse
            java.util.List directTargets = CombatUtils.getMissilesWithinRange(
                    missile.getSource().getMouseTarget(), 100f, true);

            if (!directTargets.isEmpty())
            {
                MissileAPI tmp;
                for (Iterator iter = directTargets.iterator(); iter.hasNext(); )
                {
                    //filter out friendlies
                    tmp = (MissileAPI) iter.next();
                    if (tmp.getOwner() != missile.getSource().getOwner())
                    {
                        target = tmp;
                        break;
                    }
                }
            }
        }

        // Otherwise, use default targeting AI
        if (target == null)
        {
            target = findBestTarget(missile);
        }
    }
   
   
    public static MissileAPI findBestTarget(MissileAPI missile)
    {
        //find targets in ark in front of missile
        ArrayList targets = getEnemyMissilesInArk(missile, Ark, searchrange, true);
        if (!targets.isEmpty())
        {   //pick random missile in list     //replace with .get(0) for nearest
            return (MissileAPI) targets.get((int)(targets.size()*Math.random()));
        }                                                                         
        else return null;

    }

    @Override
    public void advance(float amount)
    {
        // Apparently commands still work while fizzling
        if (missile.isFading() || missile.isFizzling())
        {
            return;
        }

        //find a target
        if (target == null)
        {
            target = findBestTarget(missile);
        }



        if (target!=null ) //if you have a target
        {
            //aming
            //1step calculations of various stats
            Vector2f MVel = missile.getVelocity();
            Vector2f MLoc = missile.getLocation();
            Vector2f TLoc = target.getLocation();
            Vector2f TVel = target.getVelocity();
            //float MSpeed = (float)Math.sqrt(MVel.lengthSquared());
            //float TSpeed = (float)Math.sqrt(TVel.lengthSquared());
            float MFace = missile.getFacing();
            double TfaceRad = Math.toRadians(target.getFacing());
            float TCol = target.getCollisionRadius();
            float sx = (float) (TCol*.5*Math.cos(TfaceRad));
            float sy = (float) (TCol*.5*Math.sin(TfaceRad));
            Vector2f TNose = new Vector2f(sx, sy);
            //float RangeToTarget = MathUtils.getDistance(TLoc, MLoc);
            //float TimeToTarget = RangeToTarget/MSpeed;                      //how long till you hit

            //testing InterceptPoint
            Vector2f Lvec = LeadVector(TLoc, TVel, MLoc, MVel);

            //lead target
            Vector2f TLead = add(TLoc,            //target location+
                    Lvec,       //target speed*time to get to target+
                    null);      // if its too long just assume 3 seconds is long enough to course correct



            //aim at nose (can be changed to part targeting with a few tweaks)
            Vector2f TNoseLead = add(TLead, TNose, null);//aim at the nose of the target(optional)

            //main aiming (to find angle you are off target by)
            float AngleToEnemy = MathUtils.getAngle(MLoc, TNoseLead);
            float AtTarget = getAngleDifference(  //how far off target you are
                    MFace, AngleToEnemy);         //where missile pointing, where target is in relation

            float AbsAngD = Math.abs(AtTarget);


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


            //point towards target
            if (AbsAngD > 0.5)
            {
                missile.giveCommand(AtTarget > 0
                        ? ShipCommand.TURN_LEFT : ShipCommand.TURN_RIGHT);
            }

            if (AbsAngD < 5)
            {


                //course correct for missile velocity vector (some bugs when severly off target)
                float MFlightAng = MathUtils.getAngle(new Vector2f(0, 0), MVel);
                float MFlightCC = getAngleDifference(MFace, MFlightAng);
                if (Math.abs(MFlightCC)>20)
                {
                missile.giveCommand(MFlightCC < 0
                        ? ShipCommand.STRAFE_LEFT : ShipCommand.STRAFE_RIGHT);
                }

            }

            //stop turning once you are on target (way of the hack, ignores missile limitations)
            if (AbsAngD<0.4)
            {
                missile.setAngularVelocity(0);
            }

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


            //acceleration code
            if (AbsAngD < 40)
            {
                missile.giveCommand(ShipCommand.ACCELERATE);
            }
            if (MVel.lengthSquared()<TVel.lengthSquared())
            {
                missile.giveCommand(ShipCommand.ACCELERATE);
            }
            if (AbsAngD>120)        //if you missed stop and turn around
            {
                missile.giveCommand(ShipCommand.DECELERATE);
            }



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


            //testcode    spawns particle at aim points
            CombatEngineAPI engine = Global.getCombatEngine(); //engine
            engine.addSmoothParticle(TLead, new Vector2f(0,0), 5, 1, 1, new Color(255,10,15,255));
            engine.addSmoothParticle(TNoseLead, new Vector2f(0,0), 5, 1, 1, new Color(93, 255, 40,255));
            engine.addSmoothParticle(MLoc, multV2f(MVel, 4), 5, .5f, 1, new Color(248, 244, 255,255));
        }


        //clear target code if target is gone
        if (target == null // unset
                ||  ( missile.getOwner() == target.getOwner() )        // friendly
                ||  !Global.getCombatEngine().isEntityInPlay(target) ) // completely removed
        {

            target = findBestTarget(missile);
            return;
        }
    }




    // Will be in next LazyLib version
    public static float getAngleDifference(float angle1, float angle2)
    {
        float distance = (angle2 - angle1) + 180f;
        distance = (distance / 360.0f);
        distance = ((distance - (float) Math.floor(distance)) * 360f) - 180f;
        return distance;
    }

    //multiply vectors //own code
    public static Vector2f multV2f(Vector2f Vector1, float Multiplier)
    {
        float v1x = Vector1.getX()*Multiplier;
        float v1y = Vector1.getY()*Multiplier;
        Vector2f v1end = new Vector2f(v1x, v1y);
        return v1end;
    }
    //find intercept between a missile and a target
    //adapted from code by Jens Seiler
    //http://jaran.de/goodbits/2011/07/17/calculating-an-intercept-course-to-a-target-with-constant-direction-and-velocity-in-a-2-dimensional-plane/
    //have fun if you want to actually understand what going on
    //basicaly gets where T will be by the time M gets to it
    public static Vector2f LeadVector(Vector2f TLoc, Vector2f TVel, Vector2f MLoc, Vector2f MVel)
    {
        //get missiles speed
        float MSpeed = (float)Math.sqrt(MVel.lengthSquared());

        //separate out the vectors
        float Tx = TLoc.getX();
        float Ty = TLoc.getY();
        float Mx = MLoc.getX();
        float My = MLoc.getY();

        float TVx = TVel.getX();
        float TVy = TVel.getY();
        float MVx = MVel.getX();
        float MVy = MVel.getY();

        //subtract position vectors
        float x1 = Tx - Mx;
        float y1 = Ty - My;

        //quadratic fun
        float h1 = TVx*TVx + TVy*TVy - MSpeed*MSpeed;
        if (h1==0)
        {
            h1= (float) .00001;
        }

        float minusMHalf = -(x1*TVx + y1*TVy)/h1;  // h2/h1

        float discriminant = minusMHalf * minusMHalf - (x1*x1 + y1*y1)/h1; // (h2/h1)^2-h3/h1 (ie D)

        //can they intersect?
        if (discriminant < 0)
        {
            return TLoc;
        }


        double root = Math.sqrt(discriminant);

        double t1 = minusMHalf + root;
        double t2 = minusMHalf - root;

        double tMin = Math.min(t1, t2);
        double tMax = Math.max(t1, t2);
        //which of the 2 is smaller
        double time = tMin > 0 ? tMin : tMax;

        //can return -ve time (this is less then useful)
        if (time < 0)
        {
            return TLoc;
        }

        //calculate vector
        return new Vector2f((float)(time * TVx), (float)(time * TVy));
    }
}
[close]
[close]
[close]

@Alex
i actualy made a script wich spawned missiles using this targeting method AND vanilla missile ai at the same time... long story short this method was much more accurate

27
Modding / Re: LeadVector
« on: May 08, 2014, 01:41:32 PM »
LeadVector + TargetLocation = ThePointYouGoTo

:P

old one if it couldnt reach target gave you [TargetLocation] instead of [Vector2f(0,0)]
so you got TargetLocation + TargetLocation = VerryFarAway

28
Modding / Re: LeadVector
« on: May 08, 2014, 01:19:34 PM »
i have this weird feeling that your code and my code are doing identical things, just written in a difrent way :P

*after looking at it closely*
yep, its identical (mine calculates time, yours calculates angle, but the actual process to get there is the same)

29
Modding / Re: LeadVector
« on: May 08, 2014, 12:57:42 PM »
Fixed (for some reason i had it returning Tloc instead of Vector2f(0,0) in the failure to intercept case)

Quote
Side note: it's not using the MVx/MVy values anywhere. Might be indicative of an issue.
Vector2f MVel is the one actualy used, i just seperated it out into MVx/MVy for some weird reason



Quote
That assumption only makes sense if the acceleration is very high. That's what I've been trying to say all along
nope, if it it is still accelerating

it will either return Vector2f(0,0) (meaning it cant intercept, and should head straight for target)

or it will give the best intercept at its curent speed, the acceleration does not actualy matter "that" much (the real difrence between taking it into acount or not is less then 5 degrees)


@Xeno
Quote
There is a weighted function there; it's not sufficient to do the quadratic interception every frame.  Anyhow, that's a major derail; perhaps a new thread?
not sure what you mean

30
Suggestions / Re: why is it that in starsector Losing != FUN!
« on: May 08, 2014, 12:35:23 PM »
Moving derail on LeadVector to modding:
http://fractalsoftworks.com/forum/index.php?topic=7967.0

Pages: 1 [2] 3 4 ... 28