Skip to content

Commit

Permalink
Catch-up life support based on Kerbals' last meals instead of an upda…
Browse files Browse the repository at this point in the history
…te time on the vessel's parts
  • Loading branch information
nanathan committed Mar 1, 2016
1 parent a42efbe commit b7ea4e6
Showing 1 changed file with 44 additions and 42 deletions.
86 changes: 44 additions & 42 deletions Source/USILifeSupport/ModuleLifeSupport.cs
Expand Up @@ -35,7 +35,6 @@ private ConversionRecipe LifeSupportRecipe

protected IResourceBroker _resBroker;
protected ResourceConverter _resConverter;
protected double lastUpdateTime;

public ResourceConverter ResConverter
{
Expand All @@ -47,41 +46,36 @@ public IResourceBroker ResBroker
get { return _resBroker ?? (_resBroker = new ResourceBroker()); }
}

protected double GetDeltaTime()
protected void CalculateKerbalSupplySeconds(out double supplySeconds, out double mealTime)
{
if (Time.timeSinceLevelLoad < 1.0f || !FlightGlobals.ready)
double now = Planetarium.GetUniversalTime();
double previousMeal = now;

foreach(ProtoCrewMember m in part.protoModuleCrew)
{
return -1;
LifeSupportStatus status = LifeSupportManager.Instance.FetchKerbal(m);
previousMeal = Math.Min(previousMeal, status.LastMeal);
}

if (Math.Abs(lastUpdateTime) < ResourceUtilities.FLOAT_TOLERANCE)
supplySeconds = 0;

if(previousMeal >= now)
{
// Just started running
lastUpdateTime = Planetarium.GetUniversalTime();
return -1;
mealTime = now;
return;
}

double deltaTime = Math.Min(Planetarium.GetUniversalTime() - lastUpdateTime,
ResourceUtilities.GetMaxDeltaTime());
lastUpdateTime += deltaTime;
return deltaTime;
}

mealTime = Math.Min(now, previousMeal + ResourceUtilities.GetMaxDeltaTime());

public override void OnLoad(ConfigNode node)
{
base.OnLoad(node);
if (!HighLogic.LoadedSceneIsFlight)
return;
lastUpdateTime = ResourceUtilities.GetValue(node, "lastUpdateTime", lastUpdateTime);
}
foreach(ProtoCrewMember m in part.protoModuleCrew)
{
LifeSupportStatus status = LifeSupportManager.Instance.FetchKerbal(m);

public override void OnSave(ConfigNode node)
{
base.OnSave(node);
if (!HighLogic.LoadedSceneIsFlight)
return;
node.AddValue("lastUpdateTime", lastUpdateTime);
if(status.LastMeal < mealTime)
{
supplySeconds += mealTime - status.LastMeal;
}
}
}

public void FixedUpdate()
Expand All @@ -96,12 +90,14 @@ public void FixedUpdate()

UnlockTins();
//Check our time
double deltaTime = GetDeltaTime();
double supplySeconds;
double mealTime;
CalculateKerbalSupplySeconds(out supplySeconds, out mealTime);

if (deltaTime < ResourceUtilities.FLOAT_TOLERANCE)
if (supplySeconds < ResourceUtilities.FLOAT_TOLERANCE)
return;

ConverterResults result = ResConverter.ProcessRecipe(deltaTime, LifeSupportRecipe, part, this, 1f);
ConverterResults result = ResConverter.ProcessRecipe(supplySeconds, LifeSupportRecipe, part, this, 1f);

var v = LifeSupportManager.Instance.FetchVessel(part.vessel.id.ToString());
v.LastUpdate = Planetarium.GetUniversalTime();
Expand Down Expand Up @@ -152,8 +148,7 @@ public void FixedUpdate()
}

//we will add a bit of a fudge factor for supplies
var tolerance = deltaTime/2f;

var tolerance = supplySeconds / 2f;

