Jump to content

GENTLEMEN, BEHOLD! Never have to distribute a modified part.cfg again!


ialdabaoth

Recommended Posts

So, let's say you want to install IonCross's Life Support System plugin.

And then you want to install FAR's accurate aerodynamics plugin.

And then you want to install my wonderful Modular Fuel Tanks plugin.

But then you realize: each of these mods requires you to replace your part.cfg files. If you want to install both, you're going to have to go into your part.cfg files, figure out what each mod needs you to change, and then write your own modified version.

This is tedious and error-prone, and no for the faint of heart.

BUT NOT ANYMORE!

Now, IonCross and FAR, and anyone else who distributes modified versions of stock parts, can simply distribute ModuleManager with their own plugin, and ModuleManager will do the work for you.

How it works:

There's a file that sits in your PluginData directory, called PluginData/ModuleManager/parts.cfg

This file looks something like this:


include = ModularFuelTanks.cfg
include = FAR.cfg
include = IonCrossLSS.cfg

Then you see that each of those files also exists within PluginData/ModuleManager/; for example, ModularFuelTanks.cfg looks something like this:


include = KW_modularFuelTanks.cfg
include = BAC9_modularFuelTanks.cfg
include = BobCat_modularFuelTanks.cfg

fuelTank
{
REPLACE
{
RESOURCE
{
name = LiquidFuel
amount = 160
maxAmount = 160
}

RESOURCE
{
name = Oxidizer
amount = 240
maxAmount = 240
}
}

ADD
{
MODULE
{
name = ModuleFuelTanks
volume = 400
basemass = 0.125
TANK
{
name = LiquidH2
efficiency = 0.975
mass = 0.000
temperature = -253
loss_rate = 0.0000000005
}
TANK
{
name = LiquidOxygen
efficiency = 0.995
mass = 0.0003125
temperature = -183
loss_rate = 0.0000000001
}
TANK
{
name = LiquidFuel
efficiency = 1.0
mass = 0.0003125
}
TANK
{
name = Oxidizer
efficiency = 1.0
mass = 0.0003125
}
TANK
{
name = MonoPropellant
efficiency = 1.0
mass = 0.0005
}
}
}
}

fuelTank_long
{
REPLACE
{
RESOURCE
{
name = LiquidFuel
amount = 320
maxAmount = 320
}

RESOURCE
{
name = Oxidizer
amount = 480
maxAmount = 480
}
}

ADD
{
MODULE
{
name = ModuleFuelTanks
volume = 800
basemass = 0.25
TANK
{
name = LiquidH2
efficiency = 0.975
mass = 0.000
temperature = -253
loss_rate = 0.0000000005
}
TANK
{
name = LiquidOxygen
efficiency = 0.995
mass = 0.0003125
temperature = -183
loss_rate = 0.0000000001
}
TANK
{
name = LiquidFuel
efficiency = 1.0
mass = 0.0003125
}
TANK
{
name = Oxidizer
efficiency = 1.0
mass = 0.0003125
}
TANK
{
name = MonoPropellant
efficiency = 1.0
mass = 0.0005
}
}
}
}

fuelTank1-2
{
REPLACE
{
RESOURCE
{
name = LiquidFuel
amount = 1440
maxAmount = 1440
}

RESOURCE
{
name = Oxidizer
amount = 1760
maxAmount = 1760
}
}

ADD
{
MODULE
{
name = ModuleFuelTanks
volume = 3200
basemass = 1
TANK
{
name = LiquidH2
loss_rate = 0.000015
efficiency = 0.975
mass = 0.000
}
TANK
{
name = LiquidOxygen
efficiency = 0.995
mass = 0.0003125
}
TANK
{
name = LiquidFuel
efficiency = 1.0
mass = 0.0003125
}
TANK
{
name = Oxidizer
efficiency = 1.0
mass = 0.0003125
}
TANK
{
name = MonoPropellant
efficiency = 1.0
mass = 0.0005
}
}
}
}

fuelTank2-2
{
REPLACE
{
RESOURCE
{
name = LiquidFuel
amount = 640
maxAmount = 640
}

RESOURCE
{
name = Oxidizer
amount = 960
maxAmount = 960
}

}
ADD
{
MODULE
{
name = ModuleFuelTanks
volume = 1600
basemass = 0.5
TANK
{
name = LiquidH2
efficiency = 0.975
temperature = -253
loss_rate = 0.0000000005
mass = 0.000
}
TANK
{
name = LiquidOxygen
efficiency = 0.995
temperature = -183
loss_rate = 0.0000000001
mass = 0.0003125
}
TANK
{
name = LiquidFuel
efficiency = 1.0
temperature = 150
mass = 0.0003125
}
TANK
{
name = Oxidizer
efficiency = 1.0
mass = 0.0003125
}
TANK
{
name = MonoPropellant
efficiency = 1.0
mass = 0.0005
}
}
}
}

fuelTank3-2
{
REMOVE
{
RESOURCE=LiquidFuel
RESOURCE=Oxidizer
}
ADD
{

RESOURCE
{
name = LiquidH2
amount = 4637
maxAmount = 4637
}

RESOURCE
{
name = LiquidOxygen
amount = 1716
maxAmount = 1716
}

MODULE
{
name = ModuleFuelTanks
volume = 6400
basemass = 2
TANK
{
name = LiquidH2
efficiency = 0.995
mass = 0.0000
temperature = -253
loss_rate = 0.0000000005
}
TANK
{
name = LiquidOxygen
efficiency = 1.0
mass = 0.0003125
temperature = -183
loss_rate = 0.0000000001
}
TANK
{
name = LiquidFuel
efficiency = 1.0
mass = 0.0003125
}
}
}
}

