Jump to content

The official unoffical "help a fellow plugin developer" thread


Recommended Posts

1 hour ago, royying said:

I want to know how to detect what DLC is installed

To check a specific expansion you’ll want the ExpansionsLoader static method IsExpansionInstalled.

Expansions.ExpansionsLoader.IsExpansionInstalled(string name)

The string to check is the same as the folder name in GameData/SquadExpansions. “MakingHistory” and “Serenity” (Breaking Ground). 

There are similar methods under that same class to check if any expansions are installed or to check a list if you need more than one. 

Link to comment
Share on other sites

5 hours ago, royying said:

quickly reload a dll file for testing

Not really possible in general, I've seen some half baked attempts at this but they all mess up under some circumstances, the fundamental problem is that there may be instances of objects from the old DLL still present, and there's no way to guarantee that they can be converted to new objects.

I recommend creating a minimal test install so that the reloads are less time consuming.  You might even consider removing some parts of GameData/Squad if you want really fast startup.

Link to comment
Share on other sites

Vessel.patchedConicSolver is a PatchedConicSolver, the patches property of which is a list of 150 Orbit objects reflecting the vessel's current orbit, as well as any future SOI transitions it will make on its current trajectory. The "real" orbits are at the start of the list, and most of the subsequent objects just have all their internal pointers set to null (presumably this was done for performance, to avoid re-allocating the list).

Vessel.patchedConicRenderer is a PatchedConicRenderer, the patchRenders property of which is a list containing one PatchRendering object for each orbit in PatchedConicSolver.patches (including the nulled-out ones). The structure here is clear enough: the solver holds the data, the renderer draws it.

PatchedConicSolver.flightPlan is just like the patches property but for the hypothetical "dotted line" orbits generated by maneuver nodes. Orbits are added to and removed from this list as you create and delete maneuver nodes.

PatchedConicRenderer.flightPlanRenders looks like it would be parallel to the patchRenders property, with objects for drawing the orbits in the flight plan, but here the symmetry breaks down; it's always empty.

Does anybody know where the objects to render flight plans live?

EDIT: Maybe these are leftover cruft from a previous design? Continuing to expore the API, I see Orbit.DrawOrbit, which might make an orbit rendering class unnecessary if it does what it says on the tin.

Edited by HebaruSan
Link to comment
Share on other sites

How can I work inertially in a rotating reference frame? Is there a sane way to convert between the rotating frame near a planet and the inertial frame above it? How do I even tell whether the present reference frame is inertial or rotating?

For context: I'm trying to operate on things stored as orbital elements, and I want them to interact with worldspace in a sensible and consistent way. I'd like to keep it all inertial.

Link to comment
Share on other sites

  • 2 weeks later...

Is it possible to make it so the "Research" button in the RnD Facility doesn't work? Like if you press it, it doesn't spend the science and research the tech node?

Would anyone be able to point me in the right direction as to where I might find more about this in the API docs or in a mod that might do something similar?

Link to comment
Share on other sites

  • 3 weeks later...

I'm having trouble with my plugin's GetResource calls.  I have my part request liquid deuterium and antimatter while obeying flow priority, like liquid fuel and oxidizer.  I thought that this was working with the code I had been using, but it was draining from any part containing those resources on the vessel.  I started with the following code

this.vessel.RequestResource (this.part, antiMatID, (minAntiMatter * 2f) * TimeWarp.fixedDeltaTime, true)

I have also tried:

this.part.RequestResource(antiMatID, (minAntiMatter * 2d) * TimeWarp.fixedDeltaTime);

and

this.part.RequestResource(antiMatID, (minAntiMatter * 2d) * TimeWarp.fixedDeltaTime, ResourceFlowMode.STAGE_PRIORITY_FLOW);

No matter what I try the part always drains every part that contains the resource all at once.  I'm not sure what to do at this point, and I come seeking counsel from more experienced coders.

Edit:  I've done some more testing and it seems that all of the parts for my mod have a flow priority of -10, which I'm not sure how to change other than in the editor manually.  When the flow priority is changed the parts drain as expected.  Also, it seems that although the resources are being drained simultaneously it is draining proportionately from each tank.  So I am getting the desired performance (doubling the amount of resources gives double the time to drain all of the resources).  So, I guess this isn't really an issue, other than it looks strange (to me at least).

Edited by TheShadow1138
Link to comment
Share on other sites

  • 2 weeks later...

Hi - am still quite new to C# namespaces and assemblies. I stole this code from a popular working mod:

f7Wvj9Y.png

 

How am I getting a definition of Texture2D that doesn't contain .LoadImage() ? If it helps, the symbols that DO show up in this class are one like LoadRawTextureData and loadedMipmapLevel. Is there namespace precedence? The last "using" is UnityEngine, as as it is in the working mod's code.

Thanks for any pointers!

Link to comment
Share on other sites

12 minutes ago, OrbitalManeuvers said:

Hi - am still quite new to C# namespaces and assemblies. 

How am I getting a definition of Texture2D that doesn't contain .LoadImage() ? If it helps, the symbols that DO show up in this class are one like LoadRawTextureData and loadedMipmapLevel. Is there namespace precedence? The last "using" is UnityEngine, as as it is in the working mod's code.

You may have been tripped up by an extension method; in C# you can force the compiler to pretend that you've added a new method to somebody else's class:

I wasn't able to figure out which mod that code came from, but if you search the rest of its code, you might find a definition of LoadImage.

I take that back—extension methods are real and could produce this result, but in this case Texture2D.LoadImage in fact seems to be a standard method:

Could be a missing reference, I guess.

Edited by HebaruSan
Link to comment
Share on other sites

3 minutes ago, HebaruSan said:

You may have been tripped up by an extension method;

