Jump to content

The official unoffical "help a fellow plugin developer" thread


Recommended Posts

A Quick Newbie question...I'm just starting out on making plugins so bare with me. I have a basic PartModule class and I am overriding both OnUpdate and OnFixedUpdate. I only have a single KSPField and KSPEvent defined within the class so far. However when I put a print statement in both functions I only see an OnUpdate is being hit. Is there something I am missing to enable the OnFixedUpdate to be hit? My part that I am attaching this to is a copy of the RCS Block, which I modified its cfg to point to my class. Thanks!

Link to comment
Share on other sites

A Quick Newbie question...I'm just starting out on making plugins so bare with me. I have a basic PartModule class and I am overriding both OnUpdate and OnFixedUpdate. I only have a single KSPField and KSPEvent defined within the class so far. However when I put a print statement in both functions I only see an OnUpdate is being hit. Is there something I am missing to enable the OnFixedUpdate to be hit? My part that I am attaching this to is a copy of the RCS Block, which I modified its cfg to point to my class. Thanks!

OnFixedUpdate() is only called when the part is active, so when it's staged.

Really you're better off using Update() and FixedUpdate() and doing things manually.

Link to comment
Share on other sites

OnFixedUpdate() is only called when the part is active, so when it's staged.

Really you're better off using Update() and FixedUpdate() and doing things manually.

Ahhh so since I have just the part attached to a command capsule on the launchpad it will never stage therefore I'll never get into that.

Which also explains why I see this: "this.part.force_activate();" in a few other plugins, I imagine to get around this.

Does the this.enabled variable mean that its active?

What do you mean by manually do things in Update()?...I don't see that function to override. Is what you suggest the more "correct" way of doing things?

Link to comment
Share on other sites

What do you mean by manually do things in Update()?...I don't see that function to override. Is what you suggest the more "correct" way of doing things?

I think the way to do it is to set up some kind of timer then run your update code at certain intervals. OnUpdate runs every frame and OnFixedUpdate runs every physics frame, since most plugins don't actually need to be updated that quickly it is sometimes better to run them with your own timer.

Something like this from TaranisElsu's plugin examples


void Update()
{
if ((Time.time - lastUpdate) > logInterval)
{
lastUpdate = Time.time;
Debug.Log("TAC Examples-SimplePartlessPlugin [" + this.GetInstanceID().ToString("X")
+ "][" + Time.time.ToString("0.0000") + "]: Update");
}
}

Link to comment
Share on other sites

What do you mean by manually do things in Update()?...I don't see that function to override. Is what you suggest the more "correct" way of doing things?

What I mean is that you don't need to override any functions.

Update() and FixedUpdate() are unity functions that are called when you need it.

See the unity documentation of Monobehaviour: https://docs.unity3d.com/Documentation/ScriptReference/MonoBehaviour.html

And the relevant functions here Update(): https://docs.unity3d.com/Documentation/ScriptReference/MonoBehaviour.Update.html

and FixedUpdate(): https://docs.unity3d.com/Documentation/ScriptReference/MonoBehaviour.FixedUpdate.html

Since PartModule inherits from Monobehaviour, your own partmodules will too, so just stick those functions in your code and you're good. RealChute uses them, so take a look at my source if you feel like it https://github.com/StupidChris/RealChute/blob/master/RealChute/RealChuteModule.cs#L796-L1065

Link to comment
Share on other sites

Kerbals are essentially one part vessels with a KerbalEVA PartModule. You can simply create a partmodule that does what you want, and then add that module to all EVA'ed Kerbals.

How can i do that?

I have pretty much 0 experience with ksp plugins, just browsed trough https://github.com/taraniselsu/TacExamples and wiki.

I know that i can write partmodule and add it to part cfg file. But how can i apply partmodule to eva kerbal? they have no cfgs.

Edited by kiwiak
Link to comment
Share on other sites

How can i do that?

I have pretty much 0 experience with ksp plugins, just browsed trough https://github.com/taraniselsu/TacExamples anw wiki.

I know that i can wrte partmodule and add it to part cfg file. But how can i apply partmodule to eva kerbal? hey have no cfgs.

Create your PartModule and then also create a plugin that runs in the flight scene. Have the second one register for the GameEvents.OnCrewOnEva event. In that function, add your PartModule. Something like this (untested, but I use something similar in one of my plugins)