fuelTank4-2
{
REPLACE
{

RESOURCE
{
name = LiquidFuel
amount = 320
maxAmount = 320
}

RESOURCE
{
name = Oxidizer
amount = 480
maxAmount = 480
}
}
ADD
{
MODULE
{
name = ModuleFuelTanks
volume = 800
basemass = 0.25
TANK
{
name = LiquidH2
efficiency = 0.975
mass = 0.000
temperature = -253
loss_rate = 0.0000000005
}
TANK
{
name = LiquidOxygen
efficiency = 0.995
mass = 0.0003125
temperature = -183
loss_rate = 0.0000000001
}
TANK
{
name = LiquidFuel
efficiency = 1.0
mass = 0.0003125
}
TANK
{
name = Oxidizer
efficiency = 1.0
mass = 0.0003125
}
TANK
{
name = MonoPropellant
efficiency = 1.0
mass = 0.0005
}
}
}
}

fuelTankSmall
{
ADD
{
MODULE
{
name = ModuleFuelTanks
volume = 200
basemass = 0.0625
TANK
{
name = LiquidH2
efficiency = 0.975
mass = 0.000
temperature = -253
loss_rate = 0.0000000005
}
TANK
{
name = LiquidOxygen
efficiency = 0.995
mass = 0.0003125
temperature = -183
loss_rate = 0.0000000001
}
TANK
{
name = LiquidFuel
efficiency = 1.0
mass = 0.0003125
}
TANK
{
name = Oxidizer
efficiency = 1.0
mass = 0.0003125
}
TANK
{
name = MonoPropellant
efficiency = 1.0
mass = 0.0005
}
}
}
REPLACE
{
RESOURCE
{
name = LiquidFuel
amount = 80
maxAmount = 80
}

RESOURCE
{
name = Oxidizer
amount = 120
maxAmount = 120
}
}
}

launchClamp1
{
ADD
{
MODULE
{
name = RefuelingLaunchClamp
pump_rate = 100.0;

trf_towerPivot_name = obj_girdercap
trf_towerStretch_name = obj_girder
trf_anchor_name = obj_ground

trf_animationRoot_name = launchclamp
anim_decouple_name = launchclamp
}
}
}

liquidEngine
{
REPLACE
{
MODULE
{
name = ModuleEngines
thrustVectorTransformName = thrustTransform
exhaustDamage = True
ignitionThreshold = 0.1
minThrust = 0
maxThrust = 215
heatProduction = 400
fxOffset = 0, 0, 0.8
PROPELLANT
{
name = LiquidFuel
ratio = 0.4
DrawGauge = True
}
PROPELLANT
{
name = Oxidizer
ratio = 0.6
}
atmosphereCurve
{
key = 0 370
key = 1 320
}
}
}
}

LiquidEngine1-2
{
REPLACE
{
MODULE
{
name = ModuleEngines
thrustVectorTransformName = thrustTransform
exhaustDamage = True
ignitionThreshold = 0.1
minThrust = 0
maxThrust = 1500
heatProduction = 500
fxOffset = 0, 0, 1.5
PROPELLANT
{
name = LiquidFuel
ratio = 0.35
DrawGauge = True
}
PROPELLANT
{
name = LiquidOxygen
ratio = 0.65
}
atmosphereCurve
{
key = 0 330
key = 1 280
}
}
}
}

liquidEngine2
{
ADD
{
MODULE
{
name = ModuleEngineConfigs
configuration = LiquidFuel+Oxidizer (200 Thrust, 370 Isp)
modded = false
CONFIG
{
name = LiquidFuel+Oxidizer (200 Thrust, 370 Isp)
thrustVectorTransformName = thrustTransform
exhaustDamage = True
ignitionThreshold = 0.1
minThrust = 0
maxThrust = 200
heatProduction = 400
fxOffset = 0, 0, 0.4
PROPELLANT
{
name = LiquidFuel
ratio = 0.4
DrawGauge = True
}
PROPELLANT
{
name = Oxidizer
ratio = 0.6
}
atmosphereCurve
{
key = 0 370
key = 1 320
}

}

CONFIG
{
name = LiquidFuel+LiquidOxygen (210 Thrust, 390 Isp)
thrustVectorTransformName = thrustTransform
exhaustDamage = True
ignitionThreshold = 0.1
minThrust = 0
maxThrust = 210
heatProduction = 375
fxOffset = 0, 0, 0.4
PROPELLANT
{
name = LiquidFuel
ratio = 0.35
DrawGauge = True
}
PROPELLANT
{
name = LiquidOxygen
ratio = 0.65
}
atmosphereCurve
{
key = 0 390
key = 1 330
}

}

CONFIG
{
name = LiquidH2+LiquidOxygen (175 Thrust, 460 Isp)
thrustVectorTransformName = thrustTransform
exhaustDamage = True
ignitionThreshold = 0.1
minThrust = 0
maxThrust = 175
heatProduction = 350
fxOffset = 0, 0, 0.4
PROPELLANT
{
name = LiquidH2
ratio = 0.73
DrawGauge = True
}
PROPELLANT
{
name = LiquidOxygen
ratio = 0.27
}
atmosphereCurve
{
key = 0 460
key = 1 340
}

}
}
}
REPLACE
{
MODULE
{
name = ModuleEngines
thrustVectorTransformName = thrustTransform
exhaustDamage = True
ignitionThreshold = 0.1
minThrust = 0
maxThrust = 200
heatProduction = 400
fxOffset = 0, 0, 0.574338
PROPELLANT
{
name = LiquidFuel
ratio = 0.4
DrawGauge = True
}
PROPELLANT
{
name = Oxidizer
ratio = 0.6
}
atmosphereCurve
{
key = 0 370
key = 1 320
}
}
}
}

