Jump to content

The official unoffical "help a fellow plugin developer" thread


Recommended Posts

Is there something like a Time-Event? I need something to trigger one of my methods at a given time.

Can you be more specific about what you want to do?

Anyway, you could just wait for the universal time to wait for your wanted time and then do your logic. Or maybe you mean a repeated event?

Link to comment
Share on other sites

I have a Process which takes several Kerbindays to complete.

To check if the Process has finished I calculated the universal completion time but now I don't know if there is something like a GameEvent which could trigger at the given time or if I have to check on my own if the time has elapsed...

Link to comment
Share on other sites

A conversation in the KSPModding IRC has suggested that the generator is recreated by copying the prefab part with the same name as the protopart and then dropping the snapshot info on top of it, so there's the solution I guess.

Right now I'm trying to figure out whether a given PartModule in an unloaded vessel is enabled or not. As far as I can tell the enabled state is present in the ProtoPartModuleSnapshot in the confignode of persisted data - every module has an isEnabled value in there. The problem is figuring out which ProtoPartModuleSnapshot maps to which PartModule in the prefab part. There's no GUID or anything to go on, matching by type fails if there are two modules with the same type on the part (and it does matter - imagine a part with two ModuleGenerators that produce different resources, one enabled, one disabled). Anyone know how this works? Is the order the same in both lists, for example, in which case I can just step one by one?

Link to comment
Share on other sites

I have a Process which takes several Kerbindays to complete.

To check if the Process has finished I calculated the universal completion time but now I don't know if there is something like a GameEvent which could trigger at the given time or if I have to check on my own if the time has elapsed...

To my knowledge you'll have to write a repeating worker that checks the game UT at intervals. This is effectively the guts of a few of my mods and you can find examples of how to set up a repeating worker in them - I use the method regularly. In fact you could look at the pluginframework as well and use it.

Link to comment
Share on other sites

To my knowledge you'll have to write a repeating worker that checks the game UT at intervals. This is effectively the guts of a few of my mods and you can find examples of how to set up a repeating worker in them - I use the method regularly. In fact you could look at the pluginframework as well and use it.

Ok thanks, since I was doing this all in an ContractParameter-class I just used the OnUpdate()-method to check if the time has elapsed.

Link to comment
Share on other sites

Does Persistent work with Properties? I haven't used it in quite a while but think it only worked on fields. You might want to try this instead:

And Faark nailed it. Switching to fields works.

The other thing to try is change how the object is created.

ConfigNode.CreateConfigFromObject(new Pair<string, double>("a string", 1.0), testNode);

change to

testNode = ConfigNode.CreateConfigFromObject(new Pair<string, double>("a string", 1.0));

Note I have not used this function of ConfigNodes, but those suggestions are what my experience does suggest.

The second function is (or was, as of 0.23.5) pretty badly broken: http://forum.kerbalspaceprogram.com/threads/7544?p=1083531&viewfull=1#post1083531.

Link to comment
Share on other sites

Is my code correct? This is my first plug-in so I don't want to kill any bad habits before they have time to take hold. I've complied this, and it runs it just doesn't display the button. I also don't think that my GUI class is correct. I can post it if you would like.

using System;
using UnityEngine;
using KSP;
using System.Collections;
using System.Text;

namespace KXP
{
[KSPAddon(KSPAddon.Startup.EveryScene, false)]
public class DVbutton : MonoBehaviour
{
public void onAppLaunchToggleOn()
{
DvMapGUI.close = false;
}

public void onAppLaunchToggleOff()
{
DvMapGUI.close = true;
}

public void DummyVoid()
{
DvMapGUI.close = true;
}

public ApplicationLauncherButton dvMapButton = null;
void OnGUIAppLauncherReady()
{
while (ApplicationLauncher.Ready == true)
{
dvMapButton = ApplicationLauncher.Instance.AddModApplication (
onAppLaunchToggleOn,
onAppLaunchToggleOff,
DummyVoid,
DummyVoid,
DummyVoid,
DummyVoid,
ApplicationLauncher.AppScenes.ALWAYS,
(Texture)GameDatabase.Instance.GetTexture ("GameData/DvMap/textures/map_icon", false));
Debug.Log ("Working?");
}


}
public void FixedUpdate()
{


}
}
}

