Jump to content

The official unoffical "help a fellow plugin developer" thread


Recommended Posts

Is there a way to check if there is a CommNet path between two vessels that are not necessarily connected to Home, and get the total distance and signal strength? I can't find anything of use here in the CommNet classes and I wouldn't know how to make this myself.

Edit: seems like asking this improved my chances of finding the right thing, because I think

override void CommNet.CommNetwork.CreateShortestPathTree(CommNode start, CommNode end) 	

or

override bool FindPath(CommNode start, CommPath path, CommNode end)

might be what I was looking for, though I don't understand how to use these (getting a path from a pathtree that is not returned? find the best path when I don't have a path? findpath returns bool instead of path?)

Edited by ExtremeTrader
Link to comment
Share on other sites

1 hour ago, ExtremeTrader said:

find the best path when I don't have a path?

CreateShortestPathTree is protected, I don't think you're supposed to use it the way you're probably imagining.

 

1 hour ago, ExtremeTrader said:

findpath returns bool instead of path

FindPath's bool return value is probably a success/failure flag, for instance there may not be any path between the given start and end nodes.

The path param probably behaves like an out or ref param.

Try something like this? (Note: purely speculative from reading API and not actually tested)

CommNode start = vessel1.Connection.Comm;
CommNode end = vessel2.Connection.Comm;
CommPath path = null; // may need to instantiate if this causes null reference exceptions

CommNetwork network = CommNetNetwork.Instance.CommNet;
// not sure if needed, seems like a good precaution:
if (network.IsDirty)
    network.Rebuild();

if (!network.FindPath(start, path, end))
{
    // did not find a path
    Debug.Log($"Failed to find a path between {vessel1.vesselName} and {vessel2.vesselName}")
    // ...
}
else
{
    // do things with path, like
    Debug.Log($"Signal strength between {vessel1.vesselName} and {vessel2.vesselName} is {path.signalStrength}");
}

 

hth

Link to comment
Share on other sites

1 hour ago, cakepie said:

FindPath's bool return value is probably a success/failure flag, for instance there may not be any path between the given start and end nodes.

The path param probably behaves like an out or ref param.

That does make sense, but it's not set as out or ref or even optional (https://kerbalspaceprogram.com/api/class_comm_net_1_1_comm_network.html#ab3c35970caed4e281ded1612770acdfe).

