Esempio n. 1
0
 private SimpleEdge?CreateEdge(
     StarSystem from,
     StarSystem to,
     double fuel,
     SimpleJumpParameters parameters)
 {
     if (this.CanCompleteInSingleJump(from, to, fuel, parameters))
     {
         return(this.GetSingleJump(from, to, fuel, parameters));
     }
     else
     {
         return(this.GetMultiJump(from, to, fuel, parameters));
     }
 }
Esempio n. 2
0
        private SimpleEdge?GetMultiJump(
            StarSystem from,
            StarSystem to,
            double fuel,
            SimpleJumpParameters parameters)
        {
            // must be allowed
            if (parameters.JumpsMax < 2)
            {
                return(null);
            }

            // must scoop refuel
            if (parameters.RefuelType != RefuelType.Scoop && parameters.RefuelType != RefuelType.ScoopHeatsink)
            {
                return(null);
            }

            var distance = Vector3.Distance(from.Coordinates, to.Coordinates);

            var fstJumpRange  = this.shipHandler.GetJumpRange(fuel);
            var fstBoostType  = parameters.BoostType;
            var fstJumpFactor = this.GetJumpFactor(fstBoostType);
            var fstDistance   = parameters.MultiJumpRangeFactor * fstJumpFactor * fstJumpRange;

            // was a multi-jump with refuel but single without
            if (distance < fstDistance)
            {
                return(null);
            }

            var rstDistance   = distance - fstDistance;
            var rstJumpRange  = this.shipHandler.GetJumpRange(parameters.Refuel.Value);
            var rstJumpFactor = this.options.UseFsdBoost ? 2 : 1;
            var rstBoostType  = this.options.UseFsdBoost ? BoostType.Synthesis : BoostType.None;
            var rstJumps      = (int)Math.Ceiling(rstDistance / (parameters.MultiJumpRangeFactor * rstJumpFactor * rstJumpRange));

            var jumps = rstJumps + 1;

            if (jumps < parameters.JumpsMin || parameters.JumpsMax < jumps)
            {
                return(null);
            }

            double?timeFst;
            double?timeRst;
            double?timeRstRefuel;
            double fuelCostRst;

            if (jumps == 2 && this.options.UseRefuelStarFinder)
            {
                var refuel = this.refuelStarFinder.GetCandidate(from, fuel, to, parameters.Refuel.Value);

                if (refuel == null)
                {
                    return(null);
                }

                timeFst = this.jumpTime.Get(from, fstBoostType, RefuelType.None, null);
                var distFst     = Vector3.Distance(from.Coordinates, refuel.Coordinates);
                var fuelCostFst = this.shipHandler.GetFuelCost(fuel, distFst / fstJumpFactor);

                // must have enough fuel to make first jump
                if (fuel < fuelCostFst + this.minimumFuelLevel)
                {
                    return(null);
                }

                // must refuel to a higher fuel level
                if (parameters.Refuel.Value < (fuel - fuelCostFst))
                {
                    return(null);
                }

                timeRst = 0;

                timeRstRefuel = this.jumpTime.Get(refuel, rstBoostType, parameters.RefuelType, parameters.Refuel.Value - (fuel + fuelCostFst));
                var distRst = Vector3.Distance(refuel.Coordinates, to.Coordinates);
                fuelCostRst = this.shipHandler.GetFuelCost(parameters.Refuel.Value, distRst / rstJumpFactor);
            }
            else
            {
                // must have enough fuel to make first jump
                if (fuel < this.ship.FSD.MaxFuelPerJump + this.minimumFuelLevel)
                {
                    return(null);
                }

                // must refuel to a higher fuel level
                if (parameters.Refuel.Value < fuel)
                {
                    return(null);
                }

                timeFst       = this.jumpTime.Get(from, fstBoostType, RefuelType.None, null);
                timeRst       = this.jumpTime.Get(null, rstBoostType, RefuelType.None, null);
                timeRstRefuel = this.jumpTime.Get(null, rstBoostType, parameters.RefuelType, rstJumps * this.ship.FSD.MaxFuelPerJump + parameters.Refuel.Value - fuel);
                fuelCostRst   = this.ship.FSD.MaxFuelPerJump;
            }

            if (!timeFst.HasValue || !timeRst.HasValue || !timeRstRefuel.HasValue)
            {
                return(null);
            }

            var time = timeFst.Value + (rstJumps - 1) * timeRst.Value + timeRstRefuel.Value;

            fuel = Math.Max(0, parameters.Refuel.Value - fuelCostRst);

            return(new SimpleEdge
            {
                Distance = time,
                Fuel = fuel,
                Jumps = jumps
            });
        }
Esempio n. 3
0
        private SimpleEdge?GetSingleJump(
            StarSystem from,
            StarSystem to,
            double fuel,
            SimpleJumpParameters parameters)
        {
            if (1 < parameters.JumpsMin)
            {
                return(null);
            }

            double?time;

            if (parameters.RefuelType != RefuelType.None)
            {
                // cannot be start system
                if (from == this.start)
                {
                    return(null);
                }

                // must be above current fuel
                if (parameters.Refuel.Value < fuel)
                {
                    return(null);
                }

                switch (parameters.RefuelType)
                {
                case RefuelType.Scoop:
                case RefuelType.ScoopHeatsink:
                case RefuelType.ScoopReckless:
                {
                    // must have scoopable
                    if (!from.HasScoopable || 100 < from.DistanceToScoopable)
                    {
                        return(null);
                    }

                    break;
                }

                case RefuelType.Station:
                {
                    // must have station
                    if (!from.HasStation)
                    {
                        return(null);
                    }

                    break;
                }
                }

                time = this.jumpTime.Get(from, parameters.BoostType, parameters.RefuelType, parameters.Refuel.Value - fuel);

                fuel = parameters.Refuel.Value;
            }
            else
            {
                time = this.jumpTime.Get(from, parameters.BoostType, RefuelType.None, null);
            }

            if (!time.HasValue)
            {
                return(null);
            }

            var distance   = Vector3.Distance(from.Coordinates, to.Coordinates);
            var jumpFactor = this.GetJumpFactor(parameters.BoostType);

            fuel -= this.shipHandler.GetFuelCost(fuel, distance / jumpFactor);

            if (fuel < this.minimumFuelLevel)
            {
                return(null);
            }

            return(new SimpleEdge
            {
                Distance = time.Value,
                Fuel = fuel,
                Jumps = 1
            });
        }
Esempio n. 4
0
        private bool CanCompleteInSingleJump(StarSystem from, StarSystem to, double fuel, SimpleJumpParameters parameters)
        {
            var distance = Vector3.Distance(from.Coordinates, to.Coordinates);

            var jumpFactor = this.GetJumpFactor(parameters.BoostType);
            var jumpRange  = this.shipHandler.GetJumpRange(parameters.Refuel ?? fuel);

            return(distance < jumpFactor * jumpRange);
        }