I believe you are exactly correct, though the definition doesn't exist in code. However, there's a reference to another mod by the same author and it's probably in there.

Seems everyone loads their icon images in different ways. Another example I have says:

private Texture buttontexture = GameDatabase.Instance.GetTexture(Icon_Inactive, false);

Where Icon_Inactive is a const that's a path to the file. Errm, maybe it's called a URL and not a path, as I've seen that term used in Unity, and there's no file extension on the const.

Link to comment
Share on other sites

9 minutes ago, OrbitalManeuvers said:

Seems everyone loads their icon images in different ways. Another example I have says:


private Texture buttontexture = GameDatabase.Instance.GetTexture(Icon_Inactive, false);

Where Icon_Inactive is a const that's a path to the file. Errm, maybe it's called a URL and not a path, as I've seen that term used in Unity, and there's no file extension on the const.

Yeah, I do basically the same thing:

public const string Name = "PlanningNode";

private static readonly Texture2D AppIcon = GameDatabase.Instance.GetTexture($"{Name}/Icons/{Name}", false);

This loads GameData/PlanningNode/Icons/PlanningNode.png. It's kind of nice because it relies on the game's code to do the loading for you.

Link to comment
Share on other sites

Hi. I'm trying to trigger the axis groups from code (Pitch, Yall, Rol ...). How can I do that?  I found the AxisGroupsModule.UpdateAxisGroup function, but I'm having a hard time undertanding where I can find this AxisGroupModulo object of the vessel. Any ideas? Thanks!

Edited by guigo
Link to comment
Share on other sites

4 minutes ago, OrbitalManeuvers said:

Ideally yes - any time you open it, it should be where you last left it in terms of the window contents. Essentially that's just two instance variables on my main class, one is a class one is an int.

Cool, if you make a class that inherits from ScenarioModule and sports a [KSPScenario] attribute, KSP will reserve part of the save file for your data and provide it to you pretty easily in ConfigNode format; here's my latest example:

Also, I wanted to suggest using standard KSP .cfg format files instead of INI format with a custom .checklist extension, since then you can just ask the game database for, say, all the "OMICHECKLIST" nodes to easily get them all as a ConfigNode structure, including ones added by the user or other mods (and those mods can even use ModuleManager patches to change your default ones). An example from WildBlueTools:

Edited by HebaruSan
Link to comment
Share on other sites

6 minutes ago, HebaruSan said:

here's my latest example:

I just saw that code this morning and wondered if that's where I need to head. Will look closely - thank you!

8 minutes ago, HebaruSan said:

Also, I wanted to suggest using standard KSP .cfg format files instead of INI format with a custom .checklist extension

An interesting idea from a coding standpoint. However it adds a big barrier to checklist creation. I really want the user to be able to type something out in Notepad while KSP is running, and just have it work. The [] "syntax" isn't even an error if you leave it out. Balanced braces and name/value pairs are not things I want the user to worry about.

Link to comment
Share on other sites

On 2/22/2021 at 2:23 PM, HebaruSan said:

here's my latest example

More big thanks, I really appreciate your help. I was able to get persistence working after seeing understanding what you're doing in PlanningNode. It took me a hot minute to realize that it's not the instance that survives, it's just that you can stream your state. 

My save/load ended up a tiny bit involved just because I'm trying to be as forgiving as possible about making changes to the checklist in an external editor between scene changes/saves.  It's pretty forgiving in terms of retaining checked items, balanced with not writing a boatload of data to the save.

Anyway, this is good :)  Not that the mod idea is so great (though I've been wanting this for a while) but that I was able, with some help from you and @ValiZockt, to go from idea to working code in-game ... which I had serious doubts about being able to do.  I still have miles to go in terms of C#. The ? has my head spinning but I threw it in there where I was confident enough :P . I'm thinking about converting the UI to a prefab next. I think all that's left to learn for that is how to connect to the controls in code, and also how to dynamically create a thing that goes into a listview. I figure that has to be more involved than it is with IMGUI. Plus the billions of other details that I know I don't have quite right yet. But progress has been made. 

 

Link to comment
Share on other sites

56 minutes ago, OrbitalManeuvers said:

But progress has been made. 

Congrats! It's quite an accomplishment to climb that technical hill all the way from zero to something that compiles and runs.

1 hour ago, OrbitalManeuvers said:

(though I've been wanting this for a while)

Aye, that's how it starts for most folks, I think. ;p

Link to comment
Share on other sites

  • 3 months later...

The mod Earn Your Stripes tracks how long each Kerbal has been in space, how many flights they've done etc, and it displays this (or at least part of this) information on the crew list in the Astronaut Complex screen -

unknown.png

I think I can see in the source code for the mod, that it does this by looking for the 'onGUIAstronautComplexSpawn' event, then it adds the info to the Kerbal names.

I've asked in the mod thread if this info could also be added to the crew selection screens in the SPH + VAB, but I also thought it'd be a good leaning experience if I gave it a go myself.

 

So, I was hoping you could help me by suggesting what I should be using to trigger the code when the crew selection panel is opened? Is there an equivalent to the 'onGUIAstronautComplexSpawn' event?

Link to comment
Share on other sites

13 minutes ago, WelshSteW said:

So, I was hoping you could help me by suggesting what I should be using to trigger the code when the crew selection panel is opened? Is there an equivalent to the 'onGUIAstronautComplexSpawn' event?

Maybe GameEvents.onEditorScreenChange, with parameter EditorScreen.Crew?

Link to comment
Share on other sites

So, you know how one thing leads to another.... :D

 

I've got the stuff appearing in the crew selection screen, BUT - depending on the values, it doesn't always fit.

 

Is there a way I can make the panel wider so there's more room for the text?

Link to comment
Share on other sites

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