liquidEngine2-2
{
ADD
{
MODULE
{
name = ModuleEngineConfigs
configuration = LiquidH2+LiquidOxygen (220 Thrust, 460 Isp)
modded = false
CONFIG
{
name = LiquidFuel+Oxidizer (250 Thrust, 370 Isp)
thrustVectorTransformName = thrustTransform
exhaustDamage = True
ignitionThreshold = 0.1
minThrust = 0
maxThrust = 250
heatProduction = 350
fxOffset = 0, 0, 0.4
PROPELLANT
{
name = LiquidFuel
ratio = 0.4
DrawGauge = True
}
PROPELLANT
{
name = Oxidizer
ratio = 0.6
}
atmosphereCurve
{
key = 0 370
key = 1 270
}

}

CONFIG
{
name = LiquidFuel+LiquidOxygen (255 Thrust, 390 Isp)
thrustVectorTransformName = thrustTransform
exhaustDamage = True
ignitionThreshold = 0.1
minThrust = 0
maxThrust = 55
heatProduction = 325
fxOffset = 0, 0, 0.4
PROPELLANT
{
name = LiquidFuel
ratio = 0.35
DrawGauge = True
}
PROPELLANT
{
name = LiquidOxygen
ratio = 0.65
}
atmosphereCurve
{
key = 0 390
key = 1 300
}

}

CONFIG
{
name = LiquidH2+LiquidOxygen (220 Thrust, 460 Isp)
thrustVectorTransformName = thrustTransform
exhaustDamage = True
ignitionThreshold = 0.1
minThrust = 0
maxThrust = 300
heatProduction = 290
fxOffset = 0, 0, 0.4
PROPELLANT
{
name = LiquidH2
ratio = 0.73
DrawGauge = True
}
PROPELLANT
{
name = LiquidOxygen
ratio = 0.27
}
atmosphereCurve
{
key = 0 460
key = 1 310
}

}
}
}
REPLACE
{

MODULE
{
name = ModuleEngines
thrustVectorTransformName = thrustTransform
exhaustDamage = True
ignitionThreshold = 0.1
minThrust = 0
maxThrust = 220
heatProduction = 290
fxOffset = 0, 0, 0.4
PROPELLANT
{
name = LiquidH2
ratio = 0.73
DrawGauge = True
}
PROPELLANT
{
name = LiquidOxygen
ratio = 0.27
}
atmosphereCurve
{
key = 0 450
key = 1 270
}
}
}
}

liquidEngine3
{
REPLACE
{
MODULE
{
name = ModuleEngines
thrustVectorTransformName = thrustTransform
exhaustDamage = True
ignitionThreshold = 0.1
minThrust = 0
maxThrust = 50
heatProduction = 300
fxOffset = 0, 0, 0.21
PROPELLANT
{
name = LiquidH2
ratio = 0.73
DrawGauge = True
}
PROPELLANT
{
name = LiquidOxygen
ratio = 0.27
}
atmosphereCurve
{
key = 0 460
key = 1 300
}
}
}
ADD
{
MODULE
{
name = ModuleEngineConfigs
configuration = LiquidFuel+Oxidizer (50 Thrust, 370 Isp)
modded = false
CONFIG
{
name = LiquidFuel+Oxidizer (50 Thrust, 370 Isp)
thrustVectorTransformName = thrustTransform
exhaustDamage = True
ignitionThreshold = 0.1
minThrust = 0
maxThrust = 50
heatProduction = 300
fxOffset = 0, 0, 0.21
PROPELLANT
{
name = LiquidFuel
ratio = 0.4
DrawGauge = True
}
PROPELLANT
{
name = Oxidizer
ratio = 0.6
}
atmosphereCurve
{
key = 0 370
key = 1 270
}

}

CONFIG
{
name = LiquidFuel+LiquidOxygen (55 Thrust, 390 Isp)
thrustVectorTransformName = thrustTransform
exhaustDamage = True
ignitionThreshold = 0.1
minThrust = 0
maxThrust = 55
heatProduction = 275
fxOffset = 0, 0, 0.21
PROPELLANT
{
name = LiquidFuel
ratio = 0.35
DrawGauge = True
}
PROPELLANT
{
name = LiquidOxygen
ratio = 0.65
}
atmosphereCurve
{
key = 0 390
key = 1 300
}

}

CONFIG
{
name = LiquidH2+LiquidOxygen (40 Thrust, 460 Isp)
thrustVectorTransformName = thrustTransform
exhaustDamage = True
ignitionThreshold = 0.1
minThrust = 0
maxThrust = 40
heatProduction = 250
fxOffset = 0, 0, 0.21
PROPELLANT
{
name = LiquidH2
ratio = 0.73
DrawGauge = True
}
PROPELLANT
{
name = LiquidOxygen
ratio = 0.27
}
atmosphereCurve
{
key = 0 460
key = 1 310
}

}
}
}
}

microEngine
{
ADD
{
MODULE
{
name = ModuleEngineConfigs
configuration = LiquidFuel+Oxidizer (1.5 Thrust, 290 Isp)
modded = false
CONFIG
{
name = LiquidFuel+Oxidizer (1.5 Thrust, 290 Isp)
thrustVectorTransformName = thrustTransform
exhaustDamage = True
ignitionThreshold = 0.02
minThrust = 0
maxThrust = 1.5
heatProduction = 30
fxOffset = 0, 0, 0.02
PROPELLANT
{
name = LiquidFuel
ratio = 0.4
DrawGauge = True
}
PROPELLANT
{
name = Oxidizer
ratio = 0.6
}
atmosphereCurve
{
key = 0 290
key = 1 220
}

}

CONFIG
{
name = LiquidFuel+LiquidOxygen (1.6 Thrust, 310 Isp)
thrustVectorTransformName = thrustTransform
exhaustDamage = True
ignitionThreshold = 0.1
minThrust = 0
maxThrust = 1.6
heatProduction = 25
fxOffset = 0, 0, 0.02
PROPELLANT
{
name = LiquidFuel
ratio = 0.35
DrawGauge = True
}
PROPELLANT
{
name = LiquidOxygen
ratio = 0.65
}
atmosphereCurve
{
key = 0 310
key = 1 230
}

}

CONFIG
{
name = LiquidH2+LiquidOxygen (1.2 Thrust, 425 Isp)
thrustVectorTransformName = thrustTransform
exhaustDamage = True
ignitionThreshold = 0.1
minThrust = 0
maxThrust = 1.2
heatProduction = 20
fxOffset = 0, 0, 0.02
PROPELLANT
{
name = LiquidH2
ratio = 0.73
DrawGauge = True
}
PROPELLANT
{
name = LiquidOxygen
ratio = 0.27
}
atmosphereCurve
{
key = 0 425
key = 1 270
}

}
}
}
REPLACE
{
MODULE
{
name = ModuleEngines
thrustVectorTransformName = thrustTransform
exhaustDamage = False
ignitionThreshold = 0.1
minThrust = 0
maxThrust = 1.5
heatProduction = 30
fxOffset = 0, 0, 0.02
PROPELLANT
{
name = LiquidFuel
ratio = 0.4
}
PROPELLANT
{
name = Oxidizer
ratio = 0.6
}
atmosphereCurve
{
key = 0 290
key = 1 220
}

}
}
}

