Jump to content

How to find partcount of type on current vessel


Recommended Posts

Hello, and welcome to the forum!  :)

8 hours ago, CWhizard said:

So I need to find out if there is a science lab on board the ship.  How can I do this?

There are a couple of different ways, depending on what exactly you want to do.  Which of the following is the case?

  1. You want to know, specifically, whether there are any instances of the MPL-LG-2 Mobile Processing Lab on the ship.
  2. You want to know how many science labs in general there are on the ship-- i.e. how many parts that can do the same thing that the MPL can.

In the stock game, the above two questions end up having the same answer, because there is only one part in the stock game that can do what the MPL does, and that's the MPL.  :)  But if the player is using a modded game, they may be running a mod that introduces additional modded parts that have that same functionality, so the question is, do you want to count such parts too, or not?

Both of these things are doable in a fairly straightforward fashion; it's just a question of which way you want to code it.

Let's take them one by one.

Find out specifically how many instances of the MPL there are on the ship:

  1. Get the Vessel object you want to examine (e.g. via PartModule.vessel property if you're in the code for your PartModule, or via FlightGlobals.ActiveVessel if you're in a MonoBehaviour script).
  2. The vessel has a parts property, which is of type List<Part>.
  3. Iterate through that list.  (Use a for loop with index, not a foreach loop, as the latter will spam your GC).
  4. As you examine each Part object in the parts list, check its partName property.  If the partName equals "Large_Crewed_Lab", then you've found one!  Increment your count, or whatever.

Find out how many instances of parts that can function as science labs there are on the ship:

Exactly like the above, for steps 1 through 3.  However, in step 4, instead what you do is the following for the part:

  1. get the part's Modules property, which is of type PartModuleList.
  2. Iterate through the list (again, use a numbered index, not foreach).
  3. For each PartModule that you find, then check if (module is ModuleScienceConverter)
  4. If that evaluates to true, you've found a science-lab type of part.  Increment your part count, stop iterating through the modules, and move on to the next part.

 

Does this answer your question?

Link to comment
Share on other sites

On 03/04/2018 at 6:04 PM, Snark said:

Find out how many instances of parts that can function as science labs there are on the ship:

Much easier for that one to just do vessel.FindPartModulesImplementing<ModuleScienceConverter>().Count()

Note that this won't find modules on unloaded vessels. There is a method in FinePrint.Utilities.VesselUtilities to do this, but I'm on my phone right now so can't remember exactly what it's called.

Edit : actually I think the fineprint vessel utilities might have a method for getting counts of specific parts too.

Edited by severedsolo
Link to comment
Share on other sites

5 hours ago, severedsolo said:

Much easier for that one to just do vessel.FindPartModulesImplementing<ModuleScienceConverter>().Count()

Depends on what you want to do.  I see three potential drawbacks to using vessel.FindPartModulesImplementing:

  • Algorithmic performance.  FindPartModulesImplementing will scan every module of every part on the vessel, regardless.  Depending on what one wants to do, this may be very computationally wasteful.  For example, if all you want to know is are there any labs rather than how many there are... the algorithm I suggested would allow the code to break out of the loop as soon as it finds the first one, thus short-circuiting evaluation of the rest of the vessel.
  • Correctness.  FindPartModulesImplementing will, I expect, give a correct answer to "how many labs are there" in most cases.  But it's not actually guaranteed to be correct, because it's counting modules, not parts.  In principle, it's  possible for a part to have more than one ModuleScienceConverter on it, and if so, it would get counted multiple times.
  • Heap allocation.  This one's the whopper.  FindPartModulesImplementing is going to allocate a List<>, which is of necessity on the heap, which means it's going to need to get garbage-collected.  This is no big deal if the code's not getting called very frequently, but we don't know anything yet about the context in which the OP wants to call this logic.  If it happens fairly frequently, then this is going to cause GC churn, which could have a deleterious effect on performance.

Yes, it's simpler to call vessel.FindPartModulesImplementing.  It means you only need to write one line of code instead of about half-a-dozen.

But it also means you're going to do a full scan of every single module of every single part in the vessel, every time, and that you're going to be creating heap objects every time; and if there happen to be multiple labs on the vessel, it's going to do multiple heap allocations (potentitally O(N2), but hopefully O(NlogN) assuming List<> is implemented intelligently), because each one it finds it's going to need to append to the list, which requires growing the list, which leads to reallocations.

So, which approach is "better" is going to depend a lot on which tradeoffs are the most relevant to the particular circumstances in which the logic is getting called, which in turn would depend on why the OP needs to know this information and what he'll be doing with it.

Link to comment
Share on other sites

@Snark - I owe you an apology :D I didn't read your post properly the first time - specifically I misread step 4 of the last bit, where you move on to the next part after finding the module. In my head, I was thinking "well that's just what FindPartModulesImplemening does" - but of course it doesn't, because you aren't counting every module.

TL:DR - I should not reply to posts on my mobile while I'm at work.

Oh but I will say (just to try and save a little face :P) obviously I would not use FindPartModulesImplementing if I just wanted to know "does this vessel have a lab"  - I'd probably do it your way or (because I'm lazy and hate writing for loops) use FindPartModuleImplementing<>() (the singular one) - I imagine that probably does a for loop and returns as soon as it finds one anyway.

 

Link to comment
Share on other sites

Well the intention is to modify the behavior of For Science so that on vessels including a science lab, it will gather zero science value experiments for use in the lab, which uses the data value not the remaining science value.  So, for this specific case,  I am looking at Is the There A Lab On Board.  i don't need to know how many there are or how many modules total, just if there is at least one.  But I do appreciate your explanation of the other methods which may come in handy for other projects.

Now, in meantime since posting this I have shifted to just looking for a scientist on board.  Since I develop on the base game (+ FS and Mechjeb) I assume a lab based ship or station will have a scientist on board.  And if not too bad so sad you lose out on the opportunity to gather that experiment.  

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