public void CrewGoingEva(GameEvents.FromToAction<Part, Part> arg)
{
// arg.from = ship kerbal is getting out of
// arg.to = ship being switched to (the eva kerbal)

var kerbal = arg.to.vessel;

if (kerbal.isEVA) // should be true, better safe though
if (kerbal.FindPartModulesImplementing<YourPartModule>().Count == 0)
kerbal.rootPart.AddModule("YourPartModule");
}

Link to comment
Share on other sites

GameEvents.FromToAction<Part, Part> arg

What is this thing for? What do angle brackets do?

And how actually i can make plugin register for register for the GameEvents.OnCrewOnEva ?

edit:

actually i recalled some mod that adds additional options to kerbals on eva, vanguard eva parachutes

i think this might be what i need, inside its source code:

public class ModuleKrEquipKerbal : PartModule

{

[KSPField]

public int range = 1;

[KSPField]

public string guiName = "Equip";

[KSPField(guiActive = true, guiName = "Available", isPersistant=true)]

public float count = 10;

public ConfigNode moduleNode = null;

public override void OnStart(PartModule.StartState state)

{

Events["EquipNearbyKerbal"].unfocusedRange = range;

if (count < 0)

Fields["count"].guiActive = false;

Events["EquipNearbyKerbal"].guiName = guiName;

}

[KSPEvent(guiActive = true, externalToEVAOnly = true, guiActiveUnfocused = true, unfocusedRange = 1)]

void EquipNearbyKerbal()

{

if (!FlightGlobals.ActiveVessel.isEVA || FlightGlobals.ActiveVessel.rootPart.Modules.Contains(moduleNode.GetValue("name")) || count == 0)

return;

else

{

FlightGlobals.ActiveVessel.rootPart.AddModule(moduleNode);

FlightGlobals.ActiveVessel.rootPart.Modules[moduleNode.GetValue("name")].OnStart(PartModule.StartState.Flying);

if (count > 0) count--;

}

}

public override void OnLoad(ConfigNode node)

{

if (node.HasNode("MODULE"))

moduleNode = node.GetNode("MODULE");

}

}

Edited by kiwiak
Link to comment
Share on other sites

Okay, I must be missing something obvious here.

I'm trying to delete an item from a list and it is not working as expected.

Note I have done this another way and have this working another way, but I am really puzzled by this and looking for what I'm missing.

Code executes from a button:

if (GUI.Button(new Rect(0, 0 + (20 * (RowCnt - 1)), 100, 20), ThisGroupActions.ElementAt(RowCnt - 1).group.ToString() + ": " + AGXguiNames[ThisGroupActions.ElementAt(RowCnt - 1).group]))
{
AGXAction agtemp = new AGXAction();
agtemp = ThisGroupActions.ElementAt(RowCnt - 1);
foreach (ModuleAGExtData agpm in ThisGroupActions.ElementAt(RowCnt - 1).prt.Modules.OfType<ModuleAGExtData>())
{
foreach (AGXAction agxact in agpm.partAGActions)
{
print(agxact.group.ToString() + " "+ agtemp.group.ToString() + " " +agxact.ba.name + " " +agtemp.ba.name); //note this line printing to log
if (agxact.group == agtemp.group && agxact.ba.name == agtemp.ba.name) //the important if statment
{
agpm.partAGActions.Remove(agxact); //this line is not working as expected.
goto BreakOut;
}
}
}
BreakOut:
}

In the button code, it builds automatically from a list, so I click the button to execute on the second item. It deletes the first item in the list instead.

I can see the first pass through the code where the important if statement is false because it prints to the log, then on the second pass that if statement is true and the agpm.partAGActions.Remove(agxact); command executes.

This is on the second pass through the code though, I can see the second print command in the log so I know that the agxact item being removed is the second item in the list, not the first which the command actually deletes.

Anyone have any thoughts?

D.

Link to comment
Share on other sites

Basically, the foreach statement should not be used if the thing being enumerated over is going to be changed during the enumeration. You should use a plain loop with an integer index instead (either a for loop or a while loop) and make sure that you correctly handle the index when removing an item.

Link to comment
Share on other sites

What is this thing for? What do angle brackets do?

And how actually i can make plugin register for register for the GameEvents.OnCrewOnEva ?

edit:

actually i recalled some mod that adds additional options to kerbals on eva, vanguard eva parachutes

i think this might be what i need, inside its source code:

This does what I told you, but instead of automatically adding the module to the Kerbal, the PartModule will do it on a UI action event when a part on the ship is right-clicked while in Eva.

