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)); } }
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 }); }
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 }); }
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); }