miniFuelTank
{
ADD
{

MODULE
{
name = ModuleFuelTanks
volume = 12.5
basemass = 0.01
TANK
{
name = LiquidH2
loss_rate = 0.000015
efficiency = 0.975
mass = 0.000
}
TANK
{
name = LiquidOxygen
efficiency = 0.995
mass = 0.0003125
loss_rate = 0.0000025
}
TANK
{
name = LiquidFuel
efficiency = 1.0
mass = 0.0003125
}
TANK
{
name = Oxidizer
efficiency = 1.0
mass = 0.0003125
}
TANK
{
name = MonoPropellant
efficiency = 1.0
mass = 0.0005
}
}
}
REPLACE
{

RESOURCE
{
name = LiquidFuel
amount = 5
maxAmount = 5
}

RESOURCE
{
name = Oxidizer
amount = 7.5
maxAmount = 7.5
}
}
}

MK1Fuselage
{
ADD
{
MODULE
{
name = ModuleFuelTanks
volume = 150
basemass = 0.35
TANK
{
name = LiquidH2
loss_rate = 0.000015
efficiency = 0.95
mass = 0.0
temperature = -253
loss_rate = 0.00002
}
TANK
{
name = LiquidOxygen
efficiency = 0.99
mass = 0.0
temperature = -183
loss_rate = 0.000003
}
TANK
{
name = LiquidFuel
efficiency = 1.0
mass = 0.0
}
TANK
{
name = Oxidizer
efficiency = 1.0
mass = 0.0
}
TANK
{
name = MonoPropellant
efficiency = 1.0
mass = 0.0005
}
}
}
}

mk2Fuselage
{
ADD
{

MODULE
{
name = ModuleFuelTanks
volume = 160
basemass = 0.2
TANK
{
name = LiquidH2
loss_rate = 0.000015
efficiency = 0.95
mass = 0.0
temperature = -253
loss_rate = 0.00002
}
TANK
{
name = LiquidOxygen
efficiency = 0.99
mass = 0.0
temperature = -183
loss_rate = 0.000003
}
TANK
{
name = LiquidFuel
efficiency = 1.0
mass = 0.0
}
TANK
{
name = Oxidizer
efficiency = 1.0
mass = 0.0
}
TANK
{
name = MonoPropellant
efficiency = 1.0
mass = 0.0005
}
}
}
}

mk2SpacePlaneAdapter
{

MODULE
{
name = ModuleFuelTanks
volume = 80
basemass = 0.1
TANK
{
name = LiquidH2
loss_rate = 0.000015
efficiency = 0.95
mass = 0.0
temperature = -253
loss_rate = 0.00002
}
TANK
{
name = LiquidOxygen
efficiency = 0.99
mass = 0.0
temperature = -183
loss_rate = 0.000003
}
TANK
{
name = LiquidFuel
efficiency = 1.0
mass = 0.0
}
TANK
{
name = Oxidizer
efficiency = 1.0
mass = 0.0
}
TANK
{
name = MonoPropellant
efficiency = 1.0
mass = 0.0005
}
}
}

mk3Fuselage
{
ADD
{
MODULE
{
name = ModuleFuelTanks
volume = 240
basemass = 0.3
TANK
{
name = LiquidH2
loss_rate = 0.000015
efficiency = 0.95
mass = 0.0
temperature = -253
loss_rate = 0.00002
}
TANK
{
name = LiquidOxygen
efficiency = 0.99
mass = 0.0
temperature = -183
loss_rate = 0.000003
}
TANK
{
name = LiquidFuel
efficiency = 1.0
mass = 0.0
}
TANK
{
name = Oxidizer
efficiency = 1.0
mass = 0.0
}
TANK
{
name = MonoPropellant
efficiency = 1.0
mass = 0.0005
}
}
}
}

mk3spacePlaneAdapter
{
ADD
{

MODULE
{
name = ModuleFuelTanks
volume = 160
basemass = 0.2
TANK
{
name = LiquidH2
loss_rate = 0.000015
efficiency = 0.95
mass = 0.0
temperature = -253
loss_rate = 0.00002
}
TANK
{
name = LiquidOxygen
efficiency = 0.99
mass = 0.0
temperature = -183
loss_rate = 0.000003
}
TANK
{
name = LiquidFuel
efficiency = 1.0
mass = 0.0
}
TANK
{
name = Oxidizer
efficiency = 1.0
mass = 0.0
}
TANK
{
name = MonoPropellant
efficiency = 1.0
mass = 0.0005
}
}
}
}

nuclearEngine
{
REPLACE
{

MODULE
{
name = ModuleEngines
thrustVectorTransformName = thrustTransform
exhaustDamage = True
ignitionThreshold = 0.1
minThrust = 0
maxThrust = 60
heatProduction = 600
fxOffset = 0, 0, 1.6
PROPELLANT
{
name = LiquidH2
ratio = 1.0
DrawGauge = True
}
PROPELLANT
{
name = nuclearFuel
ratio = 0.00000000001
DrawGauge = False
}
atmosphereCurve
{
key = 0 850
key = 1 220
}

}
}
ADD
{
MODULE
{
name = ModuleAlternator
OUTPUT_RESOURCE
{
name = nuclearFuel
rate = -0.000001
}
OUTPUT_RESOURCE
{
name = nuclearWaste
rate = 0.000001
}
OUTPUT_RESOURCE
{
name = ElectricCharge
rate = 0.25
}
}

MODULE
{
name = ModuleGenerator
isAlwaysActive = true

OUTPUT_RESOURCE
{
name = ElectricCharge
rate = 0.25
}
OUTPUT_RESOURCE
{
name = nuclearWaste
rate = 0.0000001
}

INPUT_RESOURCE
{
name = nuclearFuel
rate = 0.0000001
}

}



RESOURCE
{

name = nuclearFuel
amount = 4
maxAmount = 4
}
}
}

