Jump to content

The official unoffical "help a fellow plugin developer" thread


Recommended Posts

8 minutes ago, sarbian said:

OnLoad is the proper time. Module are started in the loading screen and your code should check if it is actually attached to a vessel before doing anything that night break (also helps for the editor).

Well, I managed to modify stuff so that OnLoad works for populating GetInfo. But now I have a different problem. I load the sub-nodes into a List in the OnLoad method. But that list is empty when I actually use the part in the editor. It looks like OnLoad isn't called when the module is instantiated.

Link to comment
Share on other sites

15 minutes ago, garwel said:

Well, I managed to modify stuff so that OnLoad works for populating GetInfo. But now I have a different problem. I load the sub-nodes into a List in the OnLoad method. But that list is empty when I actually use the part in the editor. It looks like OnLoad isn't called when the module is instantiated.

You probably want to read this for some background

Now, the problem you're running into with the value of that field disappearing is Unity serialization - when the part prefab is instantiated your field isn't copied over.  I should really do a post about this some time.  There aren't really any simple general-purpose solutions, just annoying workarounds.  Here's one.

2 minutes ago, garwel said:

Um... Tripleposted... Now, how do I delete a post?

Report your own post and a moderator will remove it.

Link to comment
Share on other sites

Thanks for clearing it up @blowfish. I was afraid there is something more to it than just me not using the proper methods or attributes, and it seems to be true. I guess this is why we have mods like B9 Part Switch that do stuff, which should've been trivial. In my case, I guess I'll do without the custom sub-nodes, though it won't be as neat.

Link to comment
Share on other sites

  • 3 weeks later...

I'm looking to retrieve all science data upon recovery of vessel/transmission of science and then get info as to what CelestialBody the science came from. I'm thinking I can accomplish this using "OnScienceRecieved" or "onVesselRecoveryRequested/OnVesselRecoveryProcessing", but I'm not sure how to extract those parameters. Can anyone give me any advice?

EDIT: I figured it out. Here's the code in case anyone else needs.

		private void Start()
        {
            GameEvents.OnScienceRecieved.Add(ScienceProcessingCallback);
        }

        private void OnDestroy()
        {
            GameEvents.OnScienceRecieved.Remove(ScienceProcessingCallback);
        }

        void ScienceProcessingCallback(float sciValue, ScienceSubject sub, ProtoVessel pv, bool test)
        {
            Debug.Log("Science Data: " + sub.title);
            Debug.Log("Science Value: " + sub.science);
			if (celestialBodyName in sub.title)
			{
				//code here
			}
        }

 

EDIT2: Second question: How can I retrieve data from ConfigNode? Here's what I have so far:

