Cephei

The official unoffical "help a fellow plugin developer" thread

Recommended Posts

17 minutes ago, linuxgurugamer said:

Have you tried removing the extra button from the PAW?

I have (I assume you mean by changing guiActive to false, unless there is another way to do this) - this just removes both buttons, so they seem to be linked to the same Event.

16 minutes ago, DMagic said:

KSP uses reflection to grab all of the events, so maybe it's catching your cached event list somehow. See what happens if you move the process out of start and instead wait a few frames or seconds. Maybe the base part's event loading process occurs after the part module process.

I did originally move it to FixedUpdate but that was probably not waiting long enough.

I actually just figured out a solution (as you always do just after you post for help!)

                       foreach (BaseEvent e in pm.Events)
                        {
                            int id = e.id;
                            myEventList.Add(pm.Events[id]);
                        }

Adding the Event by ID seems to bypass whatever the issue is. Probably what @DMagic said though, as my list would be referencing the original event, which would explain why both buttons disappear when removed.

Edited by severedsolo
  • Like 1

Share this post


Link to post
Share on other sites

Hi,

I am trying to find out if KSP has a GameEvent or some kind of notification on part deployment (can be antenna, solar panel, landing gear etc) and ActionGroup (eg toggle antenna extend/retract). The closest one I can find is `GameEvents.onPartActionUIDismiss` which is almost suitable for me. But I am not finding an easy way to hook to ActionGroup activation.

The reason for this is to run some update codes on demand, rather than FixedUpdate() pulse to check and run if change is detected.

Thanks!

Edited by TaxiService

Share this post


Link to post
Share on other sites
5 hours ago, TaxiService said:

Hi,

I am trying to find out if KSP has a GameEvent or some kind of notification on part deployment (can be antenna, solar panel, landing gear etc) and ActionGroup (eg toggle antenna extend/retract). The closest one I can find is `GameEvents.onPartActionUIDismiss` which is almost suitable for me. But I am not finding an easy way to hook to ActionGroup activation.

The reason for this is to run some update codes on demand, rather than FixedUpdate() pulse to check and run if change is detected.

Thanks!

I haven't done this myself, but you can register your own custom games events now in 1.3. I would think you would have to check the state of any part modules on the vessel in question

Share this post


Link to post
Share on other sites
8 hours ago, TaxiService said:

 But I am not finding an easy way to hook to ActionGroup activation.

You could modify/replace Base[Action/Event] delegates to fire a custom GameEvent for you. That's how I'd do it

  • Like 1

Share this post


Link to post
Share on other sites

@Bonus Eventus @xEvilReeperx Do you have some keywords/tips on BaseEvent, BaseAction and GameEvent for this functionality to help my learning? I am testing some of these things, included UIPartActionController.

EDIT: Never mind, I found one easy way. ModuleDeployablePart has two EventData for moving and stop animations. I just add my own callback to these and both ActionGroup and extend/retract click call mine. Thanks for pointing me towards EventData!

Edited by TaxiService
  • Like 2

Share this post


Link to post
Share on other sites

Warning: Absolute n00b here.

So, I'm having the following error:

Error    CS0103    The name 'RenderingManager' does not exist in the current context 

I can't figure out why this error is happening, I've added UnityEngine and Assembly-CSharp as references. 

How do I fix this?

complete code, if needed:

(This is taken from a sample plugin project)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;


namespace SignalTracking
{
    /// <summary>
    /// My first part!
    /// </summary>
    public class SelfDestruct : Part
    {
        protected Rect windowPos;

