Jump to content

The official unoffical "help a fellow plugin developer" thread


Recommended Posts

Hello,

I have another question. Does anyone have a working config for parts that float on water? I tried fiddling with the following

buoyancy = X (tried values from 1 to 100, no change in behavior)

and

MODULE {

name = PartBuoyancy

buoyancy = 100

}

--> This doesn't even load properly.

Do you have any clues? I would like to make a part float on the water (like a raft).

Link to comment
Share on other sites

None of those load becase buoyancy isn't a parameter that the game looks for when it loads the cfg file and because the "PartBuoyancy" is not a PartModule. You'll have to write a plugin to do that, and it shouldn't be that hard. Like it could be just that:

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

namespace buoyancy
{
public class ModuleBuoyancy : PartModule
{
[KSPField]
public float buoyancy;

public override void OnStart(PartModule.StartState state)
{
this.part.partBuoyancy.buoyancyForce = buoyancy;
}
}
}

Then, you would just need to add this to the cfg file:

MODULE
{
name = ModuleBuoyancy
buoyancy = 100 (or whatever you want)
}

Not that hard, you can do it yourself if you really wanted to :P

Edited by stupid_chris
Link to comment
Share on other sites

None of those load becase buoyancy isn't a parameter that the game looks for when it loads the cfg file and because the "PartBuoyancy" is not a PartModule. You'll have to write a plugin to do that, and it shouldn't be that hard. Like it could be just that:

...

Not that hard, you can do it yourself if you really wanted to :P

Thanks for your quick reply! I really appreciate it!

I tried your approach before but I did not succeed because I got an error (see below code):



public class KM_SimpleFloater : PartModule
{

// remember the time wehen the countdown was started
[KSPField(isPersistant = true, guiActive = true, guiName = "Buoyancy")]
private float buoyancy = 1.0F;

[KSPField(isPersistant = true, guiActive = true, guiName = "BuoyancyForce")]
private float buoyancyForce = 1.0F;



public override void OnStart(PartModule.StartState state)
{
this.part.partBuoyancy.buoyancy = buoyancy;
this.part.partBuoyancy.buoyancyForce = buoyancyForce;
}

[KSPEvent(guiName = "buoyancyForce +", guiActive = true)]
public void increaseBuoyancyForce ()
{
buoyancy = buoyancy + 10f;
this.part.partBuoyancy.buoyancyForce = buoyancyForce;
}

[KSPEvent(guiName = "buoyancyForce -", guiActive = true)]
public void decreaseBuoyancyForce ()
{
buoyancy = buoyancy - 10f;
this.part.partBuoyancy.buoyancyForce = buoyancy;
}

[KSPEvent(guiName = "buoyancy +", guiActive = true)]
public void increaseBuoyancy ()
{
buoyancy = buoyancy + 10f;
this.part.partBuoyancy.buoyancy = buoyancy;
}

[KSPEvent(guiName = "buoyancy -", guiActive = true)]
public void decreaseBuoyancy ()
{
buoyancy = buoyancy - 10f;
this.part.partBuoyancy.buoyancy = buoyancy;
}
}

Gives me: [Exception]: NullReferenceException: Object reference not set to an instance of an object

I altered the code this way and I got a PartBuoyanc Object back which I can now alter. However, it doesn't affect anything. My part does not really float (its supposed to lift the capsule after splashdown). The capsule stays in teh water without any change, regardless of what I change the values to.

Here is my new code:



public class KM_SimpleFloater : PartModule
{

// remember the time wehen the countdown was started
[KSPField(isPersistant = true, guiActive = true, guiName = "Buoyancy")]
private float buoyancy = 1.0F;

[KSPField(isPersistant = true, guiActive = true, guiName = "BuoyancyForce")]
private float buoyancyForce = 1.0F;


private void setBuoyancy() {
PartBuoyancy partB = part.GetComponent<PartBuoyancy>();
if (partB)
{
partB.buoyancy = buoyancy;
partB.buoyancyForce = buoyancyForce;
} else {
print ("PartBuoyancy not fund");
}
}


public override void OnStart(PartModule.StartState state)
{
PartBuoyancy partB = part.GetComponent<PartBuoyancy>();
if (partB)
{
partB.buoyancy = buoyancy;
partB.buoyancyForce = buoyancyForce;


} else {
print ("PartBuoyancy not fund");
}

}

[KSPEvent(guiName = "buoyancyForce +", guiActive = true)]
public void increaseBuoyancyForce ()
{
buoyancyForce = buoyancyForce + 10f;
setBuoyancy();
}

[KSPEvent(guiName = "buoyancyForce -", guiActive = true)]
public void decreaseBuoyancyForce ()
{
buoyancyForce = buoyancyForce - 10f;
setBuoyancy();
}

[KSPEvent(guiName = "buoyancy +", guiActive = true)]
public void increaseBuoyancy ()
{
buoyancy = buoyancy + 10f;
setBuoyancy();
}

[KSPEvent(guiName = "buoyancy -", guiActive = true)]
public void decreaseBuoyancy ()
{
buoyancy = buoyancy - 10f;
setBuoyancy();
}
}


Is anything necessary in addition to setting these values? What are good values for it? I tried everything from 1 to 500 for buoyancy and buoyancyForce . Any suggestions for sane values here?

Thanks a lot!!!

Link to comment
Share on other sites

  • 2 weeks later...

Hello everyone! I'm new here. And I have a hopefully simple question: how do I make my partmodule class load properties from my part.cfg? Is there anything I have to do besides defining the variables as KSPFields?

Relevant bits:

public class KAntigrav : PartModule
{
[KSPField(isPersistant = false, guiActive=true)]
public double agEfficiency;

[KSPField(isPersistant = false, guiActive = true)]
public double agStrength;

[KSPField(isPersistant = false, guiActive = true)]
public double agAttenuation;

And from the part.cfg:


MODULE
{
name = KAntigrav
agStrength = 1.2
agAttenuation = 10
agEfficiency = 500
}

Anyone have any idea what I'm missing? It's probably something obvious that I don't yet understand.

Edited by Kashaar
Link to comment
Share on other sites

I do not believe KSPField and the part.cfg are linked.

From the thread announcing KSPFields being added, KSPFields are a way to make persistent variables saved to persistence.sfs and of exposing them to the in-game UI.

There is nothing there about linking them to the part.cfg that I can see.

To do what I think you are asking, you need to initialize your variable as a KSPField, and then assign that variable the value from the part.cfg through the usual part.cfg loading logic.

edit: Apparently I was wrong, post left so replies to it below make sense but see TaranisElsu's post (5 below this one) for correct answer.

D.

Edited by Diazo
Link to comment
Share on other sites

To do what I think you are asking, you need to initialize your variable as a KSPField, and then assign that variable the value from the part.cfg through the usual part.cfg loading logic.

Oh, I thought those were linked somehow. Google isn't being very helpful unfortunately... or my google-fu is just too weak, so what is the usual part.cfg loading logic? :)

In place of an explanation, a link to an open source plugin with a pointer towards the relevant piece of code would also be helpful.

Link to comment
Share on other sites

I'm not sure what exactly you are asking for, but that is what basically happens when the game loads your custom part on first game startup:

- Game loads cfg

- For each Module element, it looks for a class with the name specified in the cfg that implements PartModule

- It loops though all of the classes members and looks for KSPFields, KSPEvents and KSPActions (thats what i am aware of, maybe even more) and uses them to create the PartModules pm.Actions, pm.Events & pm.Fields lists

- Those lists are later used by lsp while initialization, loading or saving the game to "automatically" read/write your data for you.

So yes, KSPField is just a simple .NET attribute that signals KSP to treat however you configured this attribute for your field/method. There isn't really sth we could point you to, except maybe to some of PartModules members (of type Base...List)

Link to comment
Share on other sites

Hmm, so KSPFields are a red herring in this case, I suppose... My problem is that the game doesn't seem to be assigning my PartModule's variables the values defined in the part.cfg.

I'm writing an antigravity plugin, and I want some factors (agStrength, agAttenuation, etc.) to be set by the part.cfg, so I can create multiple parts with differing characteristics, but using the same algorithms. With the code above, the three variables are all 0 when I use the debug window to look at them in game. I can define them in my code like this to make it work:

public double agEfficiency = 500;

...but that kind of defeats the purpose of the part.cfg, if I understand it correctly.

I'm sorry if I haven't expressed myself clearly. I'm very new to C#, so if this is something obvious I should know I'm sorry. I only have a little previous experience in Python, and took a Java class maybe 10 years ago that never amounted to anything.

Hmm, after this part:

- For each Module element, it looks for a class with the name specified in the cfg that implements PartModule

...what does the game do with the attributes inside the MODULE {} brackets?

Link to comment
Share on other sites

Hmm, so KSPFields are a red herring in this case, I suppose... My problem is that the game doesn't seem to be assigning my PartModule's variables the values defined in the part.cfg.

I'm writing an antigravity plugin, and I want some factors (agStrength, agAttenuation, etc.) to be set by the part.cfg, so I can create multiple parts with differing characteristics, but using the same algorithms. With the code above, the three variables are all 0 when I use the debug window to look at them in game. I can define them in my code like this to make it work:

public double agEfficiency = 500;

...but that kind of defeats the purpose of the part.cfg, if I understand it correctly.

I'm sorry if I haven't expressed myself clearly. I'm very new to C#, so if this is something obvious I should know I'm sorry. I only have a little previous experience in Python, and took a Java class maybe 10 years ago that never amounted to anything.

Hmm, after this part:

...what does the game do with the attributes inside the MODULE {} brackets?

What you first did is right. If you assign the KAntigrav module to a part and inpuit the values you did above, you should be able to see those values when right clicking the part in the flight scene. KSPField can be used to fetch values from the config file for partmodule or to store a value in the persistance file.

If you look here, you can see all the values needed by RealChuteModule. Simply listing them in KSPField will get them in the config for you.

Link to comment
Share on other sites

Hello everyone! I'm new here. And I have a hopefully simple question: how do I make my partmodule class load properties from my part.cfg? Is there anything I have to do besides defining the variables as KSPFields?

Relevant bits:

public class KAntigrav : PartModule
{
[KSPField(isPersistant = false, guiActive=true)]
public double agEfficiency;

[KSPField(isPersistant = false, guiActive = true)]
public double agStrength;

[KSPField(isPersistant = false, guiActive = true)]
public double agAttenuation;

And from the part.cfg:


MODULE
{
name = KAntigrav
agStrength = 1.2
agAttenuation = 10
agEfficiency = 500
}

Anyone have any idea what I'm missing? It's probably something obvious that I don't yet understand.

You definitely can use KSPFields for loading values from the part.cfg file. I started writing an example showing how here: https://github.com/taraniselsu/TacExamples/tree/master/05-KspFields. It is unfinished though :(. I could not get my type (that extends IConfigNode) to work even though it should.

I did find that KSPField's do not work if they are double's. Change your code above to float's and it should work fine.

Link to comment
Share on other sites

i have one problem, im sortof new to C# and the code used in KSP, but i do have some programming experience

how can i make a dynamic color definition?

by this im asking how to define a dynamic color (its a color for a tracer if you want me to be specific)

color i have currently is defined like this:

public Color tracer = new Color(1.0, 1.0, 1.0);

but i want to be able to use floats in the part's cfg file like so:

[KSPField]

public float color_red = 1.0f;

[KSPField]

public float color_green = 1.0f;

[KSPField]

public float color_blue = 1.0f;

how do i code this in order to make these 3 variables dictate color of the tracer?

i just want the part.cfg to dictate the variables the color is based off of, so each of the multiple gunpods i have dont require a entirely different projectile defenition, as thats just unnecessary code since i would think it is possible to just define tracer color in the part cfg.....

Link to comment
Share on other sites

You definitely can use KSPFields for loading values from the part.cfg file. I started writing an example showing how here: https://github.com/taraniselsu/TacExamples/tree/master/05-KspFields. It is unfinished though :(. I could not get my type (that extends IConfigNode) to work even though it should.

The reason for this is that (unless I'm very much mistaken) Unity ignores the Serializable attribute on any classes not in the original set of assemblies that it loads itself, so it isn't any fault of yours.

Link to comment
Share on other sites

how do i code this in order to make these 3 variables dictate color of the tracer?

[KSPField]

public float color_red = 1.0f;

[KSPField]

public float color_green = 1.0f;

[KSPField]

public float color_blue = 1.0f;

public Color tracerColor = new Color(color_red, color_green, color_blue);

Link to comment
Share on other sites

[KSPField]

public float color_red = 1.0f;

[KSPField]

public float color_green = 1.0f;

[KSPField]

public float color_blue = 1.0f;

public Color tracerColor = new Color(color_red, color_green, color_blue);

its giving me errors here

the name color_red does not exist within the current context

namely it doesnt want to accept anything but a number followed by f to designate it as a float

so is there any way to get this to work? As in what i want to do in the end is define a color to be used for my weapon tracers, but have it defined in the part.cfg instead of in the dll, as it just makes no sense to define multiple projectiles when all im really changing between them is the color of the tracer left behind it.

Link to comment
Share on other sites

From the error message it may be a scope issue, can you post your code?

specifically the following code compiles fine for me:

public class SomeClass : PartModule
{
[KSPField]
public float color_red = 1.0f;
[KSPField]
public float color_green = 1.0f;
[KSPField]
public float color_blue = 1.0f;

public Color tracerColor;

public override void OnStart(StartState state)
{
tracerColor = new Color(color_red, color_green, color_blue);
}
}

Link to comment
Share on other sites

Wouldn't it be easier to use a confignode and vector3? (Or vector4 for rgba)

if (node.HasValue("Color"))
{
Vector3 col = (node.GetValue("Color"));
node.coloryouwanttoconfig = new Color(col.x, col.y, col.z);
}

Obviously you need to set the foreach and the name of your config file, but that's the confignode stuff.

EDIT:Typed the wrong thing. I don't have the best memory.

Also a question myself, how can I get a plugin to detect proximity to a CelestialBody?

Edited by Nutt007
Link to comment
Share on other sites

So, how do I maek plugin maek ship maek sounds?

I wanna make an annoying "TERRAIN TERRAIN. PULL UP. PULL. FRIGGIN'. UP!!!11!1!11111" thingy.

I've got the base down, with the GUI and stuff, but how do I...

1. detect altitude (preferably radar)

2. detect vertical velocity

3. play sounds...?

Thanks. :)

Naten. :D

Link to comment
Share on other sites

Anybody have any idea why using "KSPAddon.Startup.EditorAny" only works for the VAB and not for the SPH? I know I can just do one for each, but using EditorAny seems like a much nicer approach...

EDIT: actually this might not be EditorAny giving me problems, but GameScenes. I'm just not getting things to show up in the SPH that are working just fine in the VAB =P

So, how do I maek plugin maek ship maek sounds?

I wanna make an annoying "TERRAIN TERRAIN. PULL UP. PULL. FRIGGIN'. UP!!!11!1!11111" thingy.

I've got the base down, with the GUI and stuff, but how do I...

1. detect altitude (preferably radar)

2. detect vertical velocity

3. play sounds...?

Thanks. :)

Naten. :D

You can try:

For radar altitude: FlightGlobals.ActiveVessel.GetHeightFromSurface() or FlightGlobals.ActiveVessel.GetHeightFromTerrain()

For Vertical Velocity: FlightGlobals.ActiveVessel.verticalSpeed

to play sounds, I'm not sure, but there should be a Unity or KSP Plugin tutorial out there that will help you there =3 Google is your friend!

Edited by Ekku Zakku
Link to comment
Share on other sites

The FlightGlobals probably answers my question too.

Ekku: Have you tried using KSPAddonFixed by Majiir? Probably won't change anything but it's what all the ~cool~ modders are using. If the editor thing doesn't work have you considered loading at the Menu? Hyperedit does that.

Edited by Nutt007
Link to comment
Share on other sites

I'm trying to shutdown an engine under certain circumstances, but I can't seem to figure out the appropriate command. Basically I just want to do the same thing that happens when you click the "shutdown engine" button in game. It should be simple, but I've tried a bunch of functions and variables within moduleengines and partmodule without any success.

Thanks!

@Naten: I asked a very similar question about radar altitude here. One of the responses provides some very nice example code.

Edited by XanderTek
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...