Link to comment
Share on other sites

This piece of code right here, for some reason, causes a System.TypeLoadException to where KSP won't even load the dll. Removing the line of code resolves the issue, adding it back in, recreates it. The code is currently in the default constructor of a custom camera object that inherits off of monobehavior.


skyboxRenderers = (from Renderer r in (FindObjectsOfType(typeof(Renderer)) as IEnumerable<Renderer>) where (r.name == "XP" || r.name == "XN" || r.name == "YP" || r.name == "YN" || r.name == "ZP" || r.name == "ZN") select r).ToArray<Renderer>();

Is there any idea as to why this code causes the dll to not even load? The code is being compile using Visual Studio 2013 Ultimate, if that makes a difference (I don't think it does).

Link to comment
Share on other sites

This piece of code right here, for some reason, causes a System.TypeLoadException to where KSP won't even load the dll. Removing the line of code resolves the issue, adding it back in, recreates it. The code is currently in the default constructor of a custom camera object that inherits off of monobehavior.


skyboxRenderers = (from Renderer r in (FindObjectsOfType(typeof(Renderer)) as IEnumerable<Renderer>) where (r.name == "XP" || r.name == "XN" || r.name == "YP" || r.name == "YN" || r.name == "ZP" || r.name == "ZN") select r).ToArray<Renderer>();

Is there any idea as to why this code causes the dll to not even load? The code is being compile using Visual Studio 2013 Ultimate, if that makes a difference (I don't think it does).

Are you compiling against .net 3.5?

Link to comment
Share on other sites

I have got my plug-in working, but it adds a new button every time it switches scenes? How do I make it load once?

Where are you adding the button? If it's from a KSPAddon, you'll want to pass 'true' to the second parameter of the KSPAddon annotation, and call DontDestroyOnLoad(this) in Start()

Link to comment
Share on other sites

I want to put a texture on a sphere. The texture is a Mercator projection.

Ideally, I would like to apply the texture to a sphere without ever downloading a modeling program. I could find a sphere model on the internet.

Failing that, could someone please tell me how to achieve this in a free modeling program?

Link to comment
Share on other sites

Yes, you can check the loaded assemblies for the mod's presence.

I do this to check if KAS is installed:

foreach (AssemblyLoader.LoadedAssembly Asm in AssemblyLoader.loadedAssemblies) //auto detect KAS for Skycrane
{
if (Asm.dllName == "KAS")
{
TWR1KASDetect = true;
}
}

I am not sure on the name you have to match, if it is the .dll name, or the namespace of the mod you have to match.

D.

Link to comment
Share on other sites

I got the DVmap plugin working, forgot the OnDestroy() method was all. Now I'm working on a different plug-in, and I am wondering how to get GUI.TextArea to work in a window. Edit: never mind, I was trying to write to a static string. :rolleyes: Double Edit: I was trying to input text into a passive window. :confused:

Edited by Robotengineer
Link to comment
Share on other sites

Is it possible to code a mod for KSP in C++? (There's only a C# API I believe?)

It's possible to invoke some C++ from C# - see http://stackoverflow.com/questions/935664/possible-to-call-c-code-from-c . If you've got something particularly computation-intensive or where you want control over memory allocation, that's how you can get into C++.

Other than that, nope. Your main plugin code has to be C# - there isn't really an API so much as KSP directly loading all C# dlls in the right folders and doing reflection stuff to grab relevant types.

Link to comment
Share on other sites

Typing this in the form of a question made me figure out how to answer it (yay for rubber duck programming) so I'll leave it here in the form of a Hot Tip so that it might help someone else out in the future:

I have a partmodule that accesses model transforms in the editor. Everything works great, I launch, everything still works, I revert to VAB, and things get weird. I get a NullReferenceException in FindModelTransform when the same code path is called, where it worked the first time through in the editor. If I throw that part away and grab a new one from the part menu, I get two NullReferenceExceptions in FindModelTransform. If I back out of the VAB and come back in and try that, I'm up to 3. I get one more NRE for every instance of that part that has ever existed.

The same happens if I skip all the FindModelTransforms and all the modifications that function made (so I know there's nothing going on there), and only print base.part.gameObject.name to the console, except the NRE comes from "(wrapper managed-to-native) UnityEngine.Component:InternalGetGameObject ()".

I had registered a delegate to GameEvents.onEditorShipModified to call that code in the first place, thus (apparently) creating a reference that prevented the partModule from being destroyed along with the part, thus leaving leftover gameObject-less partmodules in memory somewhere complaining about not having a gameobject to access every time I made another change in the editor. Properly unregistering the event in OnDestroy() fixed it up good.

thus ends today's lesson.

Link to comment
Share on other sites

I'm trying to load some music into the game database. I have no idea what goes wrong here (it even worked at some time before I refactored the code).

The path is right: C:\Kerbal Space Program\GameData\Akustik\Music\Moho.mp3

Class extends MonoBehaviourExtended (KSPPluginFramework by TriggerAu), code is inside Start() (tried Awake() before - same error).

File = "Music/Moho.mp3";
...
AssetLoader.LogFormatted_DebugOnly("Adding " + KSPUtil.ApplicationRootPath + "GameData/Akustik/" + File + " to database.");
Asset = GameDatabase.Instance.GetAudioClip(KSPUtil.ApplicationRootPath +"GameData/Akustik/" + File); // this fails and I don't know why.

AssetLoader.LogFormatted_DebugOnly("AudioClip is " + ((Asset == null) ? "null." : "loaded."));
Asset.name = File; // exception because Asset == null

KSP.log

[LOG 17:57:55.005] 11/10/2014 5:57:55 PM,Akustik,DEBUG: Adding C:/Kerbal Space Program/KSP_Data/../GameData/Akustik/Music/Moho.mp3 to database.
[LOG 17:57:55.006] 11/10/2014 5:57:55 PM,Akustik,DEBUG: AudioClip is null.
[EXC 17:57:55.011] NullReferenceException: Object reference not set to an instance of an object
Akustik.Track..ctor (.ConfigNode node)
Akustik.AssetLoader.ReadConfigFile (System.String filePath)
Akustik.AssetLoader.Start ()

output_log.txt

(Filename: C:/BuildAgent/work/d63dfc6385190b60/artifacts/StandalonePlayerGenerated/UnityEngineDebug.cpp Line: 49)

11/10/2014 5:57:55 PM,Akustik,DEBUG: Adding C:/Kerbal Space Program/KSP_Data/../GameData/Akustik/Music/Moho.mp3 to database.

(Filename: C:/BuildAgent/work/d63dfc6385190b60/artifacts/StandalonePlayerGenerated/UnityEngineDebug.cpp Line: 49)

11/10/2014 5:57:55 PM,Akustik,DEBUG: AudioClip is null.

(Filename: C:/BuildAgent/work/d63dfc6385190b60/artifacts/StandalonePlayerGenerated/UnityEngineDebug.cpp Line: 49)

NullReferenceException: Object reference not set to an instance of an object
at Akustik.Track..ctor (.ConfigNode node) [0x00000] in <filename unknown>:0

at Akustik.AssetLoader.ReadConfigFile (System.String filePath) [0x00000] in <filename unknown>:0

at Akustik.AssetLoader.Start () [0x00000] in <filename unknown>:0

(Filename: Line: -1)

I guess it's something so obvious that I'm going to smack my head at something.

Edited by *Aqua*
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...