Look, here's what you need to add somewhere in your plugin to just have your PartModule added to the eva kerbal without the player having to click anything:

[KSPAddon(KSPAddon.Startup.Flight, false)]
public class YourPartModuleAdder : MonoBehaviour
{
public void Start()
{
GameEvents.onCrewOnEva.Add(CrewGoingEva);
}
public void OnDestroy()
{
GameEvents.onCrewOnEva.Remove(CrewGoingEva);
}

public void CrewGoingEva(GameEvents.FromToAction<Part, Part> arg)
{
// arg.from = ship kerbal is getting out of
// arg.to = ship being switched to (the eva kerbal)

var kerbal = arg.to.vessel;

if (kerbal.isEVA) // should be true, better safe though
if (kerbal.FindPartModulesImplementing<YourPartModule>().Count == 0)
kerbal.rootPart.AddModule("YourPartModule");
}
}

Link to comment
Share on other sites

Seemed to be the best place to post this short of making a new thread:

Is there any mod that includes reaction control engines? As in small, radially-attached engines that function and are controlled as if they were RCS ports, but which use Liquid Fuel. I wanna check before I start thinking about making one myself.

Link to comment
Share on other sites

Seemed to be the best place to post this short of making a new thread:

Is there any mod that includes reaction control engines? As in small, radially-attached engines that function and are controlled as if they were RCS ports, but which use Liquid Fuel. I wanna check before I start thinking about making one myself.

The RCS module can use any propellant you want :)

Link to comment
Share on other sites

Did exactly that, but I had to get a little hacky and make it have two ports in the one part so it'd use Liquid Fuel AND Oxidizer, and I had to fuss with the ISPs to make it use them in the right ratios. It's a little derpy, but it sure is nice having a shunting engine ten times as powerful as an RCS block.

Link to comment
Share on other sites

Did exactly that, but I had to get a little hacky and make it have two ports in the one part so it'd use Liquid Fuel AND Oxidizer, and I had to fuss with the ISPs to make it use them in the right ratios. It's a little derpy, but it sure is nice having a shunting engine ten times as powerful as an RCS block.

This is probably as good as it gets, writing a new module just for that would get pretty hellish fast.

Link to comment
Share on other sites

I think I'll wait until I've made a few more parts and then release what I have as part of a "some useful parts" mod pack alongside 5 - 10 other things. Just have to try and remember what else I've thought KSP needs...

In the meantime, is there a way to get the engine to make a sound without using a plugin? None of the stock RCS ports have sound and I haven't seen any obvious references to activation states (e.g. "running") to which I could point an EFFECT{} node.

Edited by parameciumkid
Link to comment
Share on other sites

I think I'll wait until I've made a few more parts and then release what I have as part of a "some useful parts" mod pack alongside 5 - 10 other things. Just have to try and remember what else I've thought KSP needs...

In the meantime, is there a way to get the engine to make a sound without using a plugin? None of the stock RCS ports have sound and I haven't seen any obvious references to activation states (e.g. "running") to which I could point an EFFECT{} node.

Unfortunately no there is not, you'll need a plugin, either through FXGroups or Effects nodes.

Link to comment
Share on other sites

My latest iteration on the code. Now the IVA spins around in a sphere about the center of the part.

EDIT: I've managed to get the position of the IVAs correct. Check out HSH for the latest iteration of code. I still have not resolved the orientation issues, currently I can either get all IVAs to the correct orientation for the root part, or everything wrong but at least varying by part, or everything wrong and spinning wildly.

Edited by Alskari
Link to comment
Share on other sites

Anyone have any ideas on how to access what class any given asteroid is? ModuleAsteroid doesn't seem to have anything that directly indicates the class (maybe the seed number indicates it in some way?). The only way I can get at it is indirectly through the part's mass, but I don't have accurate values for the mass range for each class (if that is even how they are classified).

I would prefer to get the class value directly, but if I have to I can just figure out the mass ranges and get it that way.

Edit: I may have found something, DiscoveryInfo and UntrackedObjectClass look promising, now to find out how to get to this from the asteroid part itself.

Edited by DMagic
Link to comment
Share on other sites

Anyone have any ideas on how to access what class any given asteroid is?...

I would prefer to get the class value directly, but if I have to I can just figure out the mass ranges and get it that way.

Edit: I may have found something, DiscoveryInfo and UntrackedObjectClass look promising, now to find out how to get to this from the asteroid part itself.

Looks like Vessel has a new DiscoveryInfo property. That might be your way in

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...