public override void OnSave(ConfigNode node)
{
	string oldValue = 0.ToString();
    key = name;
    if (node.Contains(key))
    {
    	value = node.GetValue(key);
        oldValue = float.Parse(value);
        newValue = oldValue + addedValue;
        node.SetValue(key, newValue);
        addedValue = 0;
    }
    else
    {
        node.AddValue(key, addedValue);
    }

Using debugging, it doesn't get past the "if node.Contains(key)" , but if I don't use the if statement, then it crashes at the "GetValue(key)" code. I've been looking at other people's code and looking for online tutorials, but there always seems to be something missing, either in their example or in my brain.

Edited by Codapop
Link to comment
Share on other sites

  • 1 month later...

Hi. Hoping someone can help.  Am new to KSP/Unity/C#, but a full time programmer elsewhere.

  1. Does a KSP plugin have access to the data in the Archives tab of the R&D building? The science history data specifically. I combed over the docs for the Game object, no luck. Tried to come up with creative guesses for elsewhere, but here I am.
  2. What is the correct name for this contruct so I can investigate further:   [KSPAddon(KSPAddon.Startup.SpaceCentre, false)]

Thank you!

Link to comment
Share on other sites

13 minutes ago, OrbitalManeuvers said:
  1. Does a KSP plugin have access to the data in the Archives tab of the R&D building? The science history data specifically. I combed over the docs for the Game object, no luck. Tried to come up with creative guesses for elsewhere, but here I am.

Usually the easiest way to answer a question like this is to find a mod that already does it and then check the source to see how. I think ForScience accesses that data, possibly here?

13 minutes ago, OrbitalManeuvers said:
  1. What is the correct name for this contruct so I can investigate further:   [KSPAddon(KSPAddon.Startup.SpaceCentre, false)]

Those are C# attributes; they allow the compiler to associate additional metadata with a class or function, that can later be queried by other code. KSP uses the one you quoted to find classes that should be treated as entry points for mods.

Link to comment
Share on other sites

Noob questions. Brand new to C#. I can already tell it's gonna be the "paperwork" (scaffolding/config/options) stuff that's going to kill me long before the actual coding part. Anyway, here's my situation...

My DLL gets found by KSP but generates this: Could not load file or assembly 'netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies.

My observation is that when I load other people's projects, VS shows a bold solution node, and under there is always a child node called References, and under there are all the referenced assemblies. But, when I start a new VS project and pick Class Library (.NET Standard) I get a bold solution node, under which there is Dependencies, with children of Assemblies and SDK (no References node anywhere). Under SDK is a node referencing NetStandard.Library (2.0.3). Doesn't seem to be a way to delete this node or make my explorer look like other people's mods, so I must be doing something basic wrong.

Is this a wrong project type? Or ... ?

 

Link to comment
Share on other sites

3 minutes ago, OrbitalManeuvers said:

Could not load file or assembly 'netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies.

But, when I start a new VS project and pick Class Library (.NET Standard)

I don't know what it looks like in Visual Studio, but you need to target .NET Framework, not ".NET Standard", which is a newer thing that Microsoft made up to confuse us. It might be worth comparing csproj files in a text editor.

Link to comment
Share on other sites

13 hours ago, OrbitalManeuvers said:

Noob questions. Brand new to C#. I can already tell it's gonna be the "paperwork" (scaffolding/config/options) stuff that's going to kill me long before the actual coding part. Anyway, here's my situation...

My DLL gets found by KSP but generates this: Could not load file or assembly 'netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies.

My observation is that when I load other people's projects, VS shows a bold solution node, and under there is always a child node called References, and under there are all the referenced assemblies. But, when I start a new VS project and pick Class Library (.NET Standard) I get a bold solution node, under which there is Dependencies, with children of Assemblies and SDK (no References node anywhere). Under SDK is a node referencing NetStandard.Library (2.0.3). Doesn't seem to be a way to delete this node or make my explorer look like other people's mods, so I must be doing something basic wrong.

Is this a wrong project type? Or ... ?

 

This article may help:
https://code-maze.com/differences-between-net-framework-net-core-and-net-standard/

 

Link to comment
Share on other sites

  • 3 weeks later...
1 hour ago, cukkoo said:

So height mean height from terrain and altitude mean from sea level

I'm not sure what you're trying to say, but if you're searching for the altitude  above sea level than @peteletroll is right:

1 hour ago, peteletroll said:

I'd say Vessel.altitude.

If you're looking for the altitude above ground then you're probably looking for something like this:

double altitudeAboveTerrain = vessel.altitude - vessel.pqsAltitude;

(vessel.pqsAltitude returns the height of the terrain below the current vessel position)

Link to comment
Share on other sites

Question. How do I get the prerequisite nodes of an RDTech? (found it, RDTech wasn't what I needed) I have two calculated values in a PartModule; how do I display them on the part's info window in the VAB/SPH? Not the PAW menu, the part properties window when you mouse over the part in the part list.

 

For context, I'm trying to put together my first plugin, consisting of a small piece of code that would display in the VAB each part's tech node and research cost so that the player doesn't need to Alt+Tab/use a second monitor to consult with a tech tree while building a vessel. I have the name of the node and the recursively calculated research cost, I just need to display them.

Edited by Fraktal
Link to comment
Share on other sites

Anyone here have experience with the Breaking Ground robotic servo PartModules? I'm trying to find the rotation axis (both direction and location) so I can predict the motion of its child parts. In the API I see

ConfigurableJoint servoJoint

but it's a protected attribute and so I won't be able to access it without sketchy reflection calls. Next would be 'servoTransformName', 'jointParentName', or 'baseTransformName' and 'mainAxis'. These seem promising, but I'm just wondering if anyone has any experience they could share before I dive down the rabbit hole.

Thanks!

Link to comment
Share on other sites

On 12/9/2020 at 3:09 PM, Fraktal said:

Question. How do I get the prerequisite nodes of an RDTech? (found it, RDTech wasn't what I needed) I have two calculated values in a PartModule; how do I display them on the part's info window in the VAB/SPH? Not the PAW menu, the part properties window when you mouse over the part in the part list.

 

For context, I'm trying to put together my first plugin, consisting of a small piece of code that would display in the VAB each part's tech node and research cost so that the player doesn't need to Alt+Tab/use a second monitor to consult with a tech tree while building a vessel. I have the name of the node and the recursively calculated research cost, I just need to display them.

 

If I get it right, then you must override GetInfo in your PartModule class.

Spoiler

/// <summary>
        /// Return info about module
        /// </summary>
        /// <returns>Module info</returns>
        public override string GetInfo()
        {
            string info = "<color=#B7FE00><b>Bon Voyage Controller</b></color>";

            switch (techLevel)
            {
                case 2:
                    info += "\n\n" + Localizer.Format("#LOC_BV_Part_Description_v2");
                    break;
                case 3:
                    info += "\n\n" + Localizer.Format("#LOC_BV_Part_Description_v3");
                    break;
                case 4:
                    info += "\n\n" + Localizer.Format("#LOC_BV_Part_Description_v4");
                    break;
            }

            return info;
        }

 

 

Link to comment
Share on other sites

  • 2 weeks later...

Does anyone know how to make a simple counter using config nodes? I've been working at this project for ages and can't seem to figure it out.

 

[KSPAddon(KSPAddon.Startup.FlightAndKSC, false)]

    public class TestCounter : MonoBehaviour
    {
        void SaveTest(ConfigNode node)
        {
            bool flag = node.HasNode("TEST-NODE");
            if (!flag)
            {
                node.AddNode("TEST-NODE");
                ConfigNode node2 = node.GetNode("TEST-NODE");
                node2.AddValue("VALUE", number);
                Debug.Log("[--------TEST--------]: Save " + number);
            }
            else
            {
                ConfigNode node2 = node.GetNode("TEST-NODE");
                node2.SetValue("VALUE", 5);
                Debug.Log("[--------TEST--------]: Save 5");
            }
        }

        void LoadTest(ConfigNode node)
        {
            ConfigNode node2 = node.GetNode("TEST-NODE");
            int test = int.Parse(node2.GetValue("VALUE"));
            Debug.Log("[--------TEST--------]: Load " + test);
            number = number + 1;
        }

        private void Start()
        {
            GameEvents.onGameStateSave.Add(SaveTest);
            GameEvents.onGameStateLoad.Add(LoadTest);
        }

        private void OnDestroy()
        {
            GameEvents.onGameStateSave.Remove(SaveTest);
            GameEvents.onGameStateSave.Remove(LoadTest);
        }

        public int number = 0;

    }

No matter what I do the config file only ever says 0 for the value. It creates the config node and the value, but I can't find a way to get it to update.

EDIT: Found the answer! I was using KSPAddon rather than Scenario. Config nodes don't work very nicely without scenario modules.

Edited by Codapop
Found answer to question.
Link to comment
Share on other sites

What might I need to know to change the text on a button that is part of stock KSP? Looking through the code using dnspy doesn't reveal anything obvious, and I can't think of any mods that do something similar enough that I can look at the source for inspiration.

Link to comment
Share on other sites

Is 'dVActual' and 'TWRActual' accesable through 'FlightGlobals.ActiveVessel'? I can't seem to find it.

Edit: found it by doing the following:

int currentStage = FlightGlobals.ActiveVessel.currentStage;
return FlightGlobals.ActiveVessel.VesselDeltaV.GetStage(currentStage);

 

Edited by Albert VDS
Link to comment
Share on other sites

How can I get a UI to show up in the RnD facility? I've copied this tutorial exactly and have managed to create the UI panel and get it to appear using a part module. However, despite everything loading properly (or so I think, using debug logging), nothing shows up when I attempt to modify the code for showing up in RnD. Here's what I'm using from the tutorial, stripped down to be as simple as possible:

using System.Collections.Generic;
using System.IO;
using System.Reflection;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

namespace TestAddon
{
    [KSPAddon(KSPAddon.Startup.Instantly, true)]
    public class CoolUILoader : MonoBehaviour
    {
        private static GameObject panelPrefab;

        public static GameObject PanelPrefab
        {
            get { return panelPrefab; }
        }

        private void Awake()
        {
            AssetBundle prefabs = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "mycoolui.dat"));
            panelPrefab = prefabs.LoadAsset("MyCoolUIPanel") as GameObject;
        }
    }

    [KSPAddon(KSPAddon.Startup.FlightEditorAndKSC, true)]
    public class CoolUI : MonoBehaviour
    {
        public static GameObject CoolUICanvas = null;
        public static GameObject CoolUIText = null;

        public static void Destroy()
        {
            CoolUICanvas.DestroyGameObject();
            CoolUICanvas = null;
        }

        public static void ShowGUI()
        {
            if (CoolUICanvas != null)
                return;

            CoolUICanvas = (GameObject)Instantiate(CoolUILoader.PanelPrefab);
            CoolUICanvas.transform.SetParent(MainCanvasUtil.MainCanvas.transform);
            CoolUICanvas.AddComponent<CoolUI>();

            CoolUIText = (GameObject)GameObject.Find("ImportantText");
            GameObject checkToggle = (GameObject)GameObject.Find("CheckThisOUt");
        }
    }
}

 

And here is the addon that should show the UI. Again, I know it "works" and the functions call at the right times (via debug logging), but the UI does not appear.

using UnityEngine;

namespace TestAddon
{
    [KSPAddon(KSPAddon.Startup.AllGameScenes, false)]

    public class RnDButton : MonoBehaviour
    {
        private void Start()
        {
            GameEvents.onGUIRnDComplexSpawn.Add(SpawnButton);
            GameEvents.onGUIRnDComplexDespawn.Add(HideButton);
        }

        private void OnDestroy()
        {
            GameEvents.onGUIRnDComplexSpawn.Remove(SpawnButton);
            GameEvents.onGUIRnDComplexDespawn.Remove(HideButton);
        }

        private void SpawnButton()
        {
            CoolUI.ShowGUI();
        }

        private void HideButton()
        {
            CoolUI.Destroy();
        }
    }
}

 

I'm pretty stumped at this point, not sure where to go from here. Any help would be greatly appreciated.

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