Cephei

The official unoffical "help a fellow plugin developer" thread

Recommended Posts

11 minutes ago, katateochi said:

Hi guys, got a couple Qs about file I/O. 
Is there a method that returns the root path of the KSP instance the plugin is running in, or what's the best way to locate and read a file (ie a config file) in the mod's folder?  
Is there a standard way of detecting OS and handling OS specific file paths?
Thanks!

KSPUtil.ApplicationRootPath and  Path.DirectorySeparatorChar should do the trick, but for most case / works fine

  • Like 3

Share this post


Link to post
Share on other sites
26 minutes ago, sarbian said:

KSPUtil.ApplicationRootPath and  Path.DirectorySeparatorChar should do the trick, but for most case / works fine

wow that was quick! Just what I was looking for, thankyou! 

Share this post


Link to post
Share on other sites

Are values in KSPFields for a plugin instanced per vessel or shared somehow? I have an odd issue where I am recording the Vessel position as so

[KSPField(isPersistant = true, guiActive = false)]
Vector3 ParkPosition = new Vector3(0f, 0f, 0f);

parkfunction()
{
//
	ParkPosition = vessel.GetWorldPos3D();
//
}

I have one vessel(A) parked at 3KM from airfield. I launch vessel(B) and approach.
As soon as Vessel(B) comes into physics range of Vessel(A) the value for "ParkPostion" in Vessel(B) shows up for Vessel(B)

I had some other code (I took over this project from another dev) that I think was supposed to record the position when saving

        public override void OnSave(ConfigNode node)
        {
            base.OnSave(node);
            if (vessel != null ){ ParkPosition = vessel.GetWorldPos3D(); }
            
        }

It appears I am not storing the values correctly, but I am confused as to how a value seems to be jumping from vessel to vessel.

Edited by gomker

Share this post


Link to post
Share on other sites
2 minutes ago, blowfish said:

is this on a VesselModule?

I did not know that was a thing, I am a bit new to all this, I didn't see anything like that in API docs - my class declaration is 

public class Airpark : PartModule

 

Share this post


Link to post
Share on other sites
1 minute ago, gomker said:

I did not know that was a thing, I am a bit new to all this, I didn't see anything like that in API docs - my class declaration is 


public class Airpark : PartModule

 

PartModule fields are all unique - every instance of the part will have a separate PartModule.  If these values are turning up the same something else must be happening.  Hard to say exactly what though.  If you want some help debugging maybe post all the code in this class (or that touches it) so we can take a look.

Share this post


Link to post
Share on other sites

@blowfish Thanks for tipping me on to that I found this , but it seems it wont completely solve my issue as I would like to save the state persistently 

I just started reading it though , there may be other ways. 

//Edit - If you want to see the full code you can peruse my attempts to fix in my branches here

Thanks again!

Edited by gomker

Share this post


Link to post
Share on other sites
3 hours ago, blowfish said:

 If you want some help debugging maybe post all the code in this class (or that touches it) so we can take a look.

I pushed my latest changes here 

The issues only manifests itself when both Vessels have the Part with the module on them. If one does not the values do not jump from vessel to vessel.

Share this post


Link to post
Share on other sites

You save your position as a vector3 instead of a vector3d (as returned by GetWorldPos3D). The precision loss is most likely making the numbers equal. 

Also : planets move so your plugin current logic may be flawed 

  • Like 1

Share this post


Link to post
Share on other sites

Hi all,

How does one go about accessing the text in the vessel name field within the editor? ie, new craft are called Untitled Space Craft.

I've tried the obvious part.vessel.name, etc to no avail.

Share this post


Link to post
Share on other sites
4 hours ago, udk_lethal_d0se said:

Hi all,

How does one go about accessing the text in the vessel name field within the editor? ie, new craft are called Untitled Space Craft.

I've tried the obvious part.vessel.name, etc to no avail.

I found how to get the current ship name in the editors, but I don't know how to set it;

EditorLogic.fetch.ship.shipName;

Update - found another way to fetch the name which also allows setting it;

string name = EditorLogic.fetch.shipNameField.text; //get the name
EditorLogic.fetch.shipNameField.text = "foo"; 	    //set the name

 

 