        private void WindowGUI(int windowID)
        {
            GUIStyle mySty = new GUIStyle(GUI.skin.button);
            mySty.normal.textColor = mySty.focused.textColor = Color.white;
            mySty.hover.textColor = mySty.active.textColor = Color.yellow;
            mySty.onNormal.textColor = mySty.onFocused.textColor = mySty.onHover.textColor = mySty.onActive.textColor = Color.green;
            mySty.padding = new RectOffset(8, 8, 8, 8);

            GUILayout.BeginVertical();
            if (GUILayout.Button("DESTROY", mySty, GUILayout.ExpandWidth(true)))//GUILayout.Button is "true" when clicked
            {
                this.explode();
                this.onPartDestroy();
                this.Die();
            }
            GUILayout.EndVertical();

            //DragWindow makes the window draggable. The Rect specifies which part of the window it can by dragged by, and is 
            //clipped to the actual boundary of the window. You can also pass no argument at all and then the window can by
            //dragged by any part of it. Make sure the DragWindow command is AFTER all your other GUI input stuff, or else
            //it may "cover up" your controls and make them stop responding to the mouse.
            GUI.DragWindow(new Rect(0, 0, 10000, 20));

        }
        private void drawGUI()
        {
            GUI.skin = HighLogic.Skin;
            windowPos = GUILayout.Window(1, windowPos, WindowGUI, "Self Destruct", GUILayout.MinWidth(100));
        }
        protected override void onFlightStart()  //Called when vessel is placed on the launchpad
        {
            RenderingManager.AddToPostDrawQueue(3, new Callback(drawGUI));//start the GUI
        }
        protected override void onPartStart()
        {
            if ((windowPos.x == 0) && (windowPos.y == 0))//windowPos is used to position the GUI window, lets set it in the center of the screen
            {
                windowPos = new Rect(Screen.width / 2, Screen.height / 2, 10, 10);
            }
        }
        protected override void onPartDestroy()
        {
            RenderingManager.RemoveFromPostDrawQueue(3, new Callback(drawGUI)); //close the GUI
        }

    }
}

 

Share this post


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

How do I fix this?

RenderingManager is not present in current KSP version. Have a look at that post to see how to replace it

 

  • Like 1

Share this post


Link to post
Share on other sites

Thanks @sarbian, at least I can compile now. But it still is not working. I have changed the code to look like this: 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;


namespace SignalTracking
{
    /// <summary>
    /// My first part!
    /// </summary>
    public class testMod : Part
    {
        protected Rect windowPos;
        bool g = true;
        private void WindowGUI(int windowID)
        {
            GUIStyle mySty = new GUIStyle(GUI.skin.button);
            mySty.normal.textColor = mySty.focused.textColor = Color.white;
            mySty.hover.textColor = mySty.active.textColor = Color.yellow;
            mySty.onNormal.textColor = mySty.onFocused.textColor = mySty.onHover.textColor = mySty.onActive.textColor = Color.green;
            mySty.padding = new RectOffset(8, 8, 8, 8);

            GUILayout.BeginVertical();
            if (GUILayout.Button("DESTROY", mySty, GUILayout.ExpandWidth(true)))//GUILayout.Button is "true" when clicked
            {
                this.explode();
                this.onPartDestroy();
                this.Die();
            }
            GUILayout.EndVertical();

            //DragWindow makes the window draggable. The Rect specifies which part of the window it can by dragged by, and is 
            //clipped to the actual boundary of the window. You can also pass no argument at all and then the window can by
            //dragged by any part of it. Make sure the DragWindow command is AFTER all your other GUI input stuff, or else
            //it may "cover up" your controls and make them stop responding to the mouse.
            GUI.DragWindow(new Rect(0, 0, 10000, 20));

        }
        private void drawGUI()
        {
            GUI.skin = HighLogic.Skin;
            windowPos = GUILayout.Window(1, windowPos, WindowGUI, "Self Destruct", GUILayout.MinWidth(100));
        }
        private void OnGUI()
        {
            
            if (g) {
                drawGUI(); // Your current on postDrawQueue code
            }
        }
        protected override void onPartStart()
        {
            if ((windowPos.x == 0) && (windowPos.y == 0))//windowPos is used to position the GUI window, lets set it in the center of the screen
            {
                windowPos = new Rect(Screen.width / 2, Screen.height / 2, 10, 10);
            }
        }
        protected override void onPartDestroy()
        {
            g = false;
        }

    }
}

Also, I might be putting it in the cfg wrong. Do I just go 

MODULE
	{
		name = testMod
    }

