Skip to content

Instantly share code, notes, and snippets.

@gotmachine
Created March 3, 2021 13:50
Show Gist options
  • Save gotmachine/9f173d77ee7c76dc6881c0de1588bc3b to your computer and use it in GitHub Desktop.
Save gotmachine/9f173d77ee7c76dc6881c0de1588bc3b to your computer and use it in GitHub Desktop.
Kerbalism ResourceBroker patch
// Experimental patch that force all BaseConverter derivatives to use the Kerbalism resource simulation, intended for NFE/FFT/SystemHeat support
// This will get ride of the "incoherent producer" message on loaded vessels, but there are some limitations :
// - This bypass resource flow priorities and modes, excepted in the case of a NO_FLOW resource.
// Specifically, NFE reactors should act correctly as far as uranium is concerned.
// - This use the last sim step information to attempt to compensate the stock high timewarp speeds issues,
// but since this works outside of the main kerbalism recipes loop, this will likely still act in weird ways
// when a mix of stock and kerbalism producers/consumers are active for the same resource.
// - This require renaming Kerbalism's own ResourceBroker class to something like KsmResourceBroker so harmony doesn't get confused
using System;
using Harmony;
namespace KERBALISM
{
[HarmonyPatch(typeof(ResourceBroker))]
[HarmonyPatch("AmountAvailable", new Type[] { typeof(Part), typeof(int), typeof(double), typeof(ResourceFlowMode) })]
class ResourceBroker_AmountAvailable
{
static bool Prefix()
{
return false;
}
static void Postfix(Part part, int resID, double deltaTime, ResourceFlowMode flowMode, ref double __result)
{
PartResourceDefinition resDef = PartResourceLibrary.Instance.GetDefinition(resID);
ResourceInfo resInfo = ResourceCache.GetResource(part.vessel, resDef.name);
if (flowMode == ResourceFlowMode.NULL)
{
flowMode = PartResourceLibrary.Instance.GetDefinition(resID).resourceFlowMode;
}
if (flowMode == ResourceFlowMode.NO_FLOW)
{
foreach (PartResource stockRes in part.Resources)
{
if (stockRes.flowState && stockRes.info.id == resID)
{
__result = stockRes.amount;
return;
}
}
}
// This is a very rough approximation, not sure exactely what will the consequences be
__result = Math.Max(resInfo.Amount + (resInfo.Rate * deltaTime), 0.0);
}
}
[HarmonyPatch(typeof(ResourceBroker))]
[HarmonyPatch("StorageAvailable", new[] { typeof(Part), typeof(int), typeof(double), typeof(ResourceFlowMode), typeof(double) })]
class ResourceBroker_StorageAvailable
{
static bool Prefix()
{
return false;
}
static void Postfix(Part part, int resID, double deltaTime, ResourceFlowMode flowMode, double FillAmount, ref double __result)
{
PartResourceDefinition resDef = PartResourceLibrary.Instance.GetDefinition(resID);
ResourceInfo resInfo = ResourceCache.GetResource(part.vessel, resDef.name);
if (flowMode == ResourceFlowMode.NULL)
{
flowMode = PartResourceLibrary.Instance.GetDefinition(resID).resourceFlowMode;
}
if (flowMode == ResourceFlowMode.NO_FLOW)
{
foreach (PartResource stockRes in part.Resources)
{
if (stockRes.flowState && stockRes.info.id == resID)
{
__result = stockRes.maxAmount - stockRes.amount;
return;
}
}
}
// This is a very rough approximation, not sure exactely what will the consequences be
__result = Math.Max(resInfo.Capacity - (resInfo.Amount + (resInfo.Rate * deltaTime)), 0.0);
}
}
[HarmonyPatch(typeof(ResourceBroker))]
[HarmonyPatch("RequestResource", new[] { typeof(Part), typeof(int), typeof(double), typeof(double), typeof(ResourceFlowMode) })]
class ResourceBroker_RequestResource
{
static bool Prefix()
{
return false;
}
static void Postfix(Part part, int resID, double resAmount, double deltaTime, ResourceFlowMode flowMode, ref double __result)
{
PartResourceDefinition resDef = PartResourceLibrary.Instance.GetDefinition(resID);
ResourceInfo resInfo = ResourceCache.GetResource(part.vessel, resDef.name);
if (flowMode == ResourceFlowMode.NULL)
{
flowMode = PartResourceLibrary.Instance.GetDefinition(resID).resourceFlowMode;
}
if (flowMode == ResourceFlowMode.NO_FLOW)
{
foreach (PartResource stockRes in part.Resources)
{
if (stockRes.flowState && stockRes.info.id == resID)
{
__result = Math.Max(stockRes.amount - resAmount, 0.0);
stockRes.amount -= __result;
resInfo.Amount = Math.Max(0.0, resInfo.Amount - __result);
return;
}
}
}
__result = Math.Min(resAmount, Math.Max(resInfo.Amount + (resInfo.Rate * deltaTime), 0.0));
resInfo.Consume(__result, KsmResourceBroker.GetOrCreate(part.partInfo.name, KsmResourceBroker.BrokerCategory.Converter, part.partInfo.title));
}
}
[HarmonyPatch(typeof(ResourceBroker))]
[HarmonyPatch("StoreResource", new[] { typeof(Part), typeof(int), typeof(double), typeof(double), typeof(ResourceFlowMode) })]
class ResourceBroker_StoreResource
{
static bool Prefix()
{
return false;
}
static void Postfix(Part part, int resID, double resAmount, double deltaTime, ResourceFlowMode flowMode, ref double __result)
{
PartResourceDefinition resDef = PartResourceLibrary.Instance.GetDefinition(resID);
ResourceInfo resInfo = ResourceCache.GetResource(part.vessel, resDef.name);
if (flowMode == ResourceFlowMode.NULL)
{
flowMode = PartResourceLibrary.Instance.GetDefinition(resID).resourceFlowMode;
}
if (flowMode == ResourceFlowMode.NO_FLOW)
{
foreach (PartResource stockRes in part.Resources)
{
if (stockRes.flowState && stockRes.info.id == resID)
{
__result = Math.Min(stockRes.maxAmount - stockRes.amount, resAmount);
stockRes.amount += __result;
resInfo.Amount += __result;
return;
}
}
}
__result = Math.Min(resAmount, Math.Max(resInfo.Capacity - (resInfo.Amount + (resInfo.Rate * deltaTime)), 0.0));
resInfo.Produce(__result, KsmResourceBroker.GetOrCreate(part.partInfo.name, KsmResourceBroker.BrokerCategory.Converter, part.partInfo.title));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment