Jump to content

Adding PartModule to Part at runtime in Flight Mode


Recommended Posts

Alright.

I have a PartModule (module name 'ModuleOSJ') that I want to add dynamically during flight to the root part of the vessel.

I started with this:

if(!FlightGlobals.ActiveVessel.rootPart.Modules.Contains("ModuleOSJ")) //does our partmodule exist?
{
PartModule Added = FlightGlobals.ActiveVessel.rootPart.Modules.OfType<ModuleOSJ>().First();
}

This checks if the ModuleOSJ partmodule exists and adds it if it does not.

This works great for that first time and everything behaves as expected. This includes saving because when I check the persistence file, I can see the PartModule on the part and the values have saved correctly.

However, loading does not work.

In the log I get the following error when loading the vessel at flight scene start:


Part mk1pod cannot load module #8. It only has 8 modules defined

From this thread here: http://forum.kerbalspaceprogram.com/threads/78611-When-the-part-config-and-the-save-file-are-different it looks like that error message is thrown because having added my ModuleOSJ partmodule, the copy of the mk1pod in the persistence file has 9 part modules (module list starts at count zero for the first partmodule), but the saved prefab only has 8 modules so the mis-match causes the above error to be thrown.

Now, I don't want to update the prefab with my partmodule as only the root part on a vessel needs it.

This thread here says he figured out how to add a partmodule dynamically in the VAB using reflection to call the partmodule.Awake() method so the setup happens correctly.

http://forum.kerbalspaceprogram.com/threads/27851-part-AddModule%28ConfigNode-node%29-NullReferenceException-in-PartModule-Load%28node%29-help

Setting that up does not seem to work either, as far as I can tell calling the Awake method via reflection is working, but I still run into the partmodule mis-match error above so I don't know that can even fix my problem.

Does anyone know of a work around for this? All I'm trying to do is save a few strings and numbers on a per vessel basis, I really don't want to have to brute force adding the partmodule via ModuleManager to every part (how I'm currently doing it in my Action Groups mod), or have to figure out the Scenario Module to serve as a data storage location.

D.

Link to comment
Share on other sites

Your best bet is to change your system so that the partmodule checks if it's the root part during Start() and if not kills itself; then add that partmodule to everything via either ModuleManager or by modifying the AvailablePart pool.

[KSPAddon (KSPAddon.Startup.SpaceCentre, true)]public class AddOSJ : MonoBehaviour{	foreach (AvailablePart part in PartLoader.Instance.parts)	{		if(!part.Modules.Contains("ModuleOSJ")) //does our partmodule exist?		{			PartModule added = part.Modules.OfType<ModuleOSJ>().First();		}	}}
public class ModuleOSJ () : PartModule{
	Public override void OnStart (PartModule.StartState state)	{		if (HighLogic.LoadedSceneIsFlight && part != FlightGlobals.ActiveVessel.rootPart)		{			enabled = false;		}	}}

the above may not directly work, but it should be a good direction to go. You could alternately wrap all your other events in if (part == ~.rootPart){}, which should be cheap enough for every part to run every frame, but I'm not confidant.

Edited by Greys
Link to comment
Share on other sites

Alright.

I have a PartModule (module name 'ModuleOSJ') that I want to add dynamically during flight to the root part of the vessel.

I was in almost exactly the same position as you with ScienceAlert. I tried every way I could think of that didn't involve adding the PartModule to every prefab. Ultimately I failed and decided to design around the problem. In your case, I think Greys' solution is the best. Don't bother with MM; that's just an unnecessary dependency.

The only gotcha is that you shouldn't forget that the vessel configuration can change, so you'll be needing some appropriate logic in OnVesselWasModified etc

Edit: Also, there's the customPartData field you can use. It would be the most simple and straightforward solution, though of course there will be issues mixing your mod with any other that happens to also use the field

Link to comment
Share on other sites

/sigh, sounds like there is no direct method to do this.

@Greys: While that would work, it still seems the backwards way to do things by adding it to every part and then removing the partmodule if it is on a non-root part. If I was in a hurry I would go with that to get it up and running, but as I'm not I'm going to take this as a learning opportunity and work with the Scenario Module for the first time. (As I understand it you can use it as a data storage DB.)

@xEvilReeperx: Thanks for the confirmation that I did not miss something.

D.

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