When I try to use CommNetwork as a type visual studio mostly flips out and breaks control loops for some reason (edit: your code doesn't give errors however, not sure what happened).

 

edit 2: threw your code in a method and found this in the log:

[ERR 16:35:03.203] Module ResourceTransceiver threw during OnUpdate: System.NullReferenceException: Object reference not set to an instance of an object
  at CommNet.CommNetwork.FindPath (CommNet.CommNode start, CommNet.CommPath path, CommNet.CommNode end) [0x00000] in <filename unknown>:0 
  at ResourceBeamer.ResourceHandler.somemethod (.Vessel vessel1, .Vessel vessel2) [0x00000] in <filename unknown>:0 
  at ResourceBeamer.ResourceTransceiver.OnUpdate () [0x00000] in <filename unknown>:0 
  at Part.ModulesOnUpdate () [0x00000] in <filename unknown>:0 

I'm pretty sure that's a nullref about the path being null, I don't know how to get a path though

Edited by ExtremeTrader
Link to comment
Share on other sites

  • 2 weeks later...
On 6/12/2019 at 8:01 PM, JPGSP said:

Hi, is there a way that I can make every monoprop that uses monopropellant use another monoprop gas(I have real fuels and RO+RSS, and quite an amount of my monoprop from mods use monopropellant)?

You can do this using ModuleManager (you already have it installed if you have RO+RSS). If you want to edit engines you can make a new .cfg in your gamedata folder and use this (I haven't tested it):

@MODULE[ModuleEngines]
{
    @PROPELLANT[MonoPropellant]
    {
        @name = otherMonopropGas
    }
}

for RCS, something like this should work:

@MODULE[ModuleRCSFX]
{
    @resourceName = otherMonopropGas
}

Of course, you need to make sure that your otherMonopropGas is actually defined in a resourcedefinition cfg somewhere, but if you change it to one of the real fuels resources you don't need to think about that.

I suggest that you practice writing MM patches, they can be very useful. Some syntax explanation can be found here: https://github.com/sarbian/ModuleManager/wiki/Module-Manager-Syntax

Link to comment
Share on other sites

  • 3 weeks later...

I came to realize that using GameDatabase.Instance.GetConfigNode(Part.partInfo.partUrl) is a very handy way to get exactly what the ConfigNode of a part is in memory.

But it happens that spaces on the partUrl make it borks. I can inspect any part on the GameDatabase using the partUrl, except by the ones using spaces somewhere on the URL.

There's a workaround for this, as replacing "_" by "." on the partNames?

Link to comment
Share on other sites

14 hours ago, Lisias said:

I came to realize that using GameDatabase.Instance.GetConfigNode(Part.partInfo.partUrl) is a very handy way to get exactly what the ConfigNode of a part is in memory.

But it happens that spaces on the partUrl make it borks. I can inspect any part on the GameDatabase using the partUrl, except by the ones using spaces somewhere on the URL.

There's a workaround for this, as replacing "_" by "." on the partNames?

Try Part.partInfo.partConfig, turns out KSP saves it directly.

Link to comment
Share on other sites

  • 1 month later...
On 5/25/2019 at 5:59 AM, ExtremeTrader said:

Is there a way to check if there is a CommNet path between two vessels that are not necessarily connected to Home, and get the total distance and signal strength? I can't find anything of use here in the CommNet classes and I wouldn't know how to make this myself.

Edit: seems like asking this improved my chances of finding the right thing, because I think


override void CommNet.CommNetwork.CreateShortestPathTree(CommNode start, CommNode end) 	

or


override bool FindPath(CommNode start, CommPath path, CommNode end)

might be what I was looking for, though I don't understand how to use these (getting a path from a pathtree that is not returned? find the best path when I don't have a path? findpath returns bool instead of path?)

Did you end up figuring this out? I'm also trying to see if a path exists between two vessels that aren't connected to home. In the map view in game it is possible to see this, so I would expect that each vessel should know what other vessels it is currently connected to, but from the docs, it seems like this information is never stored anywhere...since I guess it gets recalculated every frame.

Maybe you could use 

TryConnect (CommNode a, CommNode b, double distance, bool aCanRelay, bool bCanRelay, bool bothRelay)

 

Edited by subyng
Link to comment
Share on other sites

Can anybody tell me how to change one of the strategies to change its values? I could probably do it directly in the game files, but I want to make it available for other people as a plugin and learn a bit of coding along the way.

Edit: OK, done. This was easier than I expected.

Edited by Wjolcz
Link to comment
Share on other sites

New problem: I created a resources exchanger (just like the Research Rights Sell-Out), but I get some silly values. I wanted to buy science with funds, but the problem is science is now super cheap and it takes a % from what I have. I want the prices to be constant. For example, when I set the slider to 1% it buys me 1 science for 1000 funds. Either that or I need somebody to explain me how the minShare, maxShare, minRate, maxRate values work.

Btw, can I somehow refresh/reload the game once it's launched or do I need to restart it each time I change something in the mod?

EDIT: I DID IT! Now all I need to know is how to change the name of the strategy.

Edited by Wjolcz
Link to comment
Share on other sites

  • 2 weeks later...
On 8/20/2019 at 3:46 AM, maja said:

Hi, is it possible to get settings from cheat console? Mainly infinite fuel and electricity. If yes, how?

Yes. Very easy. See this line of the KSPIE codebase: https://github.com/sswelm/KSP-Interstellar-Extended/blob/b8db46d5464f6967824ef614ea383808e63340ad/FNPlugin/Wasteheat/FNRadiator.cs#L880 for an easy example.

Link to comment
Share on other sites

3 hours ago, maja said:

:0.0: I was tired when I searched the right class. Definitelly. Big thanks :)

No worries. Get some sleep ;)

The online documentation is pretty bad for these APIs. I just happened to know exactly where some examples querying the cheat menu were from some recent reading and documenting. Some silly levels of effort (trivial obfuscation) and rules (forum gag rules) have been erected to make the interfaces harder to use...

Link to comment
Share on other sites

two things:

am working on learning the Unity UI while updating a mod and creating another. Thankfully both are fairly lite mods.

making the UI is easy, it is learning how to use the eventsystem and/or do things with the UI in game.

I want to use the Unity UI event system because it should be overall better vs. writting the code to do the same in game.

Examples am having issues with:

  • using an existing button (btnClose) on a panel on a canvas in a gameobject to close the window(panel)
  • using an existing button (btnMin) on a panel on a convas in a gameobject to minimize the window(panel) to just its title area
  • add drag/resize handles and the related eventhandlers
  • can save/load position be handled in unity? (code is simple and already have, just thought would ask)
  • add dock to screen edge behaviour

have used the very helpful "The Lazy Coder's Guide to KSP UI Design - a tutorial" post by @Fengist (thank you) - and now want to add code to close window when click on window's btnClose (s.i.c. code)