So I have a bit of a puzzlement (probably means I've misunderstood something).
I have a couple of test classes which inherit MonoBehaviour and have attributes tags which, I thought, defined what scene they'd apply to. One has the tag for the VAB and the other for the SPH, but the output to the log shows that both are being called when entering either editor.  

	[KSPAddon(KSPAddon.Startup.EditorVAB, false)]
	public class TestOne : MonoBehaviour
	{ 
		private void Start()
		{ 
			Debug.Log (("IM IN THE VAB"));
		} 
	}

	[KSPAddon(KSPAddon.Startup.EditorSPH, false)]
	public class TestTwo : MonoBehaviour
	{ 
		private void Start()
		{ 
			Debug.Log (("IM IN THE SPH"));
		}
	}

When I go into either editor I see the output from each of them, but not in other scenes (at least not in the main menu or space center).  So the attribute tag is preventing them from being called in other scenes, but what I'm seeing is what I'd expect if the attribute tag on both was [KSPAddon(KSPAddon.Startup.EditorAny, false)]

This is what I see when going into the VAB;
u88LUpb.png


Also, is there a better way of determining which editor you are in?

 

Edited by katateochi

Share this post


Link to post
Share on other sites
On 9/10/2016 at 0:34 AM, sarbian said:

You save your position as a vector3 instead of a vector3d (as returned by GetWorldPos3D). The precision loss is most likely making the numbers equal. 

Also : planets move so your plugin current logic may be flawed 

Ah, learned something new. I saw some discussion around that topic , is using vessel.transform.position any better in this case?  I see that comes back as a Vector3 and not Vector3d.   I am also taking a crack at transforming this into a VesselModule, that update is here, but I seem to be running into the same issue of  of values being shared. I've worked out how to save the data with this post

Thanks

Share this post


Link to post
Share on other sites

vessel.transform.position is only really useful inside the active physics bubble (ie. positions between two relatively close objects). It has no meaning if you're trying to save the position (worldPos3D isn't exactly that great either since while it gives you a constant position, that doesn't matter much when everything else is moving). I would be looking to hold onto the position relative to the planet with something like: (don't trust untested Quats...)

double altitude = vessel.altitude; // length of the vector
Vector3d upVec = (vessel.transform.position - vessel.mainbody.position).normalized;
Quaternion planetPosRot = Quaternion.FromToRotation(vessel.mainbody.rotation * Vector3d.up, upVec); // orientation of the vector

// recovery
Vector3d planetRelativePos = (vessel.mainbody.rotation * planetPosRot) * Vector3d.up * altitude - (refPos - planetPos);

 

Edited by Crzyrndm
  • Like 1

Share this post


Link to post
Share on other sites

Hi, I'm almost done adding some functionalities to an exiting mod, and I've encountered a few problems that I need help with:

  1. Is there a way to update the GUI editor of a field? I've discovered that when I change the value of a field (tagged with KSPField) at runtime the UI doesn't update. 
  2. Is there a simple ways to determine in a mirror symmetry which part is flipped? I've added thrust deflection (angle) on ProceduralSRBs but I can't get the mirror symmetry to work properly. I need to flip the rotation of one of the two but I can't find a reliable way to tell which one it is. (I've just spent all the weekend trying to figure this one out and it kept me awake the last two nights :confused: and adding thrust deflection just took about 5 minutes...;.;)
  3. Also I'm wondering if it is possible to reorder GUI editor fields, and if possible from other modules. I find it annoying that the order the fields are placed in code affect the order they appear in-game.

Share this post


Link to post
Share on other sites
10 hours ago, Polymaker said:

Is there a way to update the GUI editor of a field? I've discovered that when I change the value of a field (tagged with KSPField) at runtime the UI doesn't update. 

Do you mean the text of the field? I just run an update to the value in onFixedUpdate() to update my debug values I want to monitor in real time check in my PartModule.

I should probably do a proper debug message, but I am just getting started and wanted immediate satisfaction :)

        [KSPField(isPersistant = true, guiActive = true]
        public string vesselSituation;

		public void FixedUpdate()
		{
		vesselSituation = vessel.situation.ToString();

		}

You can break things by putting in values that aren't text friendly, so careful on the types

13 hours ago, Crzyrndm said:

don't trust untested Quats

I trust no Quats ( now I need to go read up on what they are :) )  This sounds promising I will implement and see what happens. If I can get these values to persist per vessel correctly I can move on to fixing the position.

Edited by gomker

Share this post


Link to post
Share on other sites
13 minutes ago, gomker said:

Do you mean the text of the field? I just run an update to the value in onFixedUpdate() to update my debug values I want to monitor in real time check in my PartModule.