radialLiquidEngine1-2
{
ADD
{

MODULE
{
name = ModuleEngineConfigs
configuration = LiquidFuel+LiquidOxygen (120 Thrust, 370 Isp)
modded = false
CONFIG
{
name = LiquidFuel+Oxidizer (115 Thrust, 280 Isp)
thrustVectorTransformName = thrustTransform
exhaustDamage = True
ignitionThreshold = 0.1
minThrust = 0
maxThrust = 115
heatProduction = 375
fxOffset = 0, 0, 0.1
PROPELLANT
{
name = LiquidFuel
ratio = 0.4
DrawGauge = True
}
PROPELLANT
{
name = Oxidizer
ratio = 0.6
}
atmosphereCurve
{
key = 0 280
key = 1 220
}
}

CONFIG
{
name = LiquidFuel+LiquidOxygen (120 Thrust, 370 Isp)
thrustVectorTransformName = thrustTransform
exhaustDamage = True
ignitionThreshold = 0.1
minThrust = 0
maxThrust = 120
heatProduction = 350
fxOffset = 0, 0, 0.1
PROPELLANT
{
name = LiquidFuel
ratio = 0.35
DrawGauge = True
}
PROPELLANT
{
name = LiquidOxygen
ratio = 0.65
}
atmosphereCurve
{
key = 0 370
key = 1 290
}
}

CONFIG
{
name = LiquidH2+LiquidOxygen (105 Thrust, 450 Isp)
thrustVectorTransformName = thrustTransform
exhaustDamage = True
ignitionThreshold = 0.1
minThrust = 0
maxThrust = 105
heatProduction = 275
fxOffset = 0, 0, 0.1
PROPELLANT
{
name = LiquidH2
ratio = 0.73
DrawGauge = True
}
PROPELLANT
{
name = LiquidOxygen
ratio = 0.27
}
atmosphereCurve
{
key = 0 450
key = 1 320
}

}
}
}
REPLACE
{
MODULE
{
name = ModuleEngines
thrustVectorTransformName = thrustTransform
exhaustDamage = True
ignitionThreshold = 0.1
minThrust = 0
maxThrust = 120
heatProduction = 350
fxOffset = 0, 0, 0.1
PROPELLANT
{
name = LiquidFuel
ratio = 0.35
DrawGauge = True
}
PROPELLANT
{
name = LiquidOxygen
ratio = 0.65
}
atmosphereCurve
{
key = 0 370
key = 1 290
}

}
}
}

radialRCSTank
{
ADD
{

MODULE
{
name = ModuleFuelTanks
volume = 40
basemass = 0.055
TANK
{
name = LiquidH2
loss_rate = 0.000015
efficiency = 0.975
mass = 0.000
}
TANK
{
name = LiquidOxygen
efficiency = 0.995
mass = 0.0003125
loss_rate = 0.0000025
}
TANK
{
name = LiquidFuel
efficiency = 1.0
mass = 0.0003125
}
TANK
{
name = Oxidizer
efficiency = 1.0
mass = 0.0003125
}
TANK
{
name = MonoPropellant
efficiency = 1.0
mass = 0.0005
}
TANK
{
name = XenonGas
efficiency = 0.99
mass = 0.00625
}
}
}
}

rocketNoseCone
{
ADD
{
MODULE
{
name = ModuleFuelTanks
volume = 400
basemass = 0.4
TANK
{
name = LiquidH2
efficiency = 0.975
mass = 0.000
temperature = -253
loss_rate = 0.0000000005
}
TANK
{
name = LiquidOxygen
efficiency = 0.995
mass = 0.0003125
temperature = -183
loss_rate = 0.0000000001
}
TANK
{
name = LiquidFuel
efficiency = 1.0
mass = 0.0003125
}
TANK
{
name = Oxidizer
efficiency = 1.0
mass = 0.0003125
}
TANK
{
name = MonoPropellant
efficiency = 1.0
mass = 0.0005
}
}

}
}

smallRadialEngine
{
ADD
{

MODULE
{
name = ModuleEngineConfigs
configuration = LiquidFuel+Oxidizer (200 Thrust, 370 Isp)
modded = false
CONFIG
{
name = LiquidFuel+Oxidizer (20 Thrust, 280 Isp)
thrustVectorTransformName = thrustTransform
exhaustDamage = True
ignitionThreshold = 0.1
minThrust = 0
maxThrust = 20
heatProduction = 150
fxOffset = 0, 0, 0.01
PROPELLANT
{
name = LiquidFuel
ratio = 0.4
DrawGauge = True
}
PROPELLANT
{
name = Oxidizer
ratio = 0.6
}
atmosphereCurve
{
key = 0 280
key = 1 220
}
}

CONFIG
{
name = LiquidFuel+LiquidOxygen (25 Thrust, 390 Isp)
thrustVectorTransformName = thrustTransform
exhaustDamage = True
ignitionThreshold = 0.1
minThrust = 0
maxThrust = 25
heatProduction = 133
fxOffset = 0, 0, 0.01
PROPELLANT
{
name = LiquidFuel
ratio = 0.35
DrawGauge = True
}
PROPELLANT
{
name = LiquidOxygen
ratio = 0.65
}
atmosphereCurve
{
key = 0 390
key = 1 250
}
}

CONFIG
{
name = LiquidH2+LiquidOxygen (18 Thrust, 450 Isp)
thrustVectorTransformName = thrustTransform
exhaustDamage = True
ignitionThreshold = 0.1
minThrust = 0
maxThrust = 18
heatProduction = 125
fxOffset = 0, 0, 0.01
PROPELLANT
{
name = LiquidH2
ratio = 0.73
DrawGauge = True
}
PROPELLANT
{
name = LiquidOxygen
ratio = 0.27
}
atmosphereCurve
{
key = 0 450
key = 1 250
}

}
}
}
REPLACE
{
MODULE
{
name = ModuleEngines
thrustVectorTransformName = thrustTransform
exhaustDamage = True
ignitionThreshold = 0.1
minThrust = 0
maxThrust = 20
heatProduction = 150
fxOffset = 0, 0, 0.01
PROPELLANT
{
name = LiquidH2
ratio = 0.73
DrawGauge = True
}
PROPELLANT
{
name = LiquidOxygen
ratio = 0.27
}
atmosphereCurve
{
key = 0 450
key = 1 250
}

}
}
}

