-
Notifications
You must be signed in to change notification settings - Fork 27
BetterCargoPartVolume
This patch will generate a value for the ModuleCargoPart.packedVolume
field if it set to 0 or isn't defined in the module configuration. This works by getting the bounds of the part prefab active mesh renderers or colliders, after part compilation. Generated volumes are logged to ksp.log
the first time, and cached in the PluginData\BetterCargoPartVolume.cfg
file.
For parts that don't have a ModuleCargoPart.packedVolume
defined and have a ModulePartVariants
, a separate volume will be generated for every VARIANT
that use a GAMEOBJECTS
definition. Those separate volumes will be used when the part instance is put in an inventory.
The volume for a variant can be explicitly defined (preventing it from being auto-generated) by adding an EXTRA_INFO
sub-node to the VARIANT
node, and adding a packedVolume = x
value (x in liters) to that subnode. Example :
MODULE
{
name = ModuleCargoPart
// make sure packedVolume isn't defined or is 0
}
MODULE
{
name = ModulePartVariants
baseVariant = Short
VARIANT
{
name = Short
GAMEOBJECTS
{
Shroud1x0 = true
Shroud1x1 = false
}
EXTRA_INFO
{
packedVolume = 200
}
}
VARIANT
{
name = Long
GAMEOBJECTS
{
Shroud1x0 = false
Shroud1x1 = true
}
EXTRA_INFO
{
packedVolume = 400
}
}
}
The public or private instance method with the signature float CFAPI_CurrentCargoVolume()
implemented on a PartModule
derivative will be called prior to the Part
being stored in an inventory. This allow plugins that alter the shape of a part (ex : Tweakscale, B9PartSwitch...) to properly handle the volume of cargo parts. Example :
public class MyPartShapeChangingModule : PartModule
{
private ShapeDefinition currentShape;
// return a volume in liters, or -1 if you want to prevent
// the part from being storable in inventories (it will still
// be manipulable in EVA construction mode)
private float CFAPI_CurrentCargoVolume()
{
return currentShape.packedVolume;
}
}
Note that when that method is called, the part will be in an invalid state sue to how stock processes about-to-be-stored parts. So you must either :
- Use pre-configured values for each shape volume
- Generate volumes during prefab compilation, and save the values
- Rely on scaling formulas
To generate volumes, you can either roll your own implementation, but for consistency it is recommended that you call the BetterCargoPartVolume method. Example implementation :
public class MyPartShapeChangingModule : PartModule
{
// That field will be populated by KSPCommunityFixes, if its AutomaticCargoPartVolume patch is enabled
private static Func<Part, float> CFAPI_GetPackedVolumeForPart;
public override void OnLoad(ConfigNode node)
{
// Execute only during prefab (re)compilation
if (CFAPI_GetPackedVolumeForPart != null && (HighLogic.LoadedScene == GameScenes.LOADING || PartLoader.Instance.Recompile))
{
foreach (ShapeDefinition shape in shapes)
{
// Setup the part transforms/meshes/scale according to your module logic
shape.Activate();
// Call the volume-getting method on the part prefab
shape.packedVolume = CFAPI_GetPackedVolumeForPart(part);
// If the method fails to compute a valid volume, it will return -1f.
// You can use that value safely, this will prevent the part from being stored
// in an inventory, and it will still be manipulable in EVA construction mode
if (shape.packedVolume <= 0f)
{
Debug.LogWarning($"Couldn't generate cargo volume for shape {shape.name}");
}
}
}
}
}
- The patch override the stock implementation of
ModuleInventoryPart.UpdateCapacityValues
to rely on the stored partProtoPartSnapshot
for mass and volume, instead of using the part prefab mass/volume :- This is necessary to handle
packedVolume
switching on instances. For that to work, the patch force theModuleCargoPart.packedVolume
KSPField to be persisted. - This fixes tons of issues where the part instance mass doesn't match the part prefab mass (modified resources, modules implementing IPartMassModifier...)
- This is necessary to handle
- The patch override the stock implementation of
ModuleCargoPart.GetInfo()
, showingpacked volume: variable
instead of a value when the part use a module implementing volume switching. - The patch remove the ability to switch variants from the cargo part icon when the part is stored in an inventory and make use of volume switching
- The volume cache in
PluginData\BetterCargoPartVolume.cfg
will be invalidated and rebuilt when a config change is detected by ModuleManager