I should probably do a proper debug message, but I am just getting started and wanted immediate satisfaction :)


        [KSPField(isPersistant = true, guiActive = true]
        public string vesselSituation;

		public void FixedUpdate()
		{
		vesselSituation = vessel.situation.ToString();

		}

You can break things by putting in values that aren't text friendly or it will break your whole gui

Yes... and no, I'm not too sure now, as I'm doing almost the same as you. But a real example will better explain my question: In ProceduralParts, I added a Mk2 shape and I wanted to snap 1.25m to 1.5m when you select that shape. So in the OnUpdate event I check if the selected shape changed and if the current diameter  is 1.25, then I set the diameter field to 1.5m, but the editor in-game still shows 1.25m (until I re-open the right-click menu).

Edited by Polymaker

Share this post


Link to post
Share on other sites
28 minutes ago, Polymaker said:

but the editor in-game still shows 1.25m (until I re-open the right-click menu).

I think you and I are running into a similar issue. I am migrating to a VesselModule which has some different behavior and I am unsure on when the onGUI() fires for my menu for the toolbar. I assume there is different behavior in the editor than when in flight, but I have not found a reference for that describes the behavior, only things on PartModule and VesselModule.

Share this post


Link to post
Share on other sites

Or you could use:
MonoUtilities.RefreshContextWindows(Part);

Edited by JPLRepo

Share this post


Link to post
Share on other sites
9 hours ago, blowfish said:

You can refresh the UI part action window using some code like this.

It works, thanks a lot!

That code also helped me with my third question (about re-ordering a part's fields/editors). Now I know that UIPartActionWindow has a list of UIPartActionItem and items of type UIPartActionFieldItem are linked to the module field. Then what I think is the display order is the sibling index on the action's transform. Now I want to test it out, but I'm not sure where/when to call the code, I'm sure it would work in OnUpdate, but I don't want to reorder each frame (it may affect performance). So my question is: Is there any event triggered when a part is selected in the editor, or even better if there is an event when the part's window is displayed? If so, how do I listen to it (I'm still not too familiar how Unity or KSP event pipeline works)? 

P.S. I can't thank the universe enough for the existence of .NET, reflection and ILSpy :D

Edited by Polymaker
English grammar...

Share this post


Link to post
Share on other sites
On 9/10/2016 at 9:05 PM, katateochi said:

When I go into either editor I see the output from each of them, but not in other scenes (at least not in the main menu or space center).  So the attribute tag is preventing them from being called in other scenes, but what I'm seeing is what I'd expect if the attribute tag on both was [KSPAddon(KSPAddon.Startup.EditorAny, false)]

Take a look at the definition of KSPAddon.Startup.  It was changed (in 0.90 I believe) so that EditorSPH, EditorVAB and EditorAny are all the same value.  This is because they both use the same scene just with different models and tweaked editing behaviour (that allows you to switch to either style of editor in either editor).

You may need to decide if you want to vary your behaviour on which building they are in or by what mode the editor is currently is.  The editorType member of EditorLogic may be useful.  You may be able to read it when your object starts (before the user has a chance to switch) to vary by which building you are in or you might want to read it before doing anything to vary the behaviour by mode.

Share this post


Link to post
Share on other sites

Thanks @Padishar, that makes sense now. I'm still very new writing KSP plugins, when you say take a look at the definition, where should I be looking? I'm currently using http://docuwiki-kspapi.rhcloud.com/ as a reference, which seems to still suggest that there's a different behaviour between EditorSPH and EditorVAB.  
It also has marked EditorLogic.editorType as deprecated and if I try to use it I get a build error saying 'EditorLogic' does not contain a definition for 'editorType'.  
All I need is to be able to choose the path saves/<current_save>/Ships/<SPH or VAB> depending on which editor I'm in.
Also tried this Debug.Log ("Editor:" + HighLogic.CurrentGame.editorFacility.ToString ()); but that seems to always return None.

EDIT
I just found that I can get the editor facility from this: 

EditorLogic.fetch.ship.shipFacility

Seems to work ok, even after loading a ship from the other editor, but it seems like a rather circuitous route to getting the current editor. 

Edited by katateochi

Share this post


Link to post
Share on other sites

Each scroll bar has several styles (background, thumb etc) but you can only set one in the GUILayout.BeginScrollView() so how do I set both the background style and thumb style?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now