Jump to content

Read .cfg file value from Vessel.Parts list


Recommended Posts

Alright.

This is probably about as simple as you can get, but it has stymied me for 3 hours now so here we go.

I have my current vessel and it's list of parts from Vessel.Parts

I am able to find which parts have a ModuleEngines node, but I'm trying to tell apart Solid Rocket Boosters which requires looking at the throttleLocked value in the ModuleEngines config node and am absolutely stuck.


namespace TWR1
{
[KSPAddon(KSPAddon.Startup.Flight, false)]
public class TWR1 : PartModule
{
private static Vessel TWR1Vessel; //Our active vessel

public void Update()
{
TWR1Vessel = FlightGlobals.ActiveVessel; //Set vessel to active vessel
foreach (Part part in TWR1Vessel.Parts)
{
print(part.Modules.Contains("ModuleEngines")); //will print "True" to debug log if a part's .cfg file has a module named "ModuleEngines"
//unknown code here to tell Solid Rocket Boosts apart
}
}
}

I've left out a bunch of code to keep focused on my question, as is this will spam your debug log every update with a true/false message for every part on your vessel.

Now, how do I look at the throttleLocked key if Contains(ModuleEngines) evaluates to true? I think I need to use part.Fields.GetValue or part.Fields.ReadValue but I've been trying variations of that for 3 hours now and am out of ideas.

Anyone know what those methods are expecting? Passing "ModuleEngines" or "throttleLocked" returns a not found error.

D.

edit: Actually it looks like I need to use the part.Module. class somehow to do this.

All I'm after is the throttleLocked = true for solid rocket boosters if someone knows a better way to check this.

Edited by Diazo
Link to comment
Share on other sites

Here's what I came up with, it should get you there

foreach (Part part in FlightGlobals.ActiveVessel.parts)
foreach (PartModule module in part.Modules.OfType<ModuleEngines>())
{
ModuleEngines engine = module as ModuleEngines;

// propellant type
foreach (ModuleEngines.Propellant propellant in engine.propellants)
UnityEngine.Debug.Log("Engine '" + part.name + "' uses " + propellant.name);

UnityEngine.Debug.Log("Can you shut it down? " + (engine.allowShutdown ? "yes" : "no"));
UnityEngine.Debug.Log("Can you change its throttle? " + (engine.throttleLocked ? "yes" : "no"));
}

Link to comment
Share on other sites

if you are solely working with loaded vessels/parts, you could just use typecasting (like suggested above). If the part isn't loaded, you'll need to access the ConfigNode generated from the part config file. If memory serves, you'll need to do something like this:


if (vessel.loaded) {
foreach (Part p in vessel.parts)
if (p.Modules.Contains("ModuleEngines") && (p.Modules["ModuleEngines"] as ModuleEngines).throttleLocked) {
//do stuff.
}
} else {
foreach (ProtoPartSnapshot p in vessel.protoVessel.protoPartSnapshots) {
if (p.partInfo.internalConfig.HasNode("ModuleEngines") &&
bool.Parse(p.partInfo.internalConfig.GetNode("ModuleEngines").GetValue("throttleLocked"))) {
//do stuff.
}
}
}

You cannot simply look through the persistence data (look into RT1 source here for example) since throttleLocked is not a persistant field.

I'm not entirely certain that p.partInfo.internalConfig is in fact the configNode you'll need, since I've never had use of it. Neither have I checked under which circumstances it is loaded. It is however an informed guess. Play around with it a bit and see what works.

In the case that you are only working with loaded vessels (ie.: FlightGlobals.ActiveVessel), you won't need anything more than the simple typecast.

Link to comment
Share on other sites

First of all, since you are dealing with a loaded vessel, there is nothing to do with the .cfg file, so make sure you understand that first.


foreach (Part p in FlightGlobals.ActiveVessel.Parts)
foreach (PartModule pm in p.Modules)
if (pm is ModuleEngines)
{
bool locked = ((ModuleEngines)pm).throttleLocked;
// stuff
}

Link to comment
Share on other sites

Wow, thanks for the replies everyone.

All 3 examples look promising and they all have something new for me to learn.

I'll try them out tonight and see which fits with what I'm trying to do. (I'm cheating and posting from work so no access to KSP until later for me.)

D.

Link to comment
Share on other sites

  • 2 months later...

Here's the code I ended up running with.

This code does two checks, first seeing if the part has a "ModuleEngines", and if it does, it checks to see if the value "throttleLocked" is true.

I then get add the min and max thrust of the engine to the available thrust of the craft for later calculations.


foreach (Part part in TWR1Vessel.Parts) //go through each part on vessel. Part is of type Parts, part is the list container
{
if (part.Modules.Contains("ModuleEngines")) //does this Part have a ModuleEngine, meaning it is an engine?
{
foreach (PartModule TWR1PartModule in part.Modules) //this Part has a ModuleEngines, move from the Part to the PartModules level
{
if (TWR1PartModule.moduleName == "ModuleEngines") //find the ModuleEngine PartModule
{
TWR1EngineModule = (ModuleEngines)TWR1PartModule; //change from the PartModules level to the ModuleEngines level
if ((bool)TWR1PartModule.Fields.GetValue("throttleLocked") && TWR1EngineModule.isOperational) //if throttlelocked is true, this is solid rocket booster. then check engine is operational. if the engine is flamedout, disabled via-right click or not yet activated via stage control, isOperational returns false. This will return false if throttleLocked does not exist.
{
TWR1MaxThrust += (float)(TWR1PartModule.Fields.GetValue("maxThrust")); //add engine thrust to MaxThrust
TWR1MinThrust += (float)(TWR1PartModule.Fields.GetValue("maxThrust")); //add engine thrust to MinThrust since this is an SRB and is always at Max thrust
}
else if (TWR1EngineModule.isOperational)//we know it is an engine and not a solid rocket booster so:
{
TWR1MaxThrust += (float)(TWR1PartModule.Fields.GetValue("maxThrust")); //add engine thrust to MaxThrust
TWR1MinThrust += (float)(TWR1PartModule.Fields.GetValue("minThrust")); //add engine thrust to MinThrust, stock engines all have min thrust of zero, but mods may not be 0
}
}
}
}
}

The big limitation here is I've hardcoded the stuff I'm looking for as I'm very specific in what I'm looking for.

Depending on what you end up wanting, you may be looking at going through a part multiple times for different values, or chaining IFs together to get the info you want.

Hope that helps,

D.

Link to comment
Share on other sites

I'd still be interested if anyone can help tell me how to read the part's .cfg file. There's some valuable info there.

I'm sure someone will let me know if this is wrong, but if you want to read certain info from the config file, I'd suggest looking at: part.partInfo...

Link to comment
Share on other sites

Seems like there's two questions here:

1. How do I read part info

2. How do I read from the cfg itself, rather than what's loaded into the game.

Every recognized line in a part.cfg file is loaded into the part object or its various modules or PartInfo object or whatever. The above code examples talk about how to get that. But if you actually want to read the cfg file you need to first find the confignode that is that part (i.e. find all PART confignodes, then find one with the value name where name == the part's id). Then you can getvalue for whatever property you want, and/or getnode if you want a subnode (like MODULE or INTERNAL or whatever).

Link to comment
Share on other sites

Here's the code I ended up running with.

This code does two checks, first seeing if the part has a "ModuleEngines", and if it does, it checks to see if the value "throttleLocked" is true.

I then get add the min and max thrust of the engine to the available thrust of the craft for later calculations.


foreach (Part part in TWR1Vessel.Parts) //go through each part on vessel. Part is of type Parts, part is the list container
{
if (part.Modules.Contains("ModuleEngines")) //does this Part have a ModuleEngine, meaning it is an engine?
{
foreach (PartModule TWR1PartModule in part.Modules) //this Part has a ModuleEngines, move from the Part to the PartModules level
{
if (TWR1PartModule.moduleName == "ModuleEngines") //find the ModuleEngine PartModule
{
TWR1EngineModule = (ModuleEngines)TWR1PartModule; //change from the PartModules level to the ModuleEngines level
if ((bool)TWR1PartModule.Fields.GetValue("throttleLocked") && TWR1EngineModule.isOperational) //if throttlelocked is true, this is solid rocket booster. then check engine is operational. if the engine is flamedout, disabled via-right click or not yet activated via stage control, isOperational returns false. This will return false if throttleLocked does not exist.
{
TWR1MaxThrust += (float)(TWR1PartModule.Fields.GetValue("maxThrust")); //add engine thrust to MaxThrust
TWR1MinThrust += (float)(TWR1PartModule.Fields.GetValue("maxThrust")); //add engine thrust to MinThrust since this is an SRB and is always at Max thrust
}
else if (TWR1EngineModule.isOperational)//we know it is an engine and not a solid rocket booster so:
{
TWR1MaxThrust += (float)(TWR1PartModule.Fields.GetValue("maxThrust")); //add engine thrust to MaxThrust
TWR1MinThrust += (float)(TWR1PartModule.Fields.GetValue("minThrust")); //add engine thrust to MinThrust, stock engines all have min thrust of zero, but mods may not be 0
}
}
}
}
}

The big limitation here is I've hardcoded the stuff I'm looking for as I'm very specific in what I'm looking for.

Depending on what you end up wanting, you may be looking at going through a part multiple times for different values, or chaining IFs together to get the info you want.

Hope that helps,

D.

Here's a cleaner (looking) way to do that with LINQ. I don't know enough about LINQ to know if it's actually any better or faster. :wink:


float maxThrust;
float minThrust;

foreach (ModuleEngines EngineModule in TWR1Vessel.Parts
.SelectMany(p => p.Modules.Cast<PartModule>())
.Where(m => m.moduleName == "ModuleEngines")
.Select(m => m as ModuleEngines)
.Where(m => m.isOperational))
{
maxThrust = EngineModule.maxThrust;

if (EngineModule.throttleLocked)
{
// This is an SRB; its minThrust is the same as its maxThrust
minThrust = EngineModule.maxThrust;
}
else
{
// This is not an SRB; get its minThrust
minThrust = EngineModule.minThrust;
}

TWR1MaxThrust += maxThrust; //add engine thrust to MaxThrust
TWR1MinThrust += minThrust; //add engine thrust to MinThrust, stock engines all have min thrust of zero, but mods may not be 0
}

If you're really wanting to get at the config files, you will need to know their file path (or be willing to search for it), at which point you can get the ConfigNode through ConfigNode.Load() or GameDatabase.GetConfigNode(). If there's a better way to do that, I'm not sure; I've never dealt much with part classes. What do you want from the config file that the part object doesn't have?

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...