Spoiler

            // Find the game object that is named btnClose
            GameObject button = (GameObject)GameObject.Find("btnClose");
            Button thisButton = button.GetComponent<Button>();
            thisButton.onClick.AddListener(delegate { onCloseClicked(); });

      // this is the event handler for btnClose
        static void onCloseClicked()
        {
            if (CoolUICanvas != null)
            {
                Destroy();
            }
        }

thank you in advance for any help/insight ! +++ 10:rep:50:science: !

Edited by zer0Kerbal
Link to comment
Share on other sites

  • 1 month later...

When you press the F4 key it toggles vessel icons on/off; does anyone know what the specific call for that is? Looking through the API I've found references to it - GameSettings keybind TOGGLE_LABELS and and the VesselLabels class for the icons proper, but not the GameEvent or similar that handles it; I'm trying to see if it's possible to toggle the vessel icons via code rather than manual keypress, is this possible?

Link to comment
Share on other sites

21 hours ago, SuicidalInsanity said:

When you press the F4 key it toggles vessel icons on/off; does anyone know what the specific call for that is? Looking through the API I've found references to it - GameSettings keybind TOGGLE_LABELS and and the VesselLabels class for the icons proper, but not the GameEvent or similar that handles it; I'm trying to see if it's possible to toggle the vessel icons via code rather than manual keypress, is this possible?

This might be what you are looking for

                KSP.UI.Screens.VesselIconSprite.Destroy();
                KSP.UI.Screens.VesselIconSprite.Instantiate();

It appears that you will have to destroy the gameobject and then re-instantiate it afterwards if you want it to show up again ... plug the above lines into VS and hover your mouse over it, VS will show you the parameters that each require inside of the brackets (name and vector3 for the instantiate and the unity gameobject in the case of destroying it)

Link to comment
Share on other sites

How can I read the persistentId of the vessel in the Editor? I tried using ShipConstruction.LoadShip().persistentId, but it causes terrible glitches (basically, the vessel on the screen is duplicated for every call of this method).

Also, will this persistentId be the same for the ship when it is launched?

Link to comment
Share on other sites

3 hours ago, garwel said:

How can I read the persistentId of the vessel in the Editor? I tried using ShipConstruction.LoadShip().persistentId, but it causes terrible glitches (basically, the vessel on the screen is duplicated for every call of this method).

Also, will this persistentId be the same for the ship when it is launched?

Persistant Vessel ID is for the flight scene and is generated when the craft is launched

Trying to get it in the editor is a lost cause since the vessel needs to be loaded into the flight scene to be assigned a persistant ID 

Take a look at a .craft file, there is no persistant ID ... take a look at a vessel in a .sfs, there is a persistant ID

I ran into something similar with coding the geo-caching of vessels within a 1km radius of the active vessel ... I had to strip a bunch of values out of the saved craft files (saved to craft file in flight scene) in order to be able to spawn them properly when a user gets close to the geo-cache 

The parts on a vessel however will have an ID number after the 'name' value in the craft file, this is generated when a part is added to a craft I believe 

TL;DR - A vessel/craft will not have a persistant ID given to it until it is launched, the editor doesn't know what to do with it ... whereas each part in a craft will have a persistant ID IIRC

I could be wrong though ... I'm just a hack :confused:

Edited by DoctorDavinci
Link to comment
Share on other sites

23 minutes ago, DoctorDavinci said:

Persistant Vessel ID is for the flight scene and is generated when the craft is launched

Trying to get it in the editor is a lost cause since the vessel needs to be loaded into the flight scene to be assigned a persistant ID 

Take a look at a .craft file, there is no persistant ID ... take a look at a vessel in a .sfs, there is a persistant ID

I ran into something similar with coding the geo-caching of vessels within a 1km radius of the active vessel ... I had to strip a bunch of values out of the saved craft files (saved to craft file in flight scene) in order to be able to spawn them properly when a user gets close to the geo-cache 

The parts on a vessel however will have an ID number after the 'name' value in the craft file, this is generated when a part is added to a craft I believe 

TL;DR - A vessel/craft will not have a persistant ID given to it until it is launched, the editor doesn't know what to do with it ... whereas each part in a craft will have a persistant ID IIRC

I could be wrong though ... I'm just a hack :confused:

Thanks, but it is bad news. I need to somehow associate the vessel in the Editor with its launched version.

If the part persistentId is available both in the editor and in-flight, I guess I could use the root part... Or I can try to make some sort of a hash function that takes all parts into account and will be the same for identical vessels (which suits my needs just fine).

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