garwel Posted June 7, 2017 Share Posted June 7, 2017 Hey. I need help doing the dirty job of killing kerbals. Using ProtoCrewMember.Die() when in the flight scene causes an NRE and doesn't remove the portrait in flight scene, so I've been using this code (PCM is an instance of ProtoCrewMember): if (PCM.seat != null) PCM.seat.part.RemoveCrewmember(PCM); PCM.rosterStatus = ProtoCrewMember.RosterStatus.Dead; However, this doesn't always work well. Sometimes, I have a portrait replaced with white noise; sometimes I still get the NRE or the kerbal even survives. I haven't been able to understand why it has different outcomes (maybe it has something to do with the game's FixedUpdate() cycle or with timewarp). In any case, the deceased kerbals disappear from the roster and are not seen in the Lost tab. So, how do you kill your kerbals? Quote Link to comment Share on other sites More sharing options...
VR_Dev Posted June 9, 2017 Share Posted June 9, 2017 I have two problems that are basic KSP functions that I can't seem to get to work. I am trying to load a .cfg node into my script. I have a "SavedValues.cfg" in the root gamedata folder that looks like this. VALUES{ pitchP = 10; pitchI = 10; pitchD = 10; } Then I access it from my script, but it throws a null reference exception. public void Awake() { ConfigNode savedValues = ConfigNode.Load("GameData/SavedValues.cfg"); savedValues = savedValues.GetNode("VALUES"); pitchPValue = float.Parse(savedValues.GetValue("pitchP")); //pitchIValue = float.Parse(savedValues.GetValue("pitchI")); //pitchDValue = float.Parse(savedValues.GetValue("pitchD")); } It seems pretty straight forward but I can't seem to figure out why its not working. Additionally I can't get this to work either. Any help on either of these would be very much appreciated. GamePersistence.LoadGame("quicksave.sfs", "default", false, true); Quote Link to comment Share on other sites More sharing options...
garwel Posted June 10, 2017 Share Posted June 10, 2017 15 hours ago, clown_baby said: I have two problems that are basic KSP functions that I can't seem to get to work. I am trying to load a .cfg node into my script. I have a "SavedValues.cfg" in the root gamedata folder that looks like this. VALUES{ pitchP = 10; pitchI = 10; pitchD = 10; } Then I access it from my script, but it throws a null reference exception. public void Awake() { ConfigNode savedValues = ConfigNode.Load("GameData/SavedValues.cfg"); savedValues = savedValues.GetNode("VALUES"); pitchPValue = float.Parse(savedValues.GetValue("pitchP")); //pitchIValue = float.Parse(savedValues.GetValue("pitchI")); //pitchDValue = float.Parse(savedValues.GetValue("pitchD")); } It seems pretty straight forward but I can't seem to figure out why its not working. Additionally I can't get this to work either. Any help on either of these would be very much appreciated. GamePersistence.LoadGame("quicksave.sfs", "default", false, true); How about removing the semicolons from the config file? Quote Link to comment Share on other sites More sharing options...
DMagic Posted June 10, 2017 Share Posted June 10, 2017 I think ConfigNode.Load requires the absolute file location, not the KSP relative location. Quote Link to comment Share on other sites More sharing options...
VR_Dev Posted June 10, 2017 Share Posted June 10, 2017 9 hours ago, garwel said: How about removing the semicolons from the config file? I have tried that as well, then dropping the( savedValues = savedValues.GetNode("VALUES"); ) and getting the root node. no luck though 4 hours ago, DMagic said: I think ConfigNode.Load requires the absolute file location, not the KSP relative location. I'll give that a shot, but how would that work if it were to be released as a mod? Everyone would have to put their own file path from wherever the folder is stored on the drive Quote Link to comment Share on other sites More sharing options...
HebaruSan Posted June 10, 2017 Share Posted June 10, 2017 2 minutes ago, clown_baby said: I'll give that a shot, but how would that work if it were to be released as a mod? Everyone would have to put their own file path from wherever the folder is stored on the drive One common strategy is to look up the path to the mod's DLL. https://github.com/HebaruSan/Astrogator/blob/master/src/KerbalTools.cs#L291-L293 https://github.com/HebaruSan/Astrogator/blob/master/src/Settings.cs#L35 Quote Link to comment Share on other sites More sharing options...
JPLRepo Posted June 10, 2017 Share Posted June 10, 2017 On 6/8/2017 at 4:50 AM, garwel said: Hey. I need help doing the dirty job of killing kerbals. Using ProtoCrewMember.Die() when in the flight scene causes an NRE and doesn't remove the portrait in flight scene, so I've been using this code (PCM is an instance of ProtoCrewMember): if (PCM.seat != null) PCM.seat.part.RemoveCrewmember(PCM); PCM.rosterStatus = ProtoCrewMember.RosterStatus.Dead; However, this doesn't always work well. Sometimes, I have a portrait replaced with white noise; sometimes I still get the NRE or the kerbal even survives. I haven't been able to understand why it has different outcomes (maybe it has something to do with the game's FixedUpdate() cycle or with timewarp). In any case, the deceased kerbals disappear from the roster and are not seen in the Lost tab. So, how do you kill your kerbals? PCM.UnregisterExperienceTraits(part); PCM.Die(); Vessel.CrewWasModified(vessel); If you intend them to respawn as per game settings. Check HighLogic.CurrentGame.Parameters.Difficulty.MissingCrewsRespawn and then call PCM.StartRespawnPeriod() Where PCM is the instance of the ProtoCrewMember and vessel is the Vessel they are in and part is the Part they are in. For crew that die it is stock intended their portrait becomes static. If you don't want this then you can call a refresh on the KerbalPortraitGallery.Instance.StartRefresh(vessel). Of course this all assumes they are in the ActiveVessel. If you are still getting NREs please supply more info on the NRE. Quote Link to comment Share on other sites More sharing options...
sarbian Posted June 10, 2017 Share Posted June 10, 2017 2 hours ago, clown_baby said: I'll give that a shot, but how would that work if it were to be released as a mod? Everyone would have to put their own file path from wherever the folder is stored on the drive KSPUtil.ApplicationRootPath + "/GameData" Quote Link to comment Share on other sites More sharing options...
garwel Posted June 11, 2017 Share Posted June 11, 2017 (edited) 17 hours ago, JPLRepo said: PCM.UnregisterExperienceTraits(part); PCM.Die(); Vessel.CrewWasModified(vessel); If you intend them to respawn as per game settings. Check HighLogic.CurrentGame.Parameters.Difficulty.MissingCrewsRespawn and then call PCM.StartRespawnPeriod() Where PCM is the instance of the ProtoCrewMember and vessel is the Vessel they are in and part is the Part they are in. For crew that die it is stock intended their portrait becomes static. If you don't want this then you can call a refresh on the KerbalPortraitGallery.Instance.StartRefresh(vessel). Of course this all assumes they are in the ActiveVessel. If you are still getting NREs please supply more info on the NRE. Thanks, will try this. The problem is, it also has to happen to unloaded kerbals (including from KSC and Tracking Station scenes). This is where I had most problems. Edited June 11, 2017 by garwel Quote Link to comment Share on other sites More sharing options...
VR_Dev Posted June 11, 2017 Share Posted June 11, 2017 I'm sorry to keep nagging about this but I just can't get it to work. On 6/10/2017 at 8:38 AM, DMagic said: I think ConfigNode.Load requires the absolute file location, not the KSP relative location. I tried just hard coding the full address into ConfigNode.Load() but still no luck. I don't get a null ref exception on the savedValues =ConfigNode.Load() call, but as soon as I try to access anything via savedValues one gets thrown. 17 hours ago, sarbian said: KSPUtil.ApplicationRootPath + "/GameData" This returns the KSP_Data folder path Quote Link to comment Share on other sites More sharing options...
DMagic Posted June 11, 2017 Share Posted June 11, 2017 @clown_baby This is how I've always done it and it works for me: https://github.com/DMagic1/KSP_Better_Maneuvering/blob/master/Source/BetterManeuvering/ManeuverPersistence.cs#L91 I'm no sure if all of that Path.Combine, Path.DirectoryName stuff is actually needed (or converting the \ to /), but it works, so I've just used the same method every time. Quote Link to comment Share on other sites More sharing options...
garwel Posted June 11, 2017 Share Posted June 11, 2017 21 hours ago, JPLRepo said: PCM.UnregisterExperienceTraits(part); PCM.Die(); Vessel.CrewWasModified(vessel); If you intend them to respawn as per game settings. Check HighLogic.CurrentGame.Parameters.Difficulty.MissingCrewsRespawn and then call PCM.StartRespawnPeriod() Where PCM is the instance of the ProtoCrewMember and vessel is the Vessel they are in and part is the Part they are in. This code appears to work for a kerbal on board ActiveVessel. But when I try it on a kerbal on EVA (I skip the first line because part is null) while being focused on a nearby vessel, he doesn't disappear or anything. Trying then to switch to that kerbal causes an NRE: NullReferenceException: Object reference not set to an instance of an object at KerbalRoster.ValidateAssignments (.Game st) [0x00000] in <filename unknown>:0 at Game.Updated () [0x00000] in <filename unknown>:0 at GamePersistence.SaveGame (System.String saveFileName, System.String saveFolder, SaveMode saveMode) [0x00000] in <filename unknown>:0 at KSP.UI.Screens.AltimeterSliderButtons.returnToSpaceCenter () [0x00000] in <filename unknown>:0 at UnityEngine.Events.InvokableCall.Invoke (System.Object[] args) [0x00000] in <filename unknown>:0 at UnityEngine.Events.InvokableCallList.Invoke (System.Object[] parameters) [0x00000] in <filename unknown>:0 at UnityEngine.Events.UnityEventBase.Invoke (System.Object[] parameters) [0x00000] in <filename unknown>:0 at UnityEngine.Events.UnityEvent.Invoke () [0x00000] in <filename unknown>:0 at UnityEngine.UI.Button.Press () [0x00000] in <filename unknown>:0 at UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) [0x00000] in <filename unknown>:0 at UnityEngine.EventSystems.ExecuteEvents.Execute (IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) [0x00000] in <filename unknown>:0 at UnityEngine.EventSystems.ExecuteEvents.Execute[IPointerClickHandler] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.EventFunction`1 functor) [0x00000] in <filename unknown>:0 UnityEngine.DebugLogHandler:Internal_LogException(Exception, Object) UnityEngine.DebugLogHandler:LogException(Exception, Object) UnityEngine.Logger:LogException(Exception, Object) UnityEngine.Debug:LogException(Exception) UnityEngine.EventSystems.ExecuteEvents:Execute(GameObject, BaseEventData, EventFunction`1) UnityEngine.EventSystems.StandaloneInputModule:ProcessMousePress(MouseButtonEventData) UnityEngine.EventSystems.StandaloneInputModule:ProcessMouseEvent(Int32) UnityEngine.EventSystems.StandaloneInputModule:ProcessMouseEvent() UnityEngine.EventSystems.StandaloneInputModule:Process() UnityEngine.EventSystems.EventSystem:Update() Quote Link to comment Share on other sites More sharing options...
VR_Dev Posted June 12, 2017 Share Posted June 12, 2017 21 hours ago, DMagic said: @clown_baby This is how I've always done it and it works for me: https://github.com/DMagic1/KSP_Better_Maneuvering/blob/master/Source/BetterManeuvering/ManeuverPersistence.cs#L91 I'm no sure if all of that Path.Combine, Path.DirectoryName stuff is actually needed (or converting the \ to /), but it works, so I've just used the same method every time. So I have tried this and every other way to get the correct path as a string. I'm starting to think that isn't the problem however. If the path were wrong I assume I would get a null ref exception when i use: fullPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "SavedValues.cfg").Replace("\\", "/"); ConfigNode savedValues = ConfigNode.Load(fullPath); But I don't. I'm starting to think I am just accessing the node incorrectly. So again here is my .cfg file. VALUES { pitchP = 10; pitchI = 10; pitchD = 10; } So i get the root node of the cfg using the code above, then get the VALUES node with this, which is when the first null ref gets thrown. if (savedValues.HasNode("VALUES")) { savedValues = savedValues.GetNode("VALUES"); } Then I should be able to access the values in the node via. pitchIValue = float.Parse(savedValues.GetValue("pitchI")); Is this not the correct way to get info from the nodes? Quote Link to comment Share on other sites More sharing options...
sarbian Posted June 12, 2017 Share Posted June 12, 2017 14 minutes ago, clown_baby said: So again here is my .cfg file. And you still have ";" at the end of your lines. It is not a C# file. Quote Link to comment Share on other sites More sharing options...
VR_Dev Posted June 12, 2017 Share Posted June 12, 2017 On 6/10/2017 at 3:39 AM, garwel said: How about removing the semicolons from the config file? 2 minutes ago, sarbian said: And you still have ";" at the end of your lines. It is not a C# file. Oh sorry I totally missed that suggestion the first time. Doesnt fix the problem though Quote Link to comment Share on other sites More sharing options...
VR_Dev Posted June 12, 2017 Share Posted June 12, 2017 (edited) So I actually fixed it. I copied an existing cfg file and changed the name/values which got it to load. When I created my "SavedValues.cfg" I must have saved it as a text file. I knew it was something stupid I did. Thanks for the help everyone. Edited June 12, 2017 by clown_baby Quote Link to comment Share on other sites More sharing options...
JPLRepo Posted June 13, 2017 Share Posted June 13, 2017 On 6/12/2017 at 4:36 AM, garwel said: This code appears to work for a kerbal on board ActiveVessel. But when I try it on a kerbal on EVA (I skip the first line because part is null) while being focused on a nearby vessel, he doesn't disappear or anything. Trying then to switch to that kerbal causes an NRE: NullReferenceException: Object reference not set to an instance of an object at KerbalRoster.ValidateAssignments (.Game st) [0x00000] in <filename unknown>:0 at Game.Updated () [0x00000] in <filename unknown>:0 at GamePersistence.SaveGame (System.String saveFileName, System.String saveFolder, SaveMode saveMode) [0x00000] in <filename unknown>:0 at KSP.UI.Screens.AltimeterSliderButtons.returnToSpaceCenter () [0x00000] in <filename unknown>:0 at UnityEngine.Events.InvokableCall.Invoke (System.Object[] args) [0x00000] in <filename unknown>:0 at UnityEngine.Events.InvokableCallList.Invoke (System.Object[] parameters) [0x00000] in <filename unknown>:0 at UnityEngine.Events.UnityEventBase.Invoke (System.Object[] parameters) [0x00000] in <filename unknown>:0 at UnityEngine.Events.UnityEvent.Invoke () [0x00000] in <filename unknown>:0 at UnityEngine.UI.Button.Press () [0x00000] in <filename unknown>:0 at UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) [0x00000] in <filename unknown>:0 at UnityEngine.EventSystems.ExecuteEvents.Execute (IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) [0x00000] in <filename unknown>:0 at UnityEngine.EventSystems.ExecuteEvents.Execute[IPointerClickHandler] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.EventFunction`1 functor) [0x00000] in <filename unknown>:0 UnityEngine.DebugLogHandler:Internal_LogException(Exception, Object) UnityEngine.DebugLogHandler:LogException(Exception, Object) UnityEngine.Logger:LogException(Exception, Object) UnityEngine.Debug:LogException(Exception) UnityEngine.EventSystems.ExecuteEvents:Execute(GameObject, BaseEventData, EventFunction`1) UnityEngine.EventSystems.StandaloneInputModule:ProcessMousePress(MouseButtonEventData) UnityEngine.EventSystems.StandaloneInputModule:ProcessMouseEvent(Int32) UnityEngine.EventSystems.StandaloneInputModule:ProcessMouseEvent() UnityEngine.EventSystems.StandaloneInputModule:Process() UnityEngine.EventSystems.EventSystem:Update() A kerbal on EVA.. You didn't mention that. In that case you have to kill the Vessel as well. You can't switch to a vessel that is an EVA Kerbal if the Kerbal is dead. If they die on EVA in stock then the vessel must also be killed and disappear. Stock does not support that use case. Quote Link to comment Share on other sites More sharing options...
klond Posted June 13, 2017 Share Posted June 13, 2017 I'm not a programmer, but I have a question. 'Hope I'm in the right place. If I open a .craft file as a text file I see a line like this for most parts modMass = 0 I was hoping this will change the effect gravity has on that part. How do I find out what this variable really does, if changing it has any effect, and what acceptable ranges are valid? Quote Link to comment Share on other sites More sharing options...
artwhaley Posted June 13, 2017 Share Posted June 13, 2017 If memory serves correctly this is the scaler that something like tweakscale can use to change the mass of a given part's instance- thus why you'll find this parameter in a .craft file or a .sfs but not in the basic .cfg that defines the part. Whether it's additive or multiplicative I don't remember! To figure it out, i'd just start fiddling with it! Write down your craft's mass, write down a given part's mass, then change that part's modmass and reload to see if the mass of the craft went up by the amount you added or if the mass of the craft increased by the mass of that part TIMES the modmass scaler. I wish there was great documentation to point you towards but... that's what KSP modmakers have always had to do - trial and error. That said, you question was specific- you want to change the effect of gravity ONLY? Not actually change the mass of the part? You want OTHER accelerations to continue to act unaffected? That's a tough one that might take a bit more explaining before we come up with an answer for you... Quote Link to comment Share on other sites More sharing options...
gomker Posted June 16, 2017 Share Posted June 16, 2017 I was wondering if anyone has seen this behavior before when using FlightGlobals.ForceSetActiveVessel. The throttle settings seem to be overriding the settings of the vessel I switch to. When using the [ ] Brackets to switch this does not occur. Vessel A (Active) = 0% Throttle Vessel B (Inactive) = 100% Throttle FlightGlobals.ForceSetActiveVessel(Vessel B) Vessel A (Inactive) = 0% Throttle Vessel B (Active) = 0% Throttle Quote Link to comment Share on other sites More sharing options...
Bonus Eventus Posted June 18, 2017 Share Posted June 18, 2017 I did a simple test with an internal module I've been tinkering with, and caused all kinds of mayhem. The module is simple. It finds a prop transform for a screen model and an empty gameObject, then adds a camera component to the empty gameObject and adds a renderTexture to the screen model. The camera then has its targetTexture assigned to the renderTexture. That's it. The game loads fine but when I load the IVA on the pad the main cam is rotated 90 degrees on the x axis or sometimes is flung into deep space before the game crashes. I'm guessing it has something to do with layers and tags. I'm sure there's some camera voodoo I'm unaware of. @linuxgurugamer would probably know what the best practices are. public class UtilisDisplay : InternalModule { [KSPField] public string dTransform = "dTransform"; [KSPField] public string cameraName = "utilisCamera"; [KSPField] public int dPixelWidth = 512; [KSPField] public int dPixelHeight = 256; private Camera cameraFeed; private Transform cTransform; private RenderTexture displayTexture; private Material displayMaterial; public override void OnAwake() { if(HighLogic.LoadedSceneIsFlight) { UtilisTools.Log(this, "Start!"); displayTexture = new RenderTexture(dPixelWidth, dPixelHeight, 24, RenderTextureFormat.ARGB32); displayMaterial = internalProp.FindModelTransform(dTransform).GetComponent<Renderer>().material; cTransform = internalProp.internalModel.FindModelTransform(cameraName); cTransform.gameObject.AddComponent<Camera>(); UtilisTools.Log(this, "Camera created"); cameraFeed = cTransform.gameObject.GetComponent<Camera>(); cameraFeed.fieldOfView = 110; cameraFeed.transform.parent = cTransform; cameraFeed.transform.localPosition = Vector3.zero; cameraFeed.transform.localEulerAngles = Vector3.zero; displayMaterial.mainTexture = displayTexture; } } } The log is spamming "Look rotation viewing vector is zero" Quote Link to comment Share on other sites More sharing options...
linuxgurugamer Posted June 18, 2017 Share Posted June 18, 2017 Sounds like you need to set a vector, probably getting an internal divide by zero Best to look at some of the camera mods to see what you may have missed. Quote Link to comment Share on other sites More sharing options...
saabstory88 Posted June 18, 2017 Share Posted June 18, 2017 Quick question. I want to setup a UI_FloatEdit with values from the config file. When attempting to pass another field as the arguments for minValue, or maxValue, I get the following error: An object reference is required for the non-static field, method, or property At the moment, the only way it compiles is if I hard code the values: [KSPField(isPersistant = true, guiName = "Length", guiFormat = "F3", guiUnits = "m"), UI_FloatEdit(scene = UI_Scene.Editor, minValue = 0.25f, incrementLarge = 2.0f, incrementSmall = 0.25f, incrementSlide = 0.001f)] public float tankLength = 1.0f; What is the proper way to make this work? Quote Link to comment Share on other sites More sharing options...
HebaruSan Posted June 18, 2017 Share Posted June 18, 2017 2 minutes ago, saabstory88 said: Quick question. I want to setup a UI_FloatEdit with values from the config file. What is the proper way to make this work? I think you would need to set those values at run time in your module's Start(). BaseField field = Fields["MyField"]; UI_FloatEdit edit = (UI_FloatEdit)field.uiControlEditor; if (edit != null) { edit.minValue = 0f; } Quote Link to comment Share on other sites More sharing options...
saabstory88 Posted June 18, 2017 Share Posted June 18, 2017 Works like a charm, thanks! 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.