Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change pad reconditioning to be independent from other LC operations #2391

Merged
merged 1 commit into from
Jul 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions Source/RP0/SpaceCenter/LaunchComplex/LaunchComplex.cs
Original file line number Diff line number Diff line change
Expand Up @@ -211,12 +211,13 @@ public int LaunchPadCount

public bool IsEmpty => LCType == LaunchComplexType.Hangar && BuildList.Count == 0 && Warehouse.Count == 0 && Engineers == 0 && LCData.StartingHangar.Compare(this);

public bool IsActive => BuildList.Count > 0 || GetAllLCOps().Any(op => !op.IsComplete());
public bool CanDismantle => BuildList.Count == 0 && Warehouse.Count == 0 &&
!Recon_Rollout.Any(r => r.RRType != ReconRolloutProject.RolloutReconType.Reconditioning) &&
VesselRepairs.Count == 0;
public bool CanModifyButton => BuildList.Count == 0 && Warehouse.Count == 0 && Recon_Rollout.Count == 0 && VesselRepairs.Count == 0;
public bool CanModifyReal => Recon_Rollout.Count == 0 && VesselRepairs.Count == 0;
public bool IsActive => BuildList.Count > 0 || GetAllLCOps().Any(op => !op.IsComplete() && op.KeepsLCActive);
public bool CanDismantle => CanModifyButton;
public bool CanModifyButton => BuildList.Count == 0 && Warehouse.Count == 0 &&
!Recon_Rollout.Any(r => r.RRType != ReconRolloutProject.RolloutReconType.Reconditioning) &&
VesselRepairs.Count == 0;
public bool CanModifyReal => !Recon_Rollout.Any(r => r.RRType != ReconRolloutProject.RolloutReconType.Reconditioning) &&
VesselRepairs.Count == 0;
public bool CanIntegrate => ProjectBPTotal == 0d;

private double _projectBPTotal = -1d;
Expand Down
5 changes: 3 additions & 2 deletions Source/RP0/SpaceCenter/Projects/LCOpsProject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public abstract class LCOpsProject : ConfigNodePersistenceBase, ISpaceCenterProj

public abstract TransactionReasonsRP0 TransactionReason { get; }
protected abstract TransactionReasonsRP0 transactionReasonTime { get; }
public abstract bool KeepsLCActive { get; }

public VesselProject AssociatedVP => KCTUtilities.FindVPByID(LC, AssociatedIdAsGuid);

Expand Down Expand Up @@ -96,7 +97,7 @@ protected double GetBaseBuildRate()
return _buildRate;
}

