MoreUmpf Posted January 22, 2015 Share Posted January 22, 2015 (edited) Is there a way to add custom events like the ones provided by the GameEvents-class.I created two of my own events like so:[B]public[/B] static class CustomEvents { [B]public[/B] static EventData<ProtoVessel> [I]onStationCompleted[/I] = [B]new[/B] EventData<ProtoVessel>("StationCompleted"); [B]public[/B] static EventData<ProtoVessel> [I]onBaseCompleted[/I] = [B]new[/B] EventData<ProtoVessel>("BaseCompleted"); }But I still had no luck actually firing those events.This is how I add, fire and remove the events:[...]Debug.Log("Firing Station event"); // <-- appears in the logCustomEvents.[I]onStationCompleted[/I].[B]Fire[/B](FlightGlobals.ActiveVessel.[I]protoVessel[/I]);[...] [B]protected[/B] override void [B]OnStart[/B]() { Debug.[B]Log[/B](" OnStart called!"); // <-- appears in the log CustomEvents.[I]onStationCompleted[/I].[B]Add[/B]([B]new[/B] EventData<ProtoVessel>.OnEvent([B]OnStationCompleted[/B])); CustomEvents.[I]onBaseCompleted[/I].[B]Add[/B]([B]new[/B] EventData<ProtoVessel>.OnEvent([B]OnBaseCompleted[/B])); } [B]protected[/B] override void [B]OnDestroy[/B]() { Debug.[B]Log[/B]("OnDestroy called!"); // <-- appears in the log CustomEvents.[I]onStationCompleted[/I].[B]Remove[/B]([B]new[/B] EventData<ProtoVessel>.OnEvent([B]OnStationCompleted[/B])); CustomEvents.[I]onBaseCompleted[/I].[B]Remove[/B]([B]new[/B] EventData<ProtoVessel>.OnEvent([B]OnBaseCompleted[/B])); } [B]private[/B] void [B]OnStationCompleted[/B](ProtoVessel pvessel) { Debug.Log("OnStationCompleted called!"); // <-- does NOT appear in the log } [B]private[/B] void [B]OnBaseCompleted[/B](ProtoVessel pvessel) { Debug.Log("OnBaseCompleted called!"); // <-- does NOT appear in the log }As you can see I did everything like with the normal GameEvents but the firing just doesn't call my functions at all. There's not even an error message in the log.What have I done wrong and how can I fix it? Edited January 22, 2015 by MoreUmpf Quote Link to comment Share on other sites More sharing options...
Diazo Posted January 25, 2015 Share Posted January 25, 2015 Alright, very simple question.There is the GameSettings Class that contains the keybinds in the game as KeyBinding objects.I need to make a List<KeyBinding> from those keybinds and I don't want to copy-paste code 100 times to manually do each keybind.Google says that this should work:foreach (KeyBinding kb in typeof(GameSettings).GetFields().OfType<KeyBinding>()) //find all keybinds in the game{print("keybind " + kb.name);}But nothing prints. Note that no error is thrown either so I think I'm on the right track, I'm just looking for the wrong thing so that line of code currently returns zero items.The issue being I have no clue what I need to change to find the keybinds as I want.Anyone have any ideas?D. Quote Link to comment Share on other sites More sharing options...
flashcactus Posted January 25, 2015 Share Posted January 25, 2015 So, I'm starting out with KSP plugin development, using MonoDevelop. 2 questions: First, what kind of project do I have to create? I'm guessing either Library or Portable library. Second, how do I add the KSP and Unity libs? Quote Link to comment Share on other sites More sharing options...
xEvilReeperx Posted January 25, 2015 Share Posted January 25, 2015 Google says that this should work:foreach (KeyBinding kb in typeof(GameSettings).GetFields().OfType<KeyBinding>()) //find all keybinds in the game{print("keybind " + kb.name);}But nothing prints. Note that no error is thrown either so I think I'm on the right track, I'm just looking for the wrong thing so that line of code currently returns zero items.You've got it almost right but there are two bugs in your code. The first is that GetFields() doesn't return static fields by default. The second is that GetFields() returns an array of FieldInfo[] which means that any fields you did retrieve are immediately thrown out when comparing FieldInfo to KeyBinding in .OfType<KeyBinding>foreach (FieldInfo kbInfo in typeof (GameSettings).GetFields(BindingFlags.Static | BindingFlags.Public) .Where(fi => fi.FieldType == typeof(KeyBinding))){ var kb = kbInfo.GetValue(null) as KeyBinding; _log.Normal("Keybinding: '" + kbInfo.Name + "' set to " + kb.primary + (kb.secondary != KeyCode.None ? (" and " + kb.secondary) : ""));} Quote Link to comment Share on other sites More sharing options...
Diazo Posted January 25, 2015 Share Posted January 25, 2015 Alright.I'm thinking I'm just going to go ahead and build the index manually at this point, faster then figuring it out it seems.Thanks for the assist.D. Quote Link to comment Share on other sites More sharing options...
Crzyrndm Posted January 26, 2015 Share Posted January 26, 2015 So, I'm starting out with KSP plugin development, using MonoDevelop. 2 questions: First, what kind of project do I have to create? I'm guessing either Library or Portable library. Second, how do I add the KSP and Unity libs?http://wiki.kerbalspaceprogram.com/wiki/Setting_up_MonoDevelop Quote Link to comment Share on other sites More sharing options...
Robotengineer Posted January 27, 2015 Share Posted January 27, 2015 If I want to create an inventory of parts for a save, how do I go about doing this? Quote Link to comment Share on other sites More sharing options...
StratoK Posted January 29, 2015 Share Posted January 29, 2015 (edited) Hi!I am thinking of making a kind of wormhole mod with actual celestial bodies instead of parts. Now, my problem is how would I go about inverting my orbit calculation wise? What parameters of it have to be changed how?Example: Ship is suborbital around body A going right round, and I have the parameters of it's orbit (FlightGlobals.ActiveVessel.orbit). Now, as with a real wormhole, your orbit on the other side (Body would be reversed. I know how to change it to go left round (add 180 to inclination), but how would I take into account eccentricity, position in orbit, and flip the direction of the 'eccentricity-bulge-direction'? Edited January 29, 2015 by StratoK Quote Link to comment Share on other sites More sharing options...
problemecium Posted January 29, 2015 Share Posted January 29, 2015 This isn't exactly a plugin question, but what's the consensus on porting old mods whose authors have left without leaving a license? Must we assume they cannot be ported, or can we port them, give credit, and agree to take them down if the author complains? Quote Link to comment Share on other sites More sharing options...
sarbian Posted January 29, 2015 Share Posted January 29, 2015 No license no porting. Quote Link to comment Share on other sites More sharing options...
NathanKell Posted January 29, 2015 Share Posted January 29, 2015 No license = All Rights Reserved, yeah. Quote Link to comment Share on other sites More sharing options...
intervenience Posted January 30, 2015 Share Posted January 30, 2015 If I want to create an inventory of parts for a save, how do I go about doing this?So you want to have parts allocated for specific game saves? I think you will have to use config nodes for this, but I'm not entirely sure how you would proceed from there.My question: I'm trying to use ConfigNode to load a string array, but it does not return any results. It just says in the log "System.String[]" Is there a better way to load this information to compare data from the game? In this case, comparing stored values in my config node to the universal time in the game, such that there may be many results to retrieve. If there is no other way to retrieve the data, could someone help me troubleshoot this.(I'm using a custom .cfg file in my mod folder for now)string timeOfRestoration;void Awake(){ ConfigNode rtLoadNode = ConfigNode.Load("GameData/recoveryTimer/Recoveries.cfg"); Debug.Log(rtLoadNode.GetValues(timeOfRestoration));}And yes, I've made sure it's loading the correct file. I've got another line of code in my file to count the nodes in the file and it's returning the correct number so it's definitely working. Thanks. Quote Link to comment Share on other sites More sharing options...
Crzyrndm Posted January 30, 2015 Share Posted January 30, 2015 string timeOfRestoration;void Awake(){ ConfigNode rtLoadNode = ConfigNode.Load("GameData/recoveryTimer/Recoveries.cfg"); [COLOR=#ff0000]foreach (string s in rtLoadNode.GetValues(timeOfRestoration)) Debug.Log(s)[/COLOR]}You can't print a collection and expect to get something sensible, you have to print the elements of the collection Quote Link to comment Share on other sites More sharing options...
intervenience Posted January 30, 2015 Share Posted January 30, 2015 You can't print a collection and expect to get something sensible, you have to print the elements of the collectionOh, I see. Thank you. Quote Link to comment Share on other sites More sharing options...
TriggerAu Posted January 30, 2015 Share Posted January 30, 2015 Got a Q thats bugging me. When Timewarp is changed by altitude limits is there anyway to detect thats the reason? I tried looking at the altitude, but when the initial change happens the vessel is not actually at the altitude, and I cant simply check for keystrokes as a mod may be affecting the warp too.Anyone got any good ideas? Quote Link to comment Share on other sites More sharing options...
sarbian Posted January 30, 2015 Share Posted January 30, 2015 You checked the alt vs TimeWarp.fetch.GetAltitudeLimit(TimeWarp.fetch.current_rate_index, vessel.mainBody) ? I guess you could check with +1 and -1 on the index. "when the initial change happens the vessel is not actually at the altitude". Do you see a small difference ? It may be that the alt used for the check is the alt of the the next frame position ( ie pos + velocity * TimeWarp.deltaTime ) Quote Link to comment Share on other sites More sharing options...
*Aqua* Posted January 30, 2015 Share Posted January 30, 2015 I'm not sure in which order the events for game loading and saving trigger.So far I think it works like that:Loading a game save(KSP reads sfs file)GameEvent.onGameStateLoaded.Fire() // returns ConfigNodeGameEvent.onGameStateCreated.Fire() // returns Game objectSaving a game saveGameEvent.onGameStateSave.Fire() // returns Game objectGameEvent.onGameStateSaved.Fire() // returns ConfigNode(KSP writes sfs file)Is that correct? Quote Link to comment Share on other sites More sharing options...
sarbian Posted January 30, 2015 Share Posted January 30, 2015 For saving it is : GameEvent.onGameStateSaved.Fire() // returns ConfigNode giving addons the opportunity to add data to the save(KSP writes sfs file)GameEvent.onGameStateSave.Fire() // returns Game object. Save is doneNo idea for the Loaded/Created. Quote Link to comment Share on other sites More sharing options...
*Aqua* Posted January 30, 2015 Share Posted January 30, 2015 Thank you. That helped a lot! Next question: This gives an error.[KSPAddon(KSPAddon.Startup.Flight,false)] public class Test: MonoBehaviour { void Awake() { Debug.Log("Awake"); GameEvents.onGameStateCreated.Add((game) => { Debug.Log("onGameStateCreated"); }); }}[LOG 17:22:44.052] Awake[EXC 17:22:44.057] NullReferenceException: Object reference not set to an instance of an object EventData`1+[Game]..ctor (.OnEvent ) EventData`1[Game].Add (.OnEvent evt) TestNamespace.Test.Awake () UnityEngine.GameObject:AddComponent(Type) AddonLoader:StartAddon(LoadedAssembly, Type, KSPAddon, Startup) AddonLoader:StartAddons(Startup) AddonLoader:OnLevelWasLoaded(Int32)What's the problem here? Visual Studio accepts the code. Quote Link to comment Share on other sites More sharing options...
stupid_chris Posted January 30, 2015 Share Posted January 30, 2015 Thank you. That helped a lot! Next question: This gives an error.[KSPAddon(KSPAddon.Startup.Flight,false)] public class Test: MonoBehaviour { void Awake() { Debug.Log("Awake"); GameEvents.onGameStateCreated.Add((game) => { Debug.Log("onGameStateCreated"); }); }}[LOG 17:22:44.052] Awake[EXC 17:22:44.057] NullReferenceException: Object reference not set to an instance of an object EventData`1+[Game]..ctor (.OnEvent ) EventData`1[Game].Add (.OnEvent evt) TestNamespace.Test.Awake () UnityEngine.GameObject:AddComponent(Type) AddonLoader:StartAddon(LoadedAssembly, Type, KSPAddon, Startup) AddonLoader:StartAddons(Startup) AddonLoader:OnLevelWasLoaded(Int32)What's the problem here? Visual Studio accepts the code.Anonymous methods don't deal well with GameEvents. You need something that can be removed, and since anonymous methods have no signature you couldn't remove the method from the event if you wanted to. Quote Link to comment Share on other sites More sharing options...
*Aqua* Posted January 30, 2015 Share Posted January 30, 2015 That was it. Man, there's some really tricky stuff you have to think about. Quote Link to comment Share on other sites More sharing options...
TriggerAu Posted January 30, 2015 Share Posted January 30, 2015 You checked the alt vs TimeWarp.fetch.GetAltitudeLimit(TimeWarp.fetch.current_rate_index, vessel.mainBody) ? I guess you could check with +1 and -1 on the index. "when the initial change happens the vessel is not actually at the altitude". Do you see a small difference ? It may be that the alt used for the check is the alt of the the next frame position ( ie pos + velocity * TimeWarp.deltaTime )Thats the code I was checking to try and see between this and previously whether it had changed AltitudeLimits. I've got a feeling its dropping out based on some lookahead type thing, the Altitude is always greater than the limit when it drops out. I'll try the next frame position idea, thanks Sarbian Quote Link to comment Share on other sites More sharing options...
*Aqua* Posted January 31, 2015 Share Posted January 31, 2015 I've got another question:How can I query which Kerbal is assigned to which capsule seat in the editor crew screen?I just can't find that information anywhere. part.protoModuleCrew.Count() always reports 0. It seems the only way is to parse the GUI via EditorPanels.Instance.crew (is a UIPanel). I bet there's a better way. Quote Link to comment Share on other sites More sharing options...
Crzyrndm Posted January 31, 2015 Share Posted January 31, 2015 I've got another question:How can I query which Kerbal is assigned to which capsule seat in the editor crew screen?I just can't find that information anywhere. part.protoModuleCrew.Count() always reports 0. It seems the only way is to parse the GUI via EditorPanels.Instance.crew (is a UIPanel). I bet there's a better way.If you can get the information from the panel manager, I'm not sure what the issue is (you're not parsing the GUI, you're getting information from the class that controls the GUI). Crew is almost certainly added/associated with the vessel post-launch Quote Link to comment Share on other sites More sharing options...
*Aqua* Posted January 31, 2015 Share Posted January 31, 2015 If you can get the information from the panel manager, I'm not sure what the issue isI'm sure that's not how you should do that. There must be somekind of collection somewhere which contains the information which Kerbal goes to which seat. The GUI parses that collection and arranges panels, buttons, etc. according to that... if it works according to the MVC design pattern. And it's this collection I want to get. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.