Jump to content

The official unoffical "help a fellow plugin developer" thread


Recommended Posts

I'm making my first foray into KSP Plugin development.  I am writing two PartModules in the plugin and I need to be able to drain and fill custom resources. I have a couple of stand-in test parts and a Resources.cfg file defining the three custom resources.  One part module will take two of the custom resources and generate the third, which is drawn by the second part module.  I realize that this behavior can be accomplished with stock modules, but I would like a little more control than say ModuleResourceConverter or ModuleGenerator provide.

So, I need to be able to find the amount of a custom resource on the vessel, drain it using the flow priority if possible, and fill reservoirs with the products.  I've been looking at the API and some other plugins but have not been able to find what I need, or am not recognizing it when I see it.

Link to comment
Share on other sites

17 hours ago, TheShadow1138 said:

So, I need to be able to find the amount of a custom resource on the vessel, drain it using the flow priority if possible, and fill reservoirs with the products.  I've been looking at the API and some other plugins but have not been able to find what I need, or am not recognizing it when I see it.

For the first one, here is the code I'd use:

int resourceid = PartResourceLibrary.Instance.GetDefinition("yourResourceName").id;
this.vessel.GetConnectedResourceTotals(resourceid, out double amount, out double maxAmount);

For the second one:

this.vessel.RequestResource(this.part, resourceid, rate * Time.fixedDeltaTime, true)

rate is measured in units/second, you have to multiply by Time.fixedDeltaTime to reduce the correct amount of the resource per frame. The last input parameter is usePriority, which I've set to true here as you've said. You can change this.part to any part you want on the vessel that you need to drain resources from.

You can add the same resource to a vessel through the same code above, except make the rate negative (-rate).

Hope this helps. :) 

Edited by Aniruddh
Link to comment
Share on other sites

38 minutes ago, Aniruddh said:

For the first one, here is the code I'd use:


int resourceid = PartResourceLibrary.Instance.GetDefinition("yourResourceName").id;
this.vessel.GetConnectedResourceTotals(resourceid, out double amount, out double maxAmount);

For the second one:


this.vessel.RequestResource(this.part, resourceid, rate * Time.fixedDeltaTime, true)

rate is measured in units/second, you have to multiply by Time.fixedDeltaTime to reduce the correct amount of the resource per frame. The last input parameter is usePriority, which I've set to true here as you've said. You can change this.part to any part you want on the vessel that you need to drain resources from.

You can add the same resource to a vessel through the same code above, except make the rate negative (-rate).

Hope this helps. :) 

Thank you!  That's exactly what I needed.  The parts fill and drain as expected now!  It did take me a couple of tries because of a typo and having to realize that I needed to declare the "amount" and "maxAmount" variables before using them.  MonoDevelop wouldn't allow me to declare those variables in the statement like you showed stating it wasn't allowed by the C# 6.0 specification, but I declared the variables before using that call and it works beautifully.  Thank you again.

Link to comment
Share on other sites

7 hours ago, garwel said:

Is there a simple way to check whether the active vessel has any running engines (i.e. under thrust)?

Try Vessel.ctrlState.isNeutral.  If you only care about the throttle, you may instead want to check Vessel.ctrlState.mainThrottle == 0.0f.  Not sure how this handles having no active engines (because of staging or being out of fuel), so you'll want to do some testing with those situations.

Link to comment
Share on other sites

3 hours ago, nightingale said:

Try Vessel.ctrlState.isNeutral.  If you only care about the throttle, you may instead want to check Vessel.ctrlState.mainThrottle == 0.0f.  Not sure how this handles having no active engines (because of staging or being out of fuel), so you'll want to do some testing with those situations.

Thanks, will try isNeutral. The main throttle is bad, because it doesn't take into account whether engines are ignited or not, and because it doesn't affect SRBs.

Link to comment
Share on other sites

1 minute ago, garwel said:

Thanks, will try isNeutral. The main throttle is bad, because it doesn't take into account whether engines are ignited or not, and because it doesn't affect SRBs.

You may also need to look at Vessel.acceleration in the case of SRBs - but if you're not in orbit it's going to have a gravity component to it as well, so that may be ugly.