protected double CalculateBuildRate(int delta)
protected virtual double CalculateBuildRate(int delta)
{
double rate;
if (IsCapped)
Expand Down Expand Up @@ -150,7 +151,7 @@ public double GetTimeLeft()

private double TimeLeftWithEfficiencyIncrease(double timeLeft)
{
if (LC.Efficiency == LCEfficiency.MaxEfficiency || timeLeft < 86400d)
if (LC.Efficiency == LCEfficiency.MaxEfficiency || timeLeft < 86400d || LC.Engineers == 0)
return timeLeft;

double bpDivRate = timeLeft * LC.Efficiency;
Expand Down
21 changes: 19 additions & 2 deletions Source/RP0/SpaceCenter/Projects/ReconRolloutProject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ public ReconRolloutProject(Vessel vessel, RolloutReconType type, string id, stri
var vp = new VesselProject(vessel, ProjectType.VAB);
isHumanRated = vp.humanRated;
BP = Formula.GetReconditioningBP(vp);
cost = Formula.GetReconditioningCost(vp);
vesselBP = vp.buildPoints;
}
catch
Expand Down Expand Up @@ -126,6 +127,7 @@ public ReconRolloutProject(VesselProject vessel, RolloutReconType type, string i
{
case RolloutReconType.Reconditioning:
BP = Formula.GetReconditioningBP(vessel);
cost = Formula.GetReconditioningCost(vessel);
break;

case RolloutReconType.Rollout:
Expand Down Expand Up @@ -174,7 +176,10 @@ public void SwitchDirection()

public override bool IsReversed => RRType == RolloutReconType.Rollback || RRType == RolloutReconType.AirlaunchUnmount;

public override bool HasCost => RRType == RolloutReconType.Rollout || RRType == RolloutReconType.AirlaunchMount;
public override bool HasCost => RRType == RolloutReconType.Rollout || RRType == RolloutReconType.AirlaunchMount ||
RRType == RolloutReconType.Reconditioning;

public override bool KeepsLCActive => RRType != RolloutReconType.Reconditioning;

public override ProjectType GetProjectType()
{
Expand All @@ -183,7 +188,6 @@ public override ProjectType GetProjectType()
case RolloutReconType.AirlaunchMount:
case RolloutReconType.AirlaunchUnmount:
return ProjectType.AirLaunch;

default:
return ProjectType.Reconditioning;
}
Expand All @@ -193,6 +197,19 @@ public override void Load(ConfigNode node)
{
base.Load(node);
}

protected override double CalculateBuildRate(int delta)
{
if (RRType == RolloutReconType.Reconditioning)
{
bool isHRCapped = IsCapped && !isHumanRated && LC.IsHumanRated;
return Formula.GetReconditioningBuildRate(LC, isHRCapped);
}
else
{
return base.CalculateBuildRate(delta);
}
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions Source/RP0/SpaceCenter/Projects/VesselRepairProject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ public class VesselRepairProject : LCOpsProject

protected override TransactionReasonsRP0 transactionReasonTime => TransactionReasonsRP0.RateRollout;

public override bool KeepsLCActive => false;

public override ProjectType GetProjectType() => ProjectType.VesselRepair;

public VesselRepairProject() : base()
Expand Down
157 changes: 85 additions & 72 deletions Source/RP0/SpaceCenter/SpaceCenterManagement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public class SpaceCenterManagement : ScenarioModule

public static bool EditorShipEditingMode = false;
public static double EditorRolloutCost = 0;
public static double EditorReconditionCost = 0;
public static double EditorRolloutBP = 0;
public static double EditorUnlockCosts = 0;
public static double EditorToolingCosts = 0;
Expand Down Expand Up @@ -1001,7 +1002,7 @@ public double GetBudgetDelta(double deltaTime)

double averageSubsidyPerDay = CurrencyUtils.Funds(TransactionReasonsRP0.Subsidy, MaintenanceHandler.GetAverageSubsidyForPeriod(deltaTime)) * (1d / 365.25d);
double fundDelta = Math.Min(0d, MaintenanceHandler.Instance.UpkeepPerDayForDisplay + averageSubsidyPerDay) * deltaTime * (1d / 86400d)
+ GetConstructionCostOverTime(deltaTime) + GetRolloutCostOverTime(deltaTime)
+ GetConstructionCostOverTime(deltaTime) + GetReconRolloutCostOverTime(deltaTime)
+ Programs.ProgramHandler.Instance.GetDisplayProgramFunding(deltaTime);

return fundDelta;
Expand Down Expand Up @@ -1039,51 +1040,53 @@ public double GetConstructionCostOverTime(double time, string kscName)
return 0d;
}

public double GetRolloutCostOverTime(double time)
public double GetReconRolloutCostOverTime(double time)
{
double delta = 0;
foreach (var ksc in KSCs)
{
delta += GetRolloutCostOverTime(time, ksc);
delta += GetReconRolloutCostOverTime(time, ksc);
}
return delta;
}

public double GetRolloutCostOverTime(double time, LCSpaceCenter ksc)
public double GetReconRolloutCostOverTime(double time, LCSpaceCenter ksc)
{
double delta = 0;
for (int i = 0; i < ksc.LaunchComplexes.Count; ++i)
delta += GetRolloutCostOverTime(time, ksc.LaunchComplexes[i]);
delta += GetReconRolloutCostOverTime(time, ksc.LaunchComplexes[i]);

return delta;
}

public double GetRolloutCostOverTime(double time, LaunchComplex lc)
public double GetReconRolloutCostOverTime(double time, LaunchComplex lc)
{
double delta = 0;
foreach (var rr in lc.Recon_Rollout)
{
if (rr.RRType != ReconRolloutProject.RolloutReconType.Rollout && rr.RRType != ReconRolloutProject.RolloutReconType.AirlaunchMount)
continue;

double t = rr.GetTimeLeft();
double fac = 1d;
if (t > time)
fac = time / t;
if (rr.RRType == ReconRolloutProject.RolloutReconType.Rollout ||
rr.RRType == ReconRolloutProject.RolloutReconType.Reconditioning ||
rr.RRType == ReconRolloutProject.RolloutReconType.AirlaunchMount)
{
double t = rr.GetTimeLeft();
double fac = 1d;
if (t > time)
fac = time / t;

delta += CurrencyUtils.Funds(rr.TransactionReason, -rr.cost * (1d - rr.progress / rr.BP) * fac);
delta += CurrencyUtils.Funds(rr.TransactionReason, -rr.cost * (1d - rr.progress / rr.BP) * fac);
}
}

return delta;
}

public double GetRolloutCostOverTime(double time, string kscName)
public double GetReconRolloutCostOverTime(double time, string kscName)
{
foreach (var ksc in KSCs)
{
if (ksc.KSCName == kscName)
{
return GetRolloutCostOverTime(time, ksc);
return GetReconRolloutCostOverTime(time, ksc);
}
}

Expand Down Expand Up @@ -1512,6 +1515,7 @@ private void RecalculateEditorBuildTime(ShipConstruct ship)
if (EditorDriver.editorFacility == EditorFacility.VAB)
{
EditorRolloutCost = Formula.GetRolloutCost(EditorVessel);
EditorReconditionCost = Formula.GetReconditioningCost(EditorVessel);
EditorRolloutBP = Formula.GetRolloutBP(EditorVessel);
}
else
Expand Down Expand Up @@ -1607,68 +1611,13 @@ public void ProgressBuildTime(double UTDiff)
remainingUT = UTDiff - passes * 86400d;
++passes;
}
int rushingEngs = 0;

int totalEngineers = 0;
foreach (LCSpaceCenter ksc in KSCs)
{
totalEngineers += ksc.Engineers;

for (int j = ksc.LaunchComplexes.Count - 1; j >= 0; j--)
{
LaunchComplex currentLC = ksc.LaunchComplexes[j];
if (!currentLC.IsOperational || currentLC.Engineers == 0 || !currentLC.IsActive)
continue;

double portionEngineers = currentLC.Engineers / (double)currentLC.MaxEngineers;

if (currentLC.IsRushing)
rushingEngs += currentLC.Engineers;
else
{
for (int p = 0; p < passes; ++p)
{
double timestep = p == 0 ? remainingUT : 86400d;
currentLC.EfficiencySource?.IncreaseEfficiency(timestep, portionEngineers);
}
}

double timeForBuild = UTDiff;
while (timeForBuild > 0d && currentLC.BuildList.Count > 0)
{
timeForBuild = currentLC.BuildList[0].IncrementProgress(UTDiff);
}

for (int i = currentLC.Recon_Rollout.Count; i-- > 0;)
{
// These work in parallel so no need to track excess time
// FIXME: that's not _quite_ true, but it's close enough: when one
// completes, the others speed up, but that's hard to deal with here
// so I think we just eat the cost.
var rr = currentLC.Recon_Rollout[i];
rr.IncrementProgress(UTDiff);
//Reset the associated launchpad id when rollback completes
Profiler.BeginSample("RP0ProgressBuildTime.ReconRollout.FindVPesselByID");
if (rr.RRType == ReconRolloutProject.RolloutReconType.Rollback && rr.IsComplete()
&& KCTUtilities.FindVPByID(rr.LC, rr.AssociatedIdAsGuid) is VesselProject vp)
{
vp.launchSiteIndex = -1;
}
Profiler.EndSample();
}

for (int i = currentLC.VesselRepairs.Count; i-- > 0;)
{
var vr = currentLC.VesselRepairs[i];
vr.IncrementProgress(UTDiff);
if (vr.IsComplete() && HighLogic.LoadedSceneIsFlight &&
vr.ApplyRepairs())
{
currentLC.VesselRepairs.Remove(vr);
}
}

currentLC.Recon_Rollout.RemoveAll(rr => rr.RRType != ReconRolloutProject.RolloutReconType.Rollout && rr.RRType != ReconRolloutProject.RolloutReconType.AirlaunchMount && rr.IsComplete());
ProgressLCBuildTime(currentLC, UTDiff, remainingUT, passes);
}

for (int i = ksc.Constructions.Count; i-- > 0;)
Expand Down Expand Up @@ -1705,6 +1654,70 @@ public void ProgressBuildTime(double UTDiff)
Profiler.EndSample();
}

private static void ProgressLCBuildTime(LaunchComplex currentLC, double UTDiff, double remainingUT, int passes)
{
if (currentLC.IsOperational && currentLC.Engineers > 0 && currentLC.IsActive)
{
double portionEngineers = currentLC.Engineers / (double)currentLC.MaxEngineers;

if (!currentLC.IsRushing)
{
for (int p = 0; p < passes; ++p)
{
double timestep = p == 0 ? remainingUT : 86400d;
currentLC.EfficiencySource?.IncreaseEfficiency(timestep, portionEngineers);
}
}

double timeForBuild = UTDiff;
while (timeForBuild > 0d && currentLC.BuildList.Count > 0)
{
timeForBuild = currentLC.BuildList[0].IncrementProgress(UTDiff);
}

for (int i = currentLC.Recon_Rollout.Count; i-- > 0;)
{
// These work in parallel so no need to track excess time
// FIXME: that's not _quite_ true, but it's close enough: when one
// completes, the others speed up, but that's hard to deal with here
// so I think we just eat the cost.
var rr = currentLC.Recon_Rollout[i];
rr.IncrementProgress(UTDiff);
//Reset the associated launchpad id when rollback completes
Profiler.BeginSample("RP0ProgressBuildTime.ReconRollout.FindVPesselByID");
if (rr.RRType == ReconRolloutProject.RolloutReconType.Rollback && rr.IsComplete()
&& KCTUtilities.FindVPByID(rr.LC, rr.AssociatedIdAsGuid) is VesselProject vp)
{
vp.launchSiteIndex = -1;
}
Profiler.EndSample();
}

for (int i = currentLC.VesselRepairs.Count; i-- > 0;)
{
var vr = currentLC.VesselRepairs[i];
vr.IncrementProgress(UTDiff);
if (vr.IsComplete() && HighLogic.LoadedSceneIsFlight &&
vr.ApplyRepairs())
{
currentLC.VesselRepairs.Remove(vr);
}
}
}
else
{
// Process reconditioning even for LCs that have no engineers or are inactive
for (int i = currentLC.Recon_Rollout.Count; i-- > 0;)
{
var rr = currentLC.Recon_Rollout[i];
if (rr.RRType == ReconRolloutProject.RolloutReconType.Reconditioning)
rr.IncrementProgress(UTDiff);
}
}

currentLC.Recon_Rollout.RemoveAll(rr => rr.RRType != ReconRolloutProject.RolloutReconType.Rollout && rr.RRType != ReconRolloutProject.RolloutReconType.AirlaunchMount && rr.IsComplete());
}

#endregion

#region Recovery
Expand Down
6 changes: 5 additions & 1 deletion Source/RP0/UI/KCT/GUI_Editor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,11 @@ private static void RenderBuildMode()
}

if (SpaceCenterManagement.EditorRolloutCost > 0)
GUILayout.Label($"Rollout Cost: √{-CurrencyUtils.Funds(TransactionReasonsRP0.RocketRollout, -SpaceCenterManagement.EditorRolloutCost):N1}");
{
double rolloutCost = -CurrencyUtils.Funds(TransactionReasonsRP0.RocketRollout, -SpaceCenterManagement.EditorRolloutCost);
double recondCost = -CurrencyUtils.Funds(TransactionReasonsRP0.RocketRollout, -SpaceCenterManagement.EditorReconditionCost);
GUILayout.Label(new GUIContent($"Launch Cost: √{rolloutCost:N1} + √{recondCost:N1}", "Launch costs consist of rollout + pad reconditioning"));
}

bool showCredit = false;
if (SpaceCenterManagement.EditorUnlockCosts > 0)
Expand Down
2 changes: 1 addition & 1 deletion Source/RP0/UI/KCT/GUI_NewLC.cs
Original file line number Diff line number Diff line change
Expand Up @@ -816,7 +816,7 @@ private static bool ValidateLCCreationParameters(LCData newLCData, LaunchComplex

if (existingLC != null && !existingLC.CanModifyReal)
{
ScreenMessages.PostScreenMessage("Please wait for any reconditioning, rollout, rollback, or recovery to complete");
ScreenMessages.PostScreenMessage("Please wait for any rollout, rollback, or recovery to complete");
RP0Debug.Log($"Can't modify LC, recon_rollout in progress");
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion Source/RP0/UI/MaintenanceGUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ public void RenderSummaryTab()
double rolloutCost = 0d;
try
{
rolloutCost = SpaceCenterManagement.Instance.GetRolloutCostOverTime(PeriodFactor * 86400d);
rolloutCost = SpaceCenterManagement.Instance.GetReconRolloutCostOverTime(PeriodFactor * 86400d);
GUILayout.Label("Rollout/Airlaunch Prep", HighLogic.Skin.label, GUILayout.Width(160));
GUILayout.Label(FormatCost(rolloutCost), RightLabel, GUILayout.Width(160));
}
Expand Down
Loading
Loading