0111narwhalz Posted October 27, 2016 Share Posted October 27, 2016 55 minutes ago, udk_lethal_d0se said: Have a look at Vessel.activeVessel, there are a number of accessible details there. Also have a look at vessel in the Api, linked below. https://anatid.github.io/XML-Documentation-for-the-KSP-API/class_vessel.html Yes, but how do I actually use that information? Do I use double d = Vessel.activeVessel.verticalSpeed; or what? Quote Link to comment Share on other sites More sharing options...
udk_lethal_d0se Posted October 27, 2016 Share Posted October 27, 2016 9 minutes ago, 0111narwhalz said: Yes, but how do I actually use that information? Do I use double d = Vessel.activeVessel.verticalSpeed; or what? Yes, that's one way of using the information you want. Once you have it, sent it to a ui, etc. Quote Link to comment Share on other sites More sharing options...
Diazo Posted October 27, 2016 Share Posted October 27, 2016 (edited) @0111narwhalz The currently focused vessel is referenced as a static at FlightGlobals.ActiveVessel. If you want to refer to a non-active vessel, getting the reference is trickier and depends on where the vessel you are trying to access is. Notably if you are in a partModule, using this.vessel instead recommended as that is the vessel that partModule is attached to. D. Edited October 27, 2016 by Diazo Quote Link to comment Share on other sites More sharing options...
IgorZ Posted October 27, 2016 Share Posted October 27, 2016 5 hours ago, Booots said: I think what he means is that the root cause is the part's orientation being incorrect because it's constantly changing. His suggestion would be to update and correct each part's position and orientation at each tick so that when it comes time to save or pack the part its orientation and position don't need adjusting because they're already up to date. Obviously this comes with the computation overhead of calculating and correcting the orientation of every part in the scene at every tick as opposed to the times when it absolutely needs to be correct. Well, it will solve the problem but doing this stuff in every tick is barely a good idea performance wise. Doing it less frequent (like once or twice per a second) could be a compromise but the approach is still ugly. 6 hours ago, Booots said: Does onGameStateSave fire before anything is persisted? If so, you could add something there to go through and fix orientations. All on save handlers which I was able to find (including this one) are called after the part was actually stored into config node. Quote Link to comment Share on other sites More sharing options...
Diazo Posted October 27, 2016 Share Posted October 27, 2016 (edited) @IgorZ Is this pivotJoint your code or Squads? If it's your code it would be easy enough to update orgPos and orgRot whenever whatever the changePivotAngle event is fires. If it's Squads code I'm not sure. If you can't find a changePivotAngle event your only choice is to monitor it. Having said that, just running numbers is very little overhead. For AGX I monitor every default action and it's assigned action groups 3 or 4 times a second and that isn't noticeable for overhead. You can't ignore the overhead it generates, but if it doesn't affect the Physics system or the rendered graphics it's not something you have to worry about 99% of the time. D. edit: Actually, I just checked my code and I only check the currently selected action group for the current part, not all groups on the entire vessel, so that is negligable overhead. Edited October 27, 2016 by Diazo Quote Link to comment Share on other sites More sharing options...
0111narwhalz Posted October 27, 2016 Share Posted October 27, 2016 20 minutes ago, Diazo said: The currently focused vessel is referenced as a static at FlightGlobals.ActiveVessel. If you want to refer to a non-active vessel, getting the reference is trickier and depends on where the vessel you are trying to access is. Notably if you are in a partModule, using this.vessel instead recommended as that is the vessel that partModule is attached to. D. Okay, so how does one determine that one is in a partModule or not? And how do you tell a part to have your module? Also, is the snippet I posted earlier incorrect in favor of double d = FlightGlobals.ActiveVessel.verticalSpeed; Quote Link to comment Share on other sites More sharing options...
Crzyrndm Posted October 27, 2016 Share Posted October 27, 2016 You are using a part module if you're adding it through part configs or the class can trace it's inheritance heirachy through the PartModule class. In that case double vSpeed = vessel.verticalSpeed; // all part modules have a reference to the part and vessel they are part of If you're inheriting from Monobehaviour and using the KSPAddon attribute (a partless plugin), your snippet above will get the vSpeed of the vessel the player is currently controlling Quote Link to comment Share on other sites More sharing options...
IgorZ Posted October 27, 2016 Share Posted October 27, 2016 21 minutes ago, Diazo said: @IgorZ Is this pivotJoint your code or Squads? If it's your code it would be easy enough to update orgPos and orgRot whenever whatever the changePivotAngle event is fires. Pivot joint feature is available from Squad but there is no "change angle event" as such. The angle is changed by game's physics (e.g. when a force is applied to the vessel). Quote Link to comment Share on other sites More sharing options...
Diazo Posted October 27, 2016 Share Posted October 27, 2016 (edited) 51 minutes ago, 0111narwhalz said: Okay, so how does one determine that one is in a partModule or not? And how do you tell a part to have your module? Also, is the snippet I posted earlier incorrect in favor of double d = FlightGlobals.ActiveVessel.verticalSpeed; You'll know your in a partModule because you inherit the class you are writing from PartModule and you add to a part with ModuleManager. You are actually asking a more basic question then I though you were, have you read through the stickies in the Plugin forum and poked around other peoples mods? That's how all of us got started way back when. 40 minutes ago, IgorZ said: Pivot joint feature is available from Squad but there is no "change angle event" as such. The angle is changed by game's physics (e.g. when a force is applied to the vessel). Ouch. In that case, does the position being just slightly out cause issues? My first though at a solution is to stick a FOR loop in a VesselModule that checked the orgPos/orgRot values on each part of the vessel and updated them if needed. To keep overhead down, remember the FOR loop integer index and just check 10 parts per physics update frame. That would be acceptable overhead I think and still have near real-time values on all but the absolute largest vessels. If the value has to be exact then you'd have to check every part every frame and hope the overhead is acceptable. Pseudo-code free-handed: public class VesselModuleUpdatePartPositions : VesselModule { int index = 0; public void FixedUpdate() { for (int i = 1;i++;i <= 10) { Part p = this.vessel.parts[index]; if(boolean check if orgPos/orgRot have changed on part p) { //update values here } index = index +1; if(index > this.vessel.parts.count) { index = 0; } } } } Or something. This works because updated the part orgPos/orgRot doesn't have to be part of the rest of your mod, it just makes them accurate for your mod's use. Edited October 27, 2016 by Diazo Quote Link to comment Share on other sites More sharing options...
IgorZ Posted October 27, 2016 Share Posted October 27, 2016 2 hours ago, Diazo said: Ouch. In that case, does the position being just slightly out cause issues? Positions that are slightly out make no issue to the joint but what does make issues is inconsistent positions on the parts within the vessel. In such case some parts may get shifted relative to the other vessel's parts. I stumbled upon it when tried to update in OnSave: the part of the vessel that was saved before the update had old values in the save file. 2 hours ago, Diazo said: My first though at a solution is to stick a FOR loop in a VesselModule that checked the orgPos/orgRot values on each part of the vessel and updated them if needed. Thanks for idea of using VesselModule. One way or another I'll have to deal with the position/rotation somewhere, and vessel module looks the right place for this code. I'm also going to try detecting vessel's situation change. Saving capability is blocked in some situations (e.g. "moving on surface"), and I could use the trigger to update the vessel since pivot is usually changed by some user or physics interaction (i.e. as a result of situation change). Quote Link to comment Share on other sites More sharing options...
IgorZ Posted October 28, 2016 Share Posted October 28, 2016 @sarbian @Booots @Diazo Guys, thanks for your suggestions. Eventually, I figured out a workaround. It's very far from being cute but at least it doesn't eat performance. I do update of the position/rotation in two steps: In PartModule.OnSave I update all children parts. It doesn't make sense to waste CPU on updating parent part(s) since they either were already updated or don't need it at all (in case of a pivot part was first in the sequence). The problem at this moment is that the part itself is already saved with the wrong values. That's why we need step #2. In GameEvents.onProtoPartSnapshotSave I check if "my" part is being saved, and if it is then the incorrect values are fixed in the config node itself: void onProtoPartSnapshotSave(GameEvents.FromToAction<ProtoPartSnapshot, ConfigNode> action) { if (isLinked && action.to != null && action.from.partRef == part) { var node = action.to; node.SetValue("position", part.orgPos); node.SetValue("rotation", part.orgRot); } } Note. There are some tricks with regard to parent-to-child relation in this approach not reflected in the code snippet. Vessel's root part can change due to docking or a KIS/KAS action, and the hierarchy can get rebuilt so what that parent-child relation is reversed. In my case such situations can be detected pretty easily. I don't like step #2 since it's a source of problems in case of major game change, but it's best I can do for now. Stealing FPS from player just to have parts updated for a probable saving was not an option for me. I've created a feature request for this matter, if it gets fixed one day then the workaround above won't be needed. Quote Link to comment Share on other sites More sharing options...
katateochi Posted October 28, 2016 Share Posted October 28, 2016 If I have a PartModule which I've attached to a docking port, how do I interact with the docking port which this port has docked with? Quote Link to comment Share on other sites More sharing options...
Crzyrndm Posted October 28, 2016 Share Posted October 28, 2016 ModuleDockingNode myDockingModule = part.Modules.GetModule<ModuleDockingNode>(); ModuleDockingNode dockedTo = myDockingModule.otherNode; Part partDockedTo = dockedTo.part; I assume "otherNode" will be null when not docked to anything Quote Link to comment Share on other sites More sharing options...
DMagic Posted October 28, 2016 Share Posted October 28, 2016 (edited) @katateochi Get the docking module on your part, then check if that module's "otherNode" field is null. ModuleDockingNode node = part.FindModuleImplementing<ModuleDockingNode>(); if (node.otherNode != null) { //Do something } Also, otherNode is not null both when docked to another vessel, and when a docking node is tracking another node (ie the magnets are on). Edited October 28, 2016 by DMagic Quote Link to comment Share on other sites More sharing options...
katateochi Posted October 28, 2016 Share Posted October 28, 2016 @Crzyrndm, @DMagic - Thanks guys! Just what I was looking for, and that bit of understanding was like unlocking a plugin development tech node for me, I see how I can do other things now. Quote Link to comment Share on other sites More sharing options...
Faile Posted October 31, 2016 Share Posted October 31, 2016 Hi all, As a personal quality of life improvement I wrote a tiny modulemanager cfg that adds a decouple function to the stock heatshields ( basically what I thought 'decouple shroud' was supposed to do.. @PART[HeatShield*] { MODULE { name = ModuleDecouple ejectionForce = 100 explosiveNodeID = bottom } } For some reason this stopped working in 1.2 and frankly, I have no idea why. Can someone explain to me why this doesn't work anymore? Perhaps suggest how to fix the problem? Quote Link to comment Share on other sites More sharing options...
K0D3R Posted October 31, 2016 Share Posted October 31, 2016 (edited) 2 hours ago, Faile said: Can someone explain to me why this doesn't work anymore? Perhaps suggest how to fix the problem? Not sure why it doesn't work, so can't answer that. I however did make this cfg based on yours and the stock squad decoupler / heatshield configs as examples. Seems to work fine with the minimal testing I did before posting it @PART[HeatShield*] { MODULE { name = ModuleDecouple ejectionForce = 100 isOmniDecoupler = false menuName=Decouple Heat Shield stagingEnabled = true stagingEnableText = HS Decouple Not Staged stagingDisableText = HS Decouple Staged } } Edited October 31, 2016 by K0D3R syntax Quote Link to comment Share on other sites More sharing options...
Faile Posted October 31, 2016 Share Posted October 31, 2016 I got it to work, thanks for the idea of putting all the configs in one section It needed one more change, isOmniDecoupler = false is the default, so basically your cfg is the same as stock, also, it doesn't work as my mod does. The user story is this: "While building my ship, I want to be able to decouple anything attached to the heatshield while keeping the heatshield in place without adding a decoupler." Your config only lets you decouple the heatshield itself ( same as stock functionality ). Here's the working cfg: @PART[HeatShield*] { MODULE { name = ModuleDecouple ejectionForce = 100 menuName=Decouple From Below Heat Shield stagingEnabled = true stagingEnableText = HS Decouple Not Staged stagingDisableText = HS Decouple Staged explosiveNodeID = bottom } } I'll be posting this to spacedock and CKAN in a bit. Quote Link to comment Share on other sites More sharing options...
Fwiffo Posted November 3, 2016 Share Posted November 3, 2016 (edited) Is there any way in a CFG I can include a RetractableLadder module in the default "Gear" action group? (So my ladders extend when my landing gear do, without having to set that up for each craft - similar to the way lights have a defaultActionGroup property) Edited November 3, 2016 by Fwiffo Quote Link to comment Share on other sites More sharing options...
Diazo Posted November 3, 2016 Share Posted November 3, 2016 Not in the .CFG file I do not believe. You can tag a KSPAction in the .dll file to be added to a group by default, but that's in code, not the .CFG file. D. Quote Link to comment Share on other sites More sharing options...
blowfish Posted November 3, 2016 Share Posted November 3, 2016 1 hour ago, Fwiffo said: Is there any way in a CFG I can include a RetractableLadder module in the default "Gear" action group? (So my ladders extend when my landing gear do, without having to set that up for each craft - similar to the way lights have a defaultActionGroup property) I think there might be a way, but you'd have to try it. Try binding the action you want in the editor, and saving the craft. Then look at the craft file, and find the module you are interested in. There should be an ACTIONS node, with a subnode for the one you want. Try putting that into the part's original cfg with the same structure (PART, MODULE, ACTIONS, <action name>). I haven't tried this but I think there's a good chance it will work Quote Link to comment Share on other sites More sharing options...
Fwiffo Posted November 4, 2016 Share Posted November 4, 2016 7 hours ago, blowfish said: I think there might be a way, but you'd have to try it. Try binding the action you want in the editor, and saving the craft. Then look at the craft file, and find the module you are interested in. There should be an ACTIONS node, with a subnode for the one you want. Try putting that into the part's original cfg with the same structure (PART, MODULE, ACTIONS, <action name>). I haven't tried this but I think there's a good chance it will work Thanks! Will try that out. Quote Link to comment Share on other sites More sharing options...
gomker Posted November 5, 2016 Share Posted November 5, 2016 (edited) Any pointers on trying to track down a memory exception error for a Part Module. Debugging in Visual Studio only goes so far as this ends up being a KSP exception Here is some analysis of the crash dump in case someone sees something I am missing Spoiler > KSP_x64_Dbg.exe!RenderNodeQueue::Cleanup(void) Unknown PROBLEM_CLASSES: ******************************************************************************* * * * Exception Analysis * * * ******************************************************************************* DUMP_CLASS: 2 DUMP_QUALIFIER: 400 CONTEXT: (.ecxr) rax=17c1d117f2003df9 rbx=0000000000000000 rcx=0000000000b4ee40 rdx=0000000000000001 rsi=000000001d280570 rdi=00000000204ad870 rip=00007ff77c93e787 rsp=0000000000b4ed90 rbp=0000000000000198 r8=000000000000000d r9=0000000000b4ee40 r10=ffffffffffffffff r11=000000000001b2c8 r12=00000000b4679060 r13=0000000000b4ee40 r14=0000000000000001 r15=0000000000000000 iopl=0 nv up ei pl nz na po nc cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010206 KSP_x64_Dbg!CallbackArrayBase<void (__cdecl*)(IndexList const * __ptr64,RendererCullData const * __ptr64),void (__cdecl*)(void const * __ptr64,IndexList const * __ptr64,RendererCullData const * __ptr64)>::Register+0x71b7: 00007ff7`7c93e787 ffd0 call rax {17c1d117`f2003df9} Resetting default scope FAULTING_IP: KSP_x64_Dbg!CallbackArrayBase<void (__cdecl*)(IndexList const * __ptr64,RendererCullData const * __ptr64),void (__cdecl*)(void const * __ptr64,IndexList const * __ptr64,RendererCullData const * __ptr64)>::Register+71b7 00007ff7`7c93e787 ffd0 call rax EXCEPTION_RECORD: (.exr -1) ExceptionAddress: 00007ff77c93e787 (KSP_x64_Dbg!CallbackArrayBase<void (__cdecl*)(IndexList const * __ptr64,RendererCullData const * __ptr64),void (__cdecl*)(void const * __ptr64,IndexList const * __ptr64,RendererCullData const * __ptr64)>::Register+0x00000000000071b7) ExceptionCode: c0000005 (Access violation) ExceptionFlags: 00000000 NumberParameters: 2 Parameter[0]: 0000000000000000 Parameter[1]: ffffffffffffffff Attempt to read from address ffffffffffffffff PROCESS_NAME: KSP_x64_Dbg.exe ERROR_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%p referenced memory at 0x%p. The memory could not be %s. EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%p referenced memory at 0x%p. The memory could not be %s. EXCEPTION_CODE_STR: c0000005 EXCEPTION_PARAMETER1: 0000000000000000 EXCEPTION_PARAMETER2: ffffffffffffffff FOLLOWUP_IP: KSP_x64_Dbg!CallbackArrayBase<void (__cdecl*)(IndexList const * __ptr64,RendererCullData const * __ptr64),void (__cdecl*)(void const * __ptr64,IndexList const * __ptr64,RendererCullData const * __ptr64)>::Register+71b7 00007ff7`7c93e787 ffd0 call rax INVALID_POINTER_READ Tid [0x5e8] Frame [0x00]: KSP_x64_Dbg!CallbackArrayBase<void IN_CALL Tid [0x5e8] Frame [0x00]: KSP_x64_Dbg!CallbackArrayBase<void Failure Bucketing BUGCHECK_STR: INVALID_POINTER_READ_IN_CALL DEFAULT_BUCKET_ID: INVALID_POINTER_READ_IN_CALL LAST_CONTROL_TRANSFER: from 00007ff77c93e88e to 00007ff77c93e787 STACK_TEXT: 00000000`00b4ed90 00007ff7`7c93e88e : 00000000`00b4ee40 00000000`00000000 00000000`1d280570 00000000`204ad870 : KSP_x64_Dbg!CallbackArrayBase<void (__cdecl*)(IndexList const * __ptr64,RendererCullData const * __ptr64),void (__cdecl*)(void const * __ptr64,IndexList const * __ptr64,RendererCullData const * __ptr64)>::Register+0x71b7 00000000`00b4edd0 00007ff7`7c974537 : 00000000`00000001 00000000`00000000 00000000`1d280570 00000000`204ad870 : KSP_x64_Dbg!CallbackArrayBase<void (__cdecl*)(IndexList const * __ptr64,RendererCullData const * __ptr64),void (__cdecl*)(void const * __ptr64,IndexList const * __ptr64,RendererCullData const * __ptr64)>::Register+0x72be 00000000`00b4ee00 00007ff7`7c97529b : 00000000`00000000 00000000`00000000 00000000`00b5ef31 00000000`1d280570 : KSP_x64_Dbg!IntermediateRenderer::GetCachedWorldAABB+0x5a7 00000000`00b5eec0 00007ff7`7c8fea6c : 00000000`00000000 00000000`1dfa4b00 00000000`00000000 00000000`04b08b60 : KSP_x64_Dbg!IntermediateRenderer::GetCachedWorldAABB+0x130b 00000000`00b5ef90 00007ff7`7c901997 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00b6f2a0 : KSP_x64_Dbg!Camera::DoRender+0x10c 00000000`00b5f020 00007ff7`7c902951 : 00000000`9b894fd0 00000000`044de8e0 00000000`00000000 00000000`bfe65db0 : KSP_x64_Dbg!Camera::Render+0x1d7 00000000`00b6f220 00007ff7`7c94b493 : 00000000`9b894fd0 00000000`204ad870 00007ff7`7da785c8 00000000`044d69f0 : KSP_x64_Dbg!Camera::Render+0x11 00000000`00b6f260 00007ff7`7cbebf17 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : KSP_x64_Dbg!IAnimation::IAnimation+0x1f23 00000000`00b6fa80 00007ff7`7cbec271 : 00000000`00000000 00000000`00000000 00000000`044f9560 00000000`00000000 : KSP_x64_Dbg!CallbackArray1<bool>::Invoke+0x6e7 00000000`00b6fac0 00007ff7`7cbeca5a : 00000000`00000056 00000000`000180aa 00000000`000082fc 00000000`00000000 : KSP_x64_Dbg!CallbackArray1<bool>::Invoke+0xa41 00000000`00b6faf0 00007ff7`7cd1a0e0 : 00000000`000007ec 00000000`00000000 00000000`00000001 00000000`00000001 : KSP_x64_Dbg!CallbackArray1<bool>::Invoke+0x122a 00000000`00b6fb40 00007ff7`7cd1a8da : 00000000`000007ec 00000000`00b6fce0 00000000`00000000 00000000`00000000 : KSP_x64_Dbg!IntermediateRenderer::GetLayer+0x3450 00000000`00b6fb70 00007ff7`7cd1e5bc : 00000000`00000000 00000000`00000000 00000000`00000004 00000000`00b6fce0 : KSP_x64_Dbg!PlayerMainWndProc+0x6ba 00000000`00b6fbe0 00007ff7`7d27bbe0 : 00000000`00000000 00000000`00000000 00007ff7`7c8a0000 00000000`00000000 : KSP_x64_Dbg!PlayerWinMain+0xf1c 00000000`00b6fe00 00007ffe`e64f8364 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : KSP_x64_Dbg!RectT<int>::GetRight+0xa5650 00000000`00b6feb0 00007ffe`e6ec5e91 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : kernel32!BaseThreadInitThunk+0x14 00000000`00b6fee0 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x21 Trying to troubleshoot an issue with BDArmory Rotary Bomb Rail. I can edit the part (right click has gui options) just fine the first time. Once you move your mouse off the part then select the part again the game crashes. Part module code can be found here Edited November 5, 2016 by gomker Quote Link to comment Share on other sites More sharing options...
Fwiffo Posted November 6, 2016 Share Posted November 6, 2016 (edited) When you use "Control from Here", is the "from here" always the origin (typically CoM) of the selected part? I ask because I know when you include docking ports in a weldment, and say "Set as target", the game seems smart enough to use the docking port coordinates as the target rather than the selected part's origin/CoM. (Which is great; although I'd love to know how that works, e.g. if it looks for something specific in the mesh...) EDIT: Nevermind I found this which I think will answer my question. Edited November 6, 2016 by Fwiffo Quote Link to comment Share on other sites More sharing options...
TaxiService Posted November 7, 2016 Share Posted November 7, 2016 (edited) Let's say I create a subclass 'SheepVesselModule' based on the KSP's existing class 'VesselModule'. Then, I just compile and launch KSP without any further action. I observe that the KSP actually accepts and integrates my "orphan" class into every existing vessel. It even calls some methods like Start() too. Is this one of the Unity's strengths, or I misinterpret the result? Edited November 7, 2016 by TaxiService 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.