toroidalAerospike
{
ADD
{
MODULE
{
name = ModuleEngineConfigs
configuration = LiquidFuel+Oxidizer (200 Thrust, 370 Isp)
modded = false
CONFIG
{
name = LiquidFuel+Oxidizer (200 Thrust, 370 Isp)
thrustVectorTransformName = thrustTransform
exhaustDamage = True
ignitionThreshold = 0.1
minThrust = 0
maxThrust = 200
heatProduction = 600
fxOffset = 0, 0, 0.25
PROPELLANT
{
name = LiquidFuel
ratio = 0.4
DrawGauge = True
}
PROPELLANT
{
name = Oxidizer
ratio = 0.6
}
atmosphereCurve
{
key = 0 370
key = 1 368
}

}

CONFIG
{
name = LiquidFuel+LiquidOxygen (175 Thrust, 390 Isp)
thrustVectorTransformName = thrustTransform
exhaustDamage = True
ignitionThreshold = 0.1
minThrust = 0
maxThrust = 175
heatProduction = 550
fxOffset = 0, 0, 0.25
PROPELLANT
{
name = LiquidFuel
ratio = 0.35
DrawGauge = True
}
PROPELLANT
{
name = LiquidOxygen
ratio = 0.65
}
atmosphereCurve
{
key = 0 390
key = 1 388
}

}

CONFIG
{
name = LiquidH2+LiquidOxygen (150 Thrust, 460 Isp)
thrustVectorTransformName = thrustTransform
exhaustDamage = True
ignitionThreshold = 0.1
minThrust = 0
maxThrust = 150
heatProduction = 500
fxOffset = 0, 0, 0.25
PROPELLANT
{
name = LiquidH2
ratio = 0.73
DrawGauge = True
}
PROPELLANT
{
name = LiquidOxygen
ratio = 0.27
}
atmosphereCurve
{
key = 0 460
key = 1 455
}

}
}
}
REPLACE
{
MODULE
{
name = ModuleEngines
thrustVectorTransformName = thrustTransform
exhaustDamage = True
ignitionThreshold = 0.1
minThrust = 0
maxThrust = 175
heatProduction = 550
fxOffset = 0, 0, 0.25
PROPELLANT
{
name = LiquidFuel
ratio = 0.35
DrawGauge = True
}
PROPELLANT
{
name = LiquidOxygen
ratio = 0.65
}
atmosphereCurve
{
key = 0 390
key = 1 388
}
}
}
}

toroidalFuelTank
{
ADD
{
MODULE
{
name = ModuleFuelTanks
volume = 22.2
basemass = 0.0125
TANK
{
name = LiquidH2
loss_rate = 0.000015
efficiency = 0.975
mass = 0.000
}
TANK
{
name = LiquidOxygen
efficiency = 0.995
mass = 0.0003125
loss_rate = 0.0000025
}
TANK
{
name = LiquidFuel
efficiency = 1.0
mass = 0.0003125
}
TANK
{
name = Oxidizer
efficiency = 1.0
mass = 0.0003125
}
TANK
{
name = MonoPropellant
efficiency = 1.0
mass = 0.0005
}
TANK
{
name = XenonGas
efficiency = 0.99
mass = 0.000625
}
}
}
REPLACE
{
RESOURCE
{
name = LiquidFuel
amount = 10
maxAmount = 10
}

RESOURCE
{
name = Oxidizer
amount = 12.2
maxAmount = 12.2
}
}
}

So, each config file can include multiple subfiles, and can also includes Part nodes. A Part node is simply the name of a Part (for example, fuelTank2-2), followed by a series of subnodes that describe what to change on that part. A Part node can contain any of three types of subnodes:

REMOVE

A REMOVE node contains a list of fields. Each field's key must be a RESOURCE or MODULE, and its value must be the name of the Resource or PartModule to remove from the part.

ADD

An ADD node contains a list of nodes. Each node must be a RESOURCE or MODULE node to add to the part.

REPLACE

A REPLACE node functionally operates like a REMOVE node followed by an ADD node - for each RESOURCE or MODULE subnode, it finds the RESOURCE or MODULE with the name specified, deletes it, and replaces it with the one defined in the subnode.

This should make plugin compatibility between authors about 10x easier, while we wait for the official solution in 0.20.

Get it here.

View source here.

What do you think, Sirs?

Edited by ialdabaoth
Link to comment
Share on other sites

interesting idea, however just to point it out: the changes to 'parts as pre-loaded database' may destroy this method completely.

and it is (scheduled) to happen in .20

Link to comment
Share on other sites

UPDATE: Link unchanged, but I've fixed a few bugs, and added config files for the following mods:

stock KSP

ModularFuelTanks

KW Rocketry

RemoteTech

IonCrossLSS

KSPX

Also, the ModularFuelTanks plugin is now included with the release.

Link to comment
Share on other sites