foreach (var c in part.protoModuleCrew)
{
Expand All @@ -165,6 +160,14 @@ public void FixedUpdate()
var k = LifeSupportManager.Instance.FetchKerbal(c);
//Update our stuff

if (k.LastMeal >= mealTime)
{
// Other kerbals are being caught up, but this one is ahead.
// (possibly docking vessels, etc)
// Ignore this kerbal until others are caught up.
continue;
}

//First - Hab effects.
if (LifeSupportManager.IsOnKerbin(part.vessel))
{
Expand All @@ -184,22 +187,22 @@ public void FixedUpdate()
isGrouchyHab = CheckHabSideEffects(k, v);

//Second - Supply
if (!LifeSupportManager.IsOnKerbin(part.vessel) && (deltaTime - result.TimeFactor > tolerance))
if (!LifeSupportManager.IsOnKerbin(part.vessel) && (supplySeconds - result.TimeFactor > tolerance))
{
isGrouchySupplies = CheckSupplySideEffects(k);
}
else
{
//All is well
k.LastMeal = lastUpdateTime;
v.LastFeeding = lastUpdateTime;
k.LastMeal = Math.Max(k.LastMeal, mealTime);
v.LastFeeding = Math.Max(v.LastFeeding, mealTime);
}

k.LastUpdate = Planetarium.GetUniversalTime();
if (!isGrouchyHab && !isGrouchySupplies)
RemoveGrouchiness(c, k);

if (deltaTime < _checkInterval*2)
if (supplySeconds < _checkInterval * 2 * part.protoModuleCrew.Count)
{
if (isGrouchyHab)
{
Expand All @@ -217,7 +220,7 @@ public void FixedUpdate()
}
}
LifeSupportManager.Instance.TrackKerbal(k);
var supAmpunt = _resBroker.AmountAvailable(part, "Supplies", deltaTime, "ALL_VESSEL");
var supAmpunt = _resBroker.AmountAvailable(part, "Supplies", supplySeconds, "ALL_VESSEL");
v.SuppliesLeft = supAmpunt/LifeSupportSetup.Instance.LSConfig.SupplyAmount/
part.vessel.GetCrewCount()/
LifeSupportManager.GetRecyclerMultiplier(vessel);
Expand All @@ -231,21 +234,20 @@ private ConversionRecipe GenerateLSRecipe()
//This is where the rubber hits the road. Let us see if we can
//keep our Kerbals cozy and warm.
var recipe = new ConversionRecipe();
var numCrew = part.protoModuleCrew.Count;
var recPercent = LifeSupportManager.GetRecyclerMultiplier(part.vessel);
var ecAmount = LifeSupportSetup.Instance.LSConfig.ECAmount;
var supAmount = LifeSupportSetup.Instance.LSConfig.SupplyAmount;
var scrapAmount = LifeSupportSetup.Instance.LSConfig.WasteAmount;
var repAmount = LifeSupportSetup.Instance.LSConfig.ReplacementPartAmount;
if (part.Resources.Contains("ReplacementParts"))
{
recipe.Inputs.Add(new ResourceRatio { FlowMode = "ALL_VESSEL", Ratio = repAmount * numCrew, ResourceName = "ReplacementParts", DumpExcess = false });
recipe.Inputs.Add(new ResourceRatio { FlowMode = "ALL_VESSEL", Ratio = repAmount, ResourceName = "ReplacementParts", DumpExcess = false });
}

var supRatio = supAmount*numCrew*recPercent;
var mulchRatio = scrapAmount*numCrew*recPercent;
var supRatio = supAmount*recPercent;
var mulchRatio = scrapAmount*recPercent;

recipe.Inputs.Add(new ResourceRatio { FlowMode = "ALL_VESSEL", Ratio = ecAmount * numCrew, ResourceName = "ElectricCharge", DumpExcess = true });
recipe.Inputs.Add(new ResourceRatio { FlowMode = "ALL_VESSEL", Ratio = ecAmount, ResourceName = "ElectricCharge", DumpExcess = true });
recipe.Inputs.Add(new ResourceRatio { FlowMode = "ALL_VESSEL", Ratio = supRatio, ResourceName = "Supplies", DumpExcess = true });
recipe.Outputs.Add(new ResourceRatio { FlowMode = "ALL_VESSEL", Ratio = mulchRatio, ResourceName = "Mulch", DumpExcess = true });
return recipe;
Expand Down

0 comments on commit b7ea4e6

Please sign in to comment.