Link to comment
Share on other sites

 I am trying to replace the Text elements in the UI of the Persistent Thrust mod with TextMeshPro elements; I followed Dmagic's guide on how to use Unity's new prefab based UI (in fact, that's how the entire UI was built) and I basically copied his code, but for some reason there is one thing that isn't working: text alignment. Every text field is reset to upper left alignment when converted to TMP. I've checked with the debugger, and the code to convert and assign the alignment style works fine, so there must be something between TMP component creation and UI initialization that is resetting the option; possibly TMP itself, but I have no idea. There's also a different issue, which is that TMP font size doesn't correspond to Text font size; specifically, TMP text is always smaller. This is a minor issue compared to alignment completely breaking, so I can ignore it for the moment.

I the only thing I was able to find online was this thread (read the last answer, which seemed the most useful), but I wasn't able to set that field through reflection. It is indeed false at initialization and true when the UI is actually loaded, so it might have to do with the issue.

The code is all available on github, but I'll post the TMProFromText method code here anyway, since I guess that's where the error lies. If anyone has any idea why this is happening, please let me know since I really can't find any error.

Spoiler

private void TMProFromText(TextHandler handler)
{
	if (handler == null)
		return;

	//The TextHandler element should be attached only to objects with a Unity Text element
	//Note that the "[RequireComponent(typeof(Text))]" attribute cannot be attached to TextHandler since Unity will not allow the Text element to be removed
	Text text = handler.GetComponent<Text>();

	if (text == null)
		return;

	//Cache all of the relevent information from the Text element
	string t = text.text;
	Color c = text.color;
	int i = text.fontSize;
	bool r = text.raycastTarget;
	FontStyles sty = TMPProUtil.FontStyle(text.fontStyle);
	TextAlignmentOptions align = TMPProUtil.TextAlignment(text.alignment);
	float spacing = text.lineSpacing;
	GameObject obj = text.gameObject;

	//The existing Text element must by destroyed since Unity will not allow two UI elements to be placed on the same GameObject
	DestroyImmediate(text);

	PTTextMeshProHolder tmp = obj.AddComponent<PTTextMeshProHolder>();

	//Populate the TextMeshPro fields with the cached data from the old Text element
	tmp.text = t;
	tmp.color = c;
	tmp.fontSize = i;
	tmp.raycastTarget = r;
	tmp.alignment = align;
	tmp.fontStyle = sty;
	tmp.lineSpacing = spacing;

	//Load the TMP Font from disk
	tmp.font = UISkinManager.TMPFont;
	//tmp.font = Resources.Load("Fonts/Calibri SDF", typeof(TMP_FontAsset)) as TMP_FontAsset;
	tmp.fontSharedMaterial = Resources.Load("Fonts/Materials/Calibri Dropshadow", typeof(Material)) as Material;

	tmp.enableWordWrapping = true;
	tmp.isOverlay = false;
	tmp.richText = true;
}

 

 

Link to comment
Share on other sites

  • 2 weeks later...

ok i am new to C# but i know the basic since i create a simple game in unity.green work red don't work

        [KSPAction("Explode")]
        public void DetonateAG(KSPActionParam param)
        {
            {
                Explode();
            }
        }

so when i press explode it should explode but it didn't

public void Explode()
        {
            Color white = new Color(1, 1, 1, 1);
            Color whitef = new Color(1, 1, 1, 0);

            weapon.vessel.GetHeightFromTerrain();

            blastRadius = weapon.blastRadius;
            blastPower = weapon.blastPower;
            blastHeat = weapon.blastHeat;

            Vector3 position = transform.position;
            Vector3 direction = transform.up;
            Quaternion rotation = Quaternion.LookRotation(VectorUtils.GetUpDirection(position));

            if (!hasExploded && weapon.TimeFired >= weapon.dropTime && weapon.vessel.heightFromTerrain >= 70000)
            {
                hasExploded = true;

                if (part != null) part.temperature = part.maxTemp + 100;

                GameObject lightBall = new GameObject();
                lightBall.SetActive(true);
                lightBall.transform.position = position;
                lightBall.transform.rotation = rotation;
                Detonator sdetonator = lightBall.AddComponent<Detonator>();
                lightBall.GetComponent<Detonator>().enabled = true;
                sdetonator.duration = 2f;
                sdetonator.size = blastRadius; //this one work
                sdetonator.detail = 10f;

            }

This work and the bottom layer show the trigger of Explode

        public override void OnStart(PartModule.StartState state)
        {
            part.OnJustAboutToBeDestroyed += new Callback(Explode);
        }

so the file compile and work but the explode button in gui don't work

 

Edited by cukkoo
Link to comment
Share on other sites

6 hours ago, cukkoo said:

ok i am new to C# but i know the basic since i create a simple game in unity.green work red don't work

        [KSPAction("Explode")]
        public void DetonateAG(KSPActionParam param)
        {
            {
                Explode();
            }
        }

so when i press explode it should explode but it didn't

 

 

I suppose, that this function is in the PartModule. Use KSPEvent instead. For example:

[KSPEvent(guiActive = true, guiName = "#LOC_BV_ContextMenu_Panel", category = "Bon Voyage", requireFullControl = true)]
public void BVControlPanel()
{
	BonVoyage.Instance.ToggleControlWindow();
}

 

Link to comment
Share on other sites

13 hours ago, maja said:

 

I suppose, that this function is in the PartModule. Use KSPEvent instead. For example:


[KSPEvent(guiActive = true, guiName = "#LOC_BV_ContextMenu_Panel", category = "Bon Voyage", requireFullControl = true)]
public void BVControlPanel()
{
	BonVoyage.Instance.ToggleControlWindow();
}

 

I NEED to use the detonate AG as it is a BDArmory extension

Link to comment
Share on other sites

7 hours ago, cukkoo said:

I NEED to use the detonate AG as it is a BDArmory extension

It looks like you are trying to modify my code here. There is no need as I'm actively updating my plugin. You're not using Detonate right in code. I've already tried adding a Detonate button and never got it to work exactly right and is the reason it's not in my code.

Edited by Next_Star_Industries
Link to comment
Share on other sites

45 minutes ago, cukkoo said:

ok i thought you says it not my code:oAlso  i try to make a space explosion but the particle effect look worse when use the plugin

It's not your code your modifying mine which is totally fine and I encourage, however it could cause conflicts later if you create a plugin.

My plugin creates a realistic space explosion. All you'd see of one is a bright light not fire there's no oxygen to burn to produce a flame. In the slow motion videos of real space detonations the ball of plasma created only lasts milliseconds as a result in real time it's just a light flash. It does however cause damage but not like in the atmosphere. Now you can create some kind of fantasy type explosionfx and you do that with Unity and Part Tools. My plugin mearly adds an altitude check and can chose a different model for different altitudes. Nukes don't make the same mushroom cloud when detonated up in the air as when detonated close to the ground and even more different in space. So anything below 500 meters will do a ground explosion, anything 501m to 69,999m will do an air explosion and above 70,000m a space explosion on any planet or moon. If you are trying to use any fx above 70,000m with my plugin you can't it doesn't call one you'll have to use BDAc's without the altitude checks.

*Edit I guess I could modify the plugin to call an fx :cool:

Edited by Next_Star_Industries
Link to comment
Share on other sites

On 9/11/2020 at 12:00 AM, Next_Star_Industries said:

and is the reason it's not in my code.

@Next_Star_IndustriesI thought it not NSI code.Oh i forgot the in,stupid me.also i know some c# so i am going to create  plugin that will check for nuclear core if the nuclear detonator are present there will be a button to detonate only the detonator,if the primary core are present there will be a button to detonate the nuclear fission and if the secondary core are present there will be a button to detonate the secondary core both will have different FX and you can determine the power.because when the detonator compress the uranium it explode then the uranium explosion force crush the heavy hydrogen and it fuse and explode once more so there will be 3 more button(the old detonate will be present).You will come in the credit :D

Link to comment
Share on other sites

10 hours ago, cukkoo said:

@Next_Star_IndustriesI thought it not NSI code.Oh i forgot the in,stupid me.also i know some c# so i am going to create  plugin that will check for nuclear core if the nuclear detonator are present there will be a button to detonate only the detonator,if the primary core are present there will be a button to detonate the nuclear fission and if the secondary core are present there will be a button to detonate the secondary core both will have different FX and you can determine the power.because when the detonator compress the uranium it explode then the uranium explosion force crush the heavy hydrogen and it fuse and explode once more so there will be 3 more button(the old detonate will be present).You will come in the credit :D

Nice can't wait to check it out, let me know if you need any help. Plus check out github to store then others can help develop if you wish.

Link to comment
Share on other sites

also i invited you on github because i publish a code (similar to your's)and you really need to be in the credit

also how to make custom loading screen

(great mod BTW by korean friend even use the little boy for https://en.wikipedia.org/wiki/National_Liberation_Day_of_Korea)

Edited by cukkoo
Link to comment
Share on other sites

9 hours ago, cukkoo said:

also i invited you on github because i publish a code (similar to your's)and you really need to be in the credit

also how to make custom loading screen

(great mod BTW by korean friend even use the little boy for https://en.wikipedia.org/wiki/National_Liberation_Day_of_Korea)

I make images 1920x1080 for the loading screens any image, I use png files easier to compress in my opinion, saving ram. I'll get on github and find you. Place images in the loadingscreen folder in the "Main" KSP directory.

Link to comment
Share on other sites

I'm trying to design part modules that contain my custom sub-config nodes, so that they look like this in GameData:

MODULE
{
	name = MyModule
    CONFIG
    {
    	name = config1
    }
    CONFIG
    {
    	name = config2
    }
}

The sub-nodes should be loaded at KSP initialization (so that GetInfo() is processed properly). I tried using OnLoad in the PartModule, but it causes my entire assembly to load, which creates lots of problems, as the game isn't ready yet.

Is there any simple way to make it work? Like, by using KSPField or something?

Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...