, or is that the wrong way to do it?

Share this post


Link to post
Share on other sites
11 hours ago, pydude said:

I have changed the code to look like this

Oh, I did not saw the first line. it should be 

public class testMod : PartModule

How old is the tutorial you are using ? 

Have a look at this one 

 

Share this post


Link to post
Share on other sites

@Sarbian Thanks for that tutorial. The one I was using was 5 years old! Now, I have a few questions.

1. What is the scene for the map view? The one that comes up when you press "m" during flight.

2. How can I get the current CommNet signal strength of the active vessel?

Thanks.

Share this post


Link to post
Share on other sites
  1. It's the normal flight scene. The difference is that MapView.MapIsEnabled is true
  2. vessel.connection.SignalStrength or vessel.connection.Signal depending if your need a state or a value.

Share this post


Link to post
Share on other sites

@sarbian Thanks! Finally my mod actually does something! Another question, however: How can I disable patched conics altogether? To make it look like before you upgrade the Tracking Station, just the grey lines?

Edited by pydude

Share this post


Link to post
Share on other sites

Does anyone happen to know how the game resolves PLANETARY_RESOURCE clashes between two different mods? If each mod has its own ResourceDef file, of the form:

PLANETARY_RESOURCE
{
	ResourceName = LqdDeuterium
	ResourceType = 2
	PlanetName = Jool
	
	Distribution
	{
		PresenceChance = ...
		MinAbundance = ...
		MaxAbundance = ...
		Variance = ...
	}
}

Such that each mod is declaring a PLANETARY_RESOURCE for LqdDeuterium, ResourceType = 2, PlanetName = Jool, however each mod has different Distribution parameters. Looking at the ModuleManager.ConfigCache file, both entries are in the cache, however, does the game choose only one of them? If yes, then how does it choose?

Share this post


Link to post
Share on other sites

 

2 hours ago, trias702 said:

Does anyone happen to know how the game resolves PLANETARY_RESOURCE clashes between two different mods? If each mod has its own ResourceDef file, of the form:


PLANETARY_RESOURCE
{
	ResourceName = LqdDeuterium
	ResourceType = 2
	PlanetName = Jool
	
	Distribution
	{
		PresenceChance = ...
		MinAbundance = ...
		MaxAbundance = ...
		Variance = ...
	}
}

Such that each mod is declaring a PLANETARY_RESOURCE for LqdDeuterium, ResourceType = 2, PlanetName = Jool, however each mod has different Distribution parameters. Looking at the ModuleManager.ConfigCache file, both entries are in the cache, however, does the game choose only one of them? If yes, then how does it choose?

I dont know how it handles it, but it is bad. Contact the mod authors to try and get it worked out. 

Share this post


Link to post
Share on other sites
On 8/1/2017 at 9:20 PM, pydude said:

@sarbian Thanks! Finally my mod actually does something! Another question, however: How can I disable patched conics altogether? To make it look like before you upgrade the Tracking Station, just the grey lines?

For a specific vessel / object or for all of them ? Have a look at vessel.discoveryInfo 

Share this post


Link to post
Share on other sites

@sarbianI want to do this for a vessel. discoveryInfo seems to be for asteroids, not ships. Are there ways to disable patched conics for vessels?

Share this post


Link to post
Share on other sites
Just now, pydude said:

I want to do this for a vessel. discoveryInfo seems to be for asteroids, not ships.

Keep in mind that asteroids are a subset of vessels.

  • Like 1

Share this post


Link to post
Share on other sites

How can I change discoveryInfo.trackingStatus? I assume that this the relevant property. If I do 

vessel.DiscoveryInfo.trackingStatus=1;

for example, it says 


Error	CS0029	Cannot implicitly convert type 'int' to 'KnowledgeItem<string>'

How do I actually change this? 

Share this post


Link to post
Share on other sites
23 minutes ago, pydude said:

How can I change discoveryInfo.trackingStatus? I assume that this the relevant property. If I do 


vessel.DiscoveryInfo.trackingStatus=1;

for example, it says 



