Jump to content

[SOLVED] ModuleScienceExperiment.DeployExperiment with multiple experiments?


Recommended Posts

tl;dr: I can't figure out how to - in code - automatically kick off more than one experiment per part.

I got it in my head to make a single part that can do all science experiments. Because I'm lazy. I mean efficient. Anyway. I want - say - the Gravioli Detector to just have all the other experiments in it so I don't have to have to bring all the other stuff too. I used ModuleManager to add the other 4 "simple" experiments (temperature, barometer, seismic, and atmosphere) to the Gravioli Detector and sure enough, in the game the buttons show up and work without a hitch. I can via the (many) buttons execute all 5 experiments, review them, remove them, etc. However, it's clunkly to do so, clunkier than just bringing the other 5 experiment parts along in the first place.

Well lucky for me I wrote All Y'All, which automatically kicks off experiments. So I right clicked the part, selected "Perform All Science" and... it only ran the Gravioli Detector. Looks like the moron who wrote this mod set it up to only run whatever experiment it found in the part first.

So I dug into the code to see what I could do, and (as is common for me) I couldn't figure it out. I am by no means an expert but it looks to me like it's not even possible to do, though I tend to doubt anything I think about coding.

Here's my code as it stands (0.3 version of AYA):

    public class AYA_Science : PartModule
    {
        [KSPEvent(guiActive = true, guiActiveEditor = false, guiName = "Perform All Science")]
        public void DoAllScience()
        {
            foreach (Part eachPart in vessel.Parts)
            {
                var thisPart = eachPart.FindModuleImplementing<ModuleScienceExperiment>();
                if (thisPart != null) thisPart.DeployExperiment();
            }
        }
    }

And here's what I changed it to that doesn't work:

    public class AYA_Science : PartModule
    {
        [KSPEvent(guiActive = true, guiActiveEditor = false, guiName = "Perform All Science")]
        public void DoAllScience()
        {
            foreach (Part eachPart in vessel.Parts)
            {
                var thisPart = eachPart.FindModuleImplementing<ModuleScienceExperiment>();
                foreach (KSPModule eachModule in thisPart.Modules)
                {
                    if (thisPart != null) thisPart.DeployExperiment(something_clever);
                }
            }
        }
    }

There are 2 things wrong with the above code:

  1. There is no "thisPart.Modules" list. I don't know how to get the list of all modules in a part, or even if that's what I need to do here. But it seems like a reasonable thing to want.
  2. Where I put "something_clever" I have no idea what to put. If anything CAN even be put there. All the examples I've found, that's blank. It seems though with it being blank, the game itself is never expecting a part to have more than one science experiment.

So am I just boned? No clever shortcuts for me? Or can someone cleverer than I help a poor scripter-turning-coder out?

Edited by 5thHorseman
Link to comment
Share on other sites

Update to this: I found a flaw in my thinking (no surprise there). The variable I had named "thisPart" is not a part at all, but a module. So it appears that the line:

var thisPart = eachPart.FindModuleImplementing<ModuleScienceExperiment>();

is the culprit. It's just finding the first experiment. However, I don't know how to tell it to loop through each experiment. Below I have a nonworking line where I renamed thisPart to thisExperiment so it's easier for me to read:

foreach (ModuleScienceExperiment thisExperiment in eachPart.FindModulesImplementing<ModuleScienceExperiment>)

however this fails with the error:

Severity	Code	Description
Error	CS0446	Foreach cannot operate on a 'method group'. Did you intend to invoke the 'method group'?

To which I answer... "I didn't intend anything. I don't even know what that means."

Link to comment
Share on other sites

Try this - quick test looks like it works

        [KSPEvent(active = true, guiActive = true)]
        public void OnPress()
        {
            ModuleScienceExperiment[] MSEList = vessel.GetComponentsInChildren<ModuleScienceExperiment>();
            for (int i=0;i<MSEList.Length;i++)
            {
                MSEList[i].DeployExperiment();
            }
        }

You may need list and loop through the parts on the vessel - not sure.

Edit: Another quick test - you will need to list and loop through the parts - this only fires the experiments if they're on the root part.

Edited by wasml
additional info
Link to comment
Share on other sites

Your logic is right in that FindModuleImplementing<> only returns the first module of that type.

It's a pretty simple fix though:

public class AYA_Science : PartModule
    {
        [KSPEvent(guiActive = true, guiActiveEditor = false, guiName = "Perform All Science")]
        public void DoAllScience()
        {
            foreach (Part eachPart in vessel.Parts) //cycle through all parts
            {
                foreach (PartModule pm in eachPart.modules) //cycle through all partModules on the current part
				{
					if(pm is ModuleScienceExperiment) //check if current partModule is a ModuleScienceExperiment, or inherited from one. 'is' is a C# keyword for this.
						{
							(ModuleScienceExperimet)pm.DeployExpriment(); //since the current partModule is a ModuleScienceExperiment, cast from type PartModule to type ModuleScienceExperiment so we can call .DeployExperiment.
						{
				}
            }
        }
    }

There is probably ways using the shortcut methods Squad supplies for working with modules that would accomplish this in fewer lines of code, but this makes it clear what is going on.

On the error you don't understand in your second post, I'm pretty sure all you need to do is add a second set of empty brackets at the end of the line.

D.

Edited by Diazo
Link to comment
Share on other sites

On 7/2/2016 at 0:24 AM, wasml said:

Try this - quick test looks like it works

Thank you both! Having solid code examples works wonders for me. However it probably shows how new I am at this whole coding thing that this suggestion:

On 7/2/2016 at 7:36 PM, Diazo said:

On the error you don't understand in your second post, I'm pretty sure all you need to do is add a second set of empty brackets at the end of the line.

was actually all I needed. :) Adding those parenthesis at the end not only cleared up the compile error, but now triggers all the experiments!

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