What you're doing is very interesting; and should very much be incorporated into the game. Modifying the files after they're loaded allows for extremely easy "batching" of types. Even more so if you include wildcards or other search terms. (Fortunately

Collections.Generic.List`1[AvailablePart] PartLoader.loadedPartsList

is public; which means you can easily skip the method and make your own search criteria. Remember, people have MANY MANY parts; why should YOU know all possible parts when you can say "Well, if it has

RESOURCE

{

name = LiquidFuel

}

it probably is a fuel tank.

(Although I do not agree with violating protections to call a method that "seems to do what you want") [i mean, I have little idea what unintended consequences awakening the part before it is on a ship may have... and as you can't "sleep" the part...]

*also, question... why not self terminate after loading the assembly? I mean, unless you actually intend to make an GUI allowing people to change Part.cfg files without restarting; hence creating a nightmare when things go wrong!

Link to comment
Share on other sites

(Although I do not agree with violating protections to call a method that "seems to do what you want") [i mean, I have little idea what unintended consequences awakening the part before it is on a ship may have... and as you can't "sleep" the part...]

Neither do I, in principle... in practice, all I can do to make it work is call the function and then hope that .20 fixes the problem.

*also, question... why not self terminate after loading the assembly? I mean, unless you actually intend to make an GUI allowing people to change Part.cfg files without restarting; hence creating a nightmare when things go wrong!

That's basically the reason. I intend to add a bit to the Settings menu to allow users to select alternate .cfg sets.

Link to comment
Share on other sites

REMOVE does not seem to work. First noticed when trying to replace a RESOURCE value that it didn't do anything. Then simply tried removing an existing RESOURCE to see what would happen, and nothing did. Any suggestions?

Link to comment
Share on other sites

REMOVE does not seem to work. First noticed when trying to replace a RESOURCE value that it didn't do anything. Then simply tried removing an existing RESOURCE to see what would happen, and nothing did. Any suggestions?

What does your REMOVE node look like?

It should look something like this:


PartName
{
REMOVE
{
RESOURCE = resourceName
MODULE = moduleName
}
}

Paste your .cfg file and I'll try debugging it.

Link to comment
Share on other sites

Okay, that does work. What I had been doing was in line with the other methods:


PartName
{
REMOVE
{
RESOURCE
{
name = ElectricCharge
}
}
}

I suppose replace is also working, but I did not realize it because the text in the hover-over gui does not reflect the new values I replaced with. But your gui on the action groups screen does show the new values. (referring to modular fuel tanks, obviously) What I mean by that is, if I change the maxAmount via replace, it is still shown as the original maxAmount in the vanilla gui.

Edited by JeBuSBrian
Link to comment
Share on other sites

Neither do I, in principle... in practice, all I can do to make it work is call the function and then hope that .20 fixes the problem.

Honestly, reflection quite scares/infuriates me.

I understand the need when using "Blind Discovery" (such as how KSP doesn't know a PartModule exists, but you can still add it); but after managing to make a ".NET peek" program (I don't have visual studio installed, and a few quick searches (based on not knowing what I wanted) for the mono equivalent were futile) I saw just how much was left. When I checked my code, I found even the tiny "Macro Functions" still managed to remain fully defined...

On the other hand, I have no idea why SQUAD is bothering with all these "XXXList" Classes, after running through the while "Assembly-Csharp.dll" I found that "PartResourceList" has a public "values" (which is the list that the wrapper class was trying to protect)....

But "PartModuleList" has a hidden (and unnamed???) "values" but it seems like I can interact with it all I want (using the properties), I just cannot call the .Add method.

Link to comment
Share on other sites

I want to install IonCross's Life Support System plugin. but I have installed additional parts mod that adds many crew containers/command modules, How do I use this tool to automatically add the lifesupport code to all parts that supports a crew inside??

would it be possible to just detect all parts that can support a crew like finding a code "CrewCapacity <= 1" and then add lifesupport? :D

I tried this manually the other day but I just gave up due to the intense amount of editing needed and its hard to pinpoint where the parts are exactly

Edited by lyndonguitar
Link to comment
Share on other sites

I want to install IonCross's Life Support System plugin. but I have installed additional parts mod that adds many crew containers/command modules, How do I use this tool to automatically add the lifesupport code to all parts that supports a crew inside??

would it be possible to just detect all parts that can support a crew like finding a code "CrewCapacity <= 1" and then add lifesupport? :D

I tried this manually the other day but I just gave up due to the intense amount of editing needed and its hard to pinpoint where the parts are exactly

I've been writing my own little programs to do this kind of stuff for me. Haven't tried with IonCross, but did it with MechJeb to integrate that into all the pods. I couldn't take manually going through all the files. Automation is awesome.

Link to comment
Share on other sites

I've been writing my own little programs to do this kind of stuff for me. Haven't tried with IonCross, but did it with MechJeb to integrate that into all the pods. I couldn't take manually going through all the files. Automation is awesome.

Could you share to me the one you used on mechjeb? that would also be handy :D

Link to comment
Share on other sites

Could you share to me the one you used on mechjeb? that would also be handy :D

Well, it's hardly pretty, not at all user-friendly, and has almost no exception handling because it was only meant for myself, but here's the code:


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace KerbalModularization
{
static class ModularMechJeb
{
/// <summary>
/// Searches through a directory to find any command modules, adds
/// MechJeb to them via modular config file.
/// </summary>
/// <param name="inDirectory">
/// Full path of the directory to search through.
/// Can be KSP's Parts folder, or a single part folder. Will search
/// all subfolders.
/// </param>
/// <param name="outCfgFile">
/// Full path of the output .cfg file. This should be
/// KSP/PluginData/moduleManager/
/// </param>
public static void Modularize(string inDirectory, string outCfgFile)
{
DirectoryInfo di = new DirectoryInfo(inDirectory);
List<FileMatches> lstFileMatches = AnalyzeConfigs(di);
MakeModularConfig(outCfgFile, lstFileMatches);
}

static List<FileMatches> AnalyzeConfigs(DirectoryInfo directory)
{
if (!directory.Exists)
return default(List<FileMatches>);

List<FileMatches> lstFileMatches = new List<FileMatches>();

foreach (DirectoryInfo partdir in directory.EnumerateDirectories())
{
foreach (string filename in Directory.EnumerateFiles(partdir.FullName, "*.cfg", SearchOption.TopDirectoryOnly))
{
using (StreamReader sr = File.OpenText(filename))
{
string cfgText = sr.ReadToEnd();

bool isPod = cfgText.Contains("category = Pods");

if (isPod)
{
List<Match> matches = GetUnNestedModules(cfgText);
FileMatches fm = new FileMatches()
{
File = new FileInfo(filename),
Matches = matches,
};

lstFileMatches.Add(fm);
}
}
}
}

return lstFileMatches;
}


static List<Match> GetUnNestedModules(string cfgText)
{
string pattern = "MODULE";
List<Match> matches = new List<Match>();
MatchCollection mc = Regex.Matches(cfgText, pattern);
foreach (Match m in mc)
{
int numOpenBracesAfter = GetInstancesOfChar(cfgText.Substring(m.Index), '{');
int numCloseBracesAfter = GetInstancesOfChar(cfgText.Substring(m.Index), '}');
bool nested = numOpenBracesAfter < numCloseBracesAfter;
//Debug.WriteLine("@Index: {0} - Nested: {1}", m.Index, nested);
if (!nested)
matches.Add(m);
}

return matches;
}

static int GetInstancesOfChar(string str, char chr)
{
char[] testchars = str.ToCharArray();
int count = 0;
for (int n = testchars.Length - 1; n >= 0; n--)
{
if (testchars[n] == chr)
count++;
}

return count;
}

static void MakeModularConfig(string filename, List<FileMatches> lstFileMatches)
{
StringBuilder sb = new StringBuilder();

foreach (FileMatches fm in lstFileMatches)
{
string cfgText = "";

using (StreamReader sr = File.OpenText(fm.File.FullName))
{
cfgText = sr.ReadToEnd();
}

if (fm.Matches.Count == 0)
continue;

List<Module> modules = new List<Module>(fm.Matches.Count);
foreach (Match m in fm.Matches)
{
Module mod = GetModule(cfgText.Substring(m.Index));
if (mod.Name == "ModuleCommand")
modules.Add(mod);
}

if (modules.Count == 0)
continue;

Module command = modules[0];

string partName = GetParameterValue(cfgText, "name").Replace('_', '.');
string t1 = "\t";
string t2 = "\t\t";
string t3 = "\t\t\t";
string t4 = "\t\t\t\t";

sb.AppendLine(partName);
sb.AppendLine("{");

sb.AppendLine(t1 + "REPLACE");
sb.AppendLine(t1 + "{");

sb.AppendLine(t2 + "MODULE");
sb.AppendLine(t2 + "{");

sb.AppendLine(t3 + "name = ModuleCommand");
sb.AppendLine(t3 + "minimumCrew = " + command.MinimumCrew);
sb.AppendLine(t3 + "RESOURCE");
sb.AppendLine(t3 + "{");

sb.AppendLine(t4 + "name = ElectricCharge");
sb.AppendLine(t4 + "rate = 0.005");

sb.AppendLine(t3 + "}");
sb.AppendLine(t2 + "}");
sb.AppendLine(t1 + "}");

sb.AppendLine("");
sb.AppendLine(t1 + "ADD");
sb.AppendLine(t1 + "{");
sb.AppendLine(t2 + "MODULE");
sb.AppendLine(t2 + "{");

sb.AppendLine(t3 + "name = MechJebCore");

sb.AppendLine(t2 + "}");
sb.AppendLine(t1 + "}");

sb.AppendLine("}");
sb.AppendLine("");

string module = sb.ToString();
}

using (StreamWriter sw = File.CreateText(filename))
{
sw.Write(sb);
}
}

static string GetParameterValue(string cfgText, string parameter)
{
parameter = parameter + " = ";
int idxParameter = NthIndexOf(cfgText, parameter, 1);

if (idxParameter == -1)
return "";

string subString = cfgText.Substring(idxParameter);
int idxNewLine = NthIndexOf(subString, Environment.NewLine, 1);
string value = subString.Substring(parameter.Length, idxNewLine - parameter.Length);

return value;
}

static Module GetModule(string cfgText)
{
string strName = GetParameterValue(cfgText, "name");

if (strName != "ModuleCommand")
return default(Module);

string strMinimumCrew = GetParameterValue(cfgText, "minimumCrew");
int minCrew = 0;
Int32.TryParse(strMinimumCrew, out minCrew);

Module m = new Module()
{
Name = strName,
MinimumCrew = minCrew,
};

return m;
}

static int NthIndexOf(string text, char searchChar, int nthindex)
{
int index = -1;
try
{
var takeCount = text.TakeWhile(x => (nthindex -= (x == searchChar ? 1 : 0)) > 0).Count();
if (takeCount < text.Length) index = takeCount;
}
catch { }
return index;
}
static int NthIndexOf(string text, string searchText, int nthindex)
{
int index = -1;
try
{
Match m = Regex.Match(text, "((" + searchText + ").*?){" + nthindex + "}");
if (m.Success) index = m.Groups[2].Captures[nthindex - 1].Index;
}
catch { }
return index;
}

class FileMatches
{
public FileInfo File { get; set; }
public List<Match> Matches { get; set; }
}

public struct Module
{
public string Name { get; set; }
public int MinimumCrew { get; set; }
}
}
}

To use it, I simply did this inside a WPF app's initialization, but you can also do it in a console program's main method if you like:


ModularMechJeb.Modularize(@"C:\Users\Mine\Desktop\B9\Parts",
@"C:\Users\Mine\Desktop\B9\B9_modularMechJeb.cfg");

At some point I should get around to making an actual user-friendly app, but I wouldn't hold my breath if I were you. I hate the process of writing safe, user-friendly code, and I avoid it as often as I can. :wink: Especially when it's only for me.

Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...