Error	CS0029	Cannot implicitly convert type 'int' to 'KnowledgeItem<string>'

How do I actually change this? 

vessel.DiscoveryInfo.trackingStatus is a string so you can only set it to strings. I don't know what the valid options for it but you could easily use Debug.Log(vessel.DiscoveryInfo.trackingStatus) to tell you what it's current value is and then figure out other accepted values from there.

Edited by TheRagingIrishman
  • Like 1

Share this post


Link to post
Share on other sites

@TheRagingIrishmanActually, I already tried this. It just says the  same thing except "cannot convert type 'string'" instead of 'int'. vessel.DiscoveryInfo.trackingStatus is a type "KnowledgeItem<string>", but I have no idea how to use one.

Share this post


Link to post
Share on other sites
Just now, pydude said:

@TheRagingIrishmanActually, I already tried this. It just says the  same thing except "cannot convert type 'string'" instead of 'int'. vessel.DiscoveryInfo.trackingStatus is a type "KnowledgeItem<string>", but I have no idea how to use one.

Looks like the constructor takes quite a few parameters:

https://kerbalspaceprogram.com/api/class_knowledge_item_3_01_t_01_4.html

KnowledgeItem< T >.KnowledgeItem(
	DiscoveryInfo 	host,
	DiscoveryLevels 	itemLevel,
	string 	caption,
	string 	valueFallback,
	UpdateDataCallback 	updateValueCallback,
	string 	suffix = "",
	string 	format = "" 
)

... but it's not clear that replacing the object is the right choice. What about something like this?

vessel.DiscoveryInfo.trackingStatus.ItemLevel = DiscoveryLevels.Owned;

Or possibly

vessel.DiscoveryInfo.SetLevel(DiscoveryLevels.Owned);

 

  • Like 1

Share this post


Link to post
Share on other sites

@HebaruSan

vessel.DiscoveryInfo.SetLevel(DiscoveryLevels.Owned);

does not work for my purposes because that method does not allow changing individual properties.  

vessel.DiscoveryInfo.trackingStatus.ItemLevel = DiscoveryLevels.Owned;

just flat out doesn't work, saying 

Error	CS1061	'KnowledgeItem<string>' does not contain a definition for 'ItemLevel' and no extension method 'ItemLevel' accepting a first argument of type 'KnowledgeItem<string>' could be found (are you missing a using directive or an assembly reference?)

The whole reason I'm messing around with this is to try to disable patched conics for the vessel. I'm trying to make it like Tracking Station level 1, with just the grey orbit lines. Do you know of any other ways to do this? 

Share this post


Link to post
Share on other sites

 

9 minutes ago, pydude said:

vessel.DiscoveryInfo.trackingStatus.ItemLevel = DiscoveryLevels.Owned;

just flat out doesn't work, saying 


Error	CS1061	'KnowledgeItem<string>' does not contain a definition for 'ItemLevel' and no extension method 'ItemLevel' accepting a first argument of type 'KnowledgeItem<string>' could be found (are you missing a using directive or an assembly reference?)

Oh oops, that property is private. Which also rules out selectively copying the properties of the old object into a new object.

9 minutes ago, pydude said:

@HebaruSan


vessel.DiscoveryInfo.SetLevel(DiscoveryLevels.Owned);

does not work for my purposes because that method does not allow changing individual properties.  

9 minutes ago, pydude said:

The whole reason I'm messing around with this is to try to disable patched conics for the vessel. I'm trying to make it like Tracking Station level 1, with just the grey orbit lines. Do you know of any other ways to do this? 

The DiscoveryLevels enum is designed to allow multiple values, and I assume StateVectors and Appearance control the orbit lines and whether you're allowed to switch to it; what about leaving them out?

vessel.DiscoveryInfo.SetLevel(DiscoveryLevels.Presence | DiscoveryLevels.Name);

 

Share this post


Link to post
Share on other sites

@HebaruSanThat did not work either. It changed the ship's icon to the question mark, but patched conics were still rendered. And, obviously, the icon should not change. Any other ideas?

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