Jump to content

The official unoffical "help a fellow plugin developer" thread


Recommended Posts

Is there any good way to check if moving a crew from one part (e.g. command pod) to another (e.g. hitchhiker) within the same vessel would render the vessel uncontrollable? Preferably before the move occurs.

I don't think checking for the part that is "control from here" works, since that could be a docking port or such.

Here's a code snippet I hacked together in OnUpdate() of my PartModule. Since I couldn't find a way to do it beforehand, I tried moving the kerbal first, hoping to be able to detect loss of control and then be able to undo the move if necessary (to restore control). moveKerbal() should be self explanatory.


if (partFrom!=dontDecrew) { // dontDecrew was initialized to null outside of OnUpdate()
moveKerbal(kerbal, partFrom, partTo);
if (!this.vessel.IsControllable) {
[COLOR="#FF0000"]// never executes. Also tried IsCommandable, doesn't work either.[/COLOR]
Debug.Log("oops, that rendered the vessel uncontrollable. Undoing...");
moveKerbal(kerbal, partTo, partFrom);
dontDecrew=partFrom; // remember this part and don't do it again
}
}

Neither IsControllable nor IsCommandable works; when a kerbal is moved and the vessel becomes no longer controllable, that move does not get undone.

I'm guessing that the controllable status of the vessel doesn't get updated until the next update cycle? That would be rather annoying for me since there is a (very small) chance that in the meantime, the player EVA the moved kerbal out of the new part (partTo), which would break my ability to undo the move.

Any ideas?

Link to comment
Share on other sites

Is there any good way to check if moving a crew from one part (e.g. command pod) to another (e.g. hitchhiker) within the same vessel would render the vessel uncontrollable? Preferably before the move occurs.

Probably you need to look for the ModuleCommand PartModule and check its minimumCrew field. Presumably the vessel is controllable if at least one part with a ModuleCommand module has a number of crew greater than or equal to its minimumCrew. See the part.cfg files for the existing command pods.

Link to comment
Share on other sites

Probably you need to look for the ModuleCommand PartModule and check its minimumCrew field. Presumably the vessel is controllable if at least one part with a ModuleCommand module has a number of crew greater than or equal to its minimumCrew. See the part.cfg files for the existing command pods.

Hmm, I was rather hoping I wouldn't need to check through all the vessel parts myself...

So, something like:


public override void OnUpdate() {
...
moveKerbal(kerbal, partFrom, partTo);
if (!myIsControllable(this.vessel)) {
// oh snap, undo!
}
...
}

public bool myIsControllable(Vessel v) {
foreach (Part p in this.vessel.parts)
if (p.Modules.Contains("ModuleCommand') && p.protoModuleCrew.Count >= (p.Modules["ModuleCommand"] as ModuleCommand).minimumCrew)
return true;
return false;
}

Guess this should work in principle (probe cores are also ModuleCommand with minimumCrew=0) ... but somewhat irritating in that it likely duplicates functionality that is already present somewhere in KSP itself. =/

I'll try to investigate IsControllable/IsCommandable a bit more before falling back on this, I think.

Link to comment
Share on other sites

Is there any good way to check if moving a crew from one part (e.g. command pod) to another (e.g. hitchhiker) within the same vessel would render the vessel uncontrollable? Preferably before the move occurs.

I don't think checking for the part that is "control from here" works' date=' since that could be a docking port or such.

Here's a code snippet I hacked together in OnUpdate() of my PartModule. Since I couldn't find a way to do it beforehand, I tried moving the kerbal first, hoping to be able to detect loss of control and then be able to undo the move if necessary (to restore control). moveKerbal() should be self explanatory.


if (partFrom!=dontDecrew) { // dontDecrew was initialized to null outside of OnUpdate()
moveKerbal(kerbal, partFrom, partTo);
if (!this.vessel.IsControllable) {
[COLOR="#FF0000"]// never executes. Also tried IsCommandable, doesn't work either.[/COLOR]
Debug.Log("oops, that rendered the vessel uncontrollable. Undoing...");
moveKerbal(kerbal, partTo, partFrom);
dontDecrew=partFrom; // remember this part and don't do it again
}
}

Neither IsControllable nor IsCommandable works; when a kerbal is moved and the vessel becomes no longer controllable, that move does not get undone.

I'm guessing that the controllable status of the vessel doesn't get updated until the next update cycle? That would be rather annoying for me since there is a (very small) chance that in the meantime, the player EVA the moved kerbal out of the new part (partTo), which would break my ability to undo the move.

Any ideas?[/quote']

I would guess that your code after IsControllable check is not executed, because after you "move" kerbals from one part to another, you need not only to call vessel.SpawnCrew() but to do it after some delay, otherwise the move does not happen or happens with bugs. So you need to wrap the move-back code into a coroutine. Look at the CrewManifest code for an example: https://github.com/sarbian/CrewManifest/blob/master/CrewManifest/ManifestController.cs

[EDIT] Oh, and there's no chance at all that the player will do anything in-between updates. Even Jedais can't move THAT fast =) But if you want more info on the matter, check this: http://docs.unity3d.com/Manual/ExecutionOrder.html

Edited by allista
terrible spelling errors ^_^
Link to comment
Share on other sites

I would guess that your code after IsControllable check is not executed, because after you "move" kerbals from one part to another, you need not only to call vessel.SpawnCrew() but to do it after some delay, otherwise the move does not happen or happens with bugs. So you need to wrap the move-back code into a coroutine.

As far as I can tell, the ubiquitous call to vessel.SpawnCrew() by crew transfer mods, delayed by one update tick, is what has been found to be the consistent solution for refreshing IVA portraits after moving kerbals around. There's about two pages of discussion about it here: http://forum.kerbalspaceprogram.com/threads/62270?p=980907#post980907

As for the IsControllable flag, you are correct to suggest that the flag isn't updated live, but rather gets updated whenever some ksp internal routine runs the check ... which we would naturally assume happens in OnUpdate() or OnFixedUpdate()... except maybe not quite every cycle. However, I'm fairly sure it does not depend on the call to vessel.SpawnCrew().

Here's what I did: I reset a counter to zero when a kerbal gets moved, and have OnUpdate() increment the counter each update tick. Then,

if (!this.vessel.IsControllable) Debug.Log("counter="+counter);

Consistently starts printing from "counter=2", regardless of whether I had made the delayed call to vessel.SpawnCrew() or not.

I can't be sure if 2 update ticks for controllability check to update holds in general, or is specific to my system (see also: Papa_Joe tries 5 and 10+ frames of delay with different results). If the former, then there is probably something that happens in ksp code in the first tick, which then triggers the check/update to happen on the second tick. A bit odd, but at least it would be consistent in terms of the OnUpdate() cycle, and can be sort of reliably used. If the latter, then there is some asynchronous process going on outside of the unity lifecycle that is dependent on processing speed and such. All bets would be off.

Incidentally, IsCommandable remains true throughout, so that flag likely refers to the presence of at least one part with ModuleCommand in the vessel (i.e. debris is not commandable), whereas IsControllable looks at whether crew requirements are met / EC available for probes (and I guess RT2 might be using this for lack of comms link). In case anyone else wondered what the difference was. (I certainly did.)

Link to comment
Share on other sites

I've decide to start trying to make a plugin, (again), and it should be simple.

What I want it to do is to display an image in the VAB/SPH via the AppManager(Is that right?) that can be toggled on and off. The issue is that I don't really know where to start, particularly on using the app manager and accessing an image in the GameData folder.

Edit: how do I add the API to my MonoDevelop project?

Edited by Robotengineer
Link to comment
Share on other sites

I'm working on starting modding, developing another resource system(similar in idea to Kethane and others). One thing I'm working on in the plugin is only being able to scan if the scanning dish is pointed at the planet. Is there a way to do this?

Link to comment
Share on other sites

I'm working on starting modding, developing another resource system(similar in idea to Kethane and others). One thing I'm working on in the plugin is only being able to scan if the scanning dish is pointed at the planet. Is there a way to do this?

I guess you want to look at the source for RemoteTech.

Link to comment
Share on other sites

RT2 doesn't actually do that. Original-RT2 did, but for RT2lite (which became the RT2 we know) it was removed.

I think you should check the UP of the transform for the antenna, and do a dot product between that and (CB.position - vessel.position). Which might need the signs flipped, dunno.

Link to comment
Share on other sites

Ok, another question: is there any elegant way to detect part (or vessel with part) unload? I've onInactive, but it only works when part is destroyed. I need to do some actions on vessel unload, like when vessel is going out of phisics range or when user switch back to Space Center.

Edited by McOffsky
Link to comment
Share on other sites

With the disclaimer I have not used it myself, the OnPartDestroyed event sounds promising.

static EventData< Part > 	onPartDestroyed
Triggered when a part object's OnDestroy method is called; occurs any time a part or vessel is unloaded, ie scene changes or vessel moving out of loading distance More...

This is in the GameEvents class.

Note that I have used OnVesselGoOnRails and OnVesselGoOffRails and those will not do what you are looking for as they seemed to trigger only 300 meters or so from the FlightGlobals.ActiveVessel.

D.

Link to comment
Share on other sites

Hi guys!

I have been trying to update the "first person EVA" mod, and I have zero experience with C# and tiny amounts of C++. looking through the source, it seems relatively straight forward, but it fails to load in 0.25. in the ksp.log it mentions

System.Reflection.ReflectionTypeLoadException: The classes in the module cannot be loaded.

the plugin is trying to add a module to the "KerbalEVA" config with this code:

public class initKerbalEVA : UnityEngine.MonoBehaviour {    public void Awake() {

ConfigNode EVA = new ConfigNode("MODULE");
EVA.AddValue("name", "FpsCamera");
EVA.AddValue("cameraName", "FpsCam");
try {
PartLoader.getPartInfoByName("KerbalEVA").partPrefab.AddModule(EVA);
} catch{}
}

Which is a modification Fel's code to add modules to the "KerbalEVA" part.

is there anything that has changed in 0.25 which may have changed any of this? or is it something completely different?

the full source for the original mod is: http://forum.kerbalspaceprogram.com/threads/73799-0-23-FirstPersonEVA

Link to comment
Share on other sites

I have a question that I hope someone could answer.

Is there a way to bring up the part info window shown in the VAB and R&D on the fly? I've been looking at PartListTooltips to see if I could make it show, but haven't had any luck.

Link to comment
Share on other sites

For my strategies mod, I've added a small section of extra text displaying the amount of income of each type relative to the total income (eg. 1k funds -> 800 funds + 500 rep). It all works in a useable manner, so I'm just trying to resolve some of the more minor issues it has.

The first of those is that after switching contracts or changing commitment level, the appearance of the text is slightly delayed. This results in a noticeable flicker, especially when dragging the commitment slider. I'm currently using the OnGUI() event to trigger the display call and from what I can tell that is the correct event, but that begs the question of what causes the delay.

http://youtu.be/9JHnhF78qj0

The second is a very minor coding gripe. To check that the effect is a currency conversion (the only type I want to apply it to), what I'm currently doing is checking that the description of the single effect spans two lines of text (currency operation and value operation are both a single line per effect). The effect name ("CurrencyConverter") isn't available for some reason. Any ideas on how I can make a more robust test for the effect type would be much appreciated.

Link to comment
Share on other sites

A noob question here – I'm trying to make a KSP 0.25 part that uses a Unity GameObject to place the the top and bottom nodes and then using NODE {} in the cfg file. In Unity I've named the two nodes “NodeTop†and “NodeBottomâ€Â. NodeTop works without any problems but NodeBottom refuses to work. After messing around and trying many things I found that I could get bottom node to work if I renamed it

Name Works

“NodeBottom†No

“NodeBot†Yes

“NodeBott†Yes

“NodeBotto†No

Eight char limit? – surely not

“ABCDEFGHI†Yes

“NodeTottom†Yes

Case insensitive?

“Nodebottom†No

“Modebottom†Yes

“nodeBottom†Yes

“NodeBottom1†Yes

I've gone back and repeated a few of the non-working test – it's consistent - they continue to not work – what am I missing here? Searched the thread and Googled – found questions but no answers. Thanks in advance for any help.

Link to comment
Share on other sites

So I have a question:

Is it possible to edit an already existing class from the game?

I want to add several new objects to the ProtoCrewMember class and integrate them into the existing methods.

So what i basically want to do in the end is this:

ProtoCrewMember kerbal
kerbal.CustomMethod(...)

Link to comment
Share on other sites

There's no way to add new members to an existing object unless you use ExpandoObject, but that only exists in .Net 4.0 and onwards.

One option though looks to be to create a subclass of ProtoCrewMember, and then use the ProtoCrewMember(ProtoCrewMember copyOf) constructor to duplicate the existing ProtoCrewMember object, and then replace the old one with the new instance.


public class MyNewCrewMember : ProtoCrewMember
{
public MyNewCrewMember(KerbalType type) : base(type)
{
}

public MyNewCrewMember(ProtoCrewMember copyOf) : base(copyOf)
{
}

public MyNewCrewMember(ConfigNode node, KerbalType crewType = KerbalType.Crew) : base(node, crewType)
{
}

public void FanceMethod()
{
}
}

var oldCrewMember = this.GetOldCrewMember();

var myShinyNewCrewMember = new MyNewCrewMember(oldCrewMember);

this.ReplaceOldCrewMemberWithNew(oldCrewMember , myShinyNewCrewMember );

myShinyNewCrewMember.FancyMethod();

I have not tried this though, and only suggest it based on the existence of the ProtoCrewMember(ProtoCrewMember copyOf) constructor.

Link to comment
Share on other sites

Sorry that I didn't tell you, but I already tried that.

But I'm not particularly happy with this solution because then I would have two Lists with ProtoCrewMembers:

1.the games CrewRoster List

and 2. my own List of ProtoCrewMembers (MyNewKerbalMembers)

So then there would be two separate lists of Kerbals and when the game changes some values of a ProtoCrewMember in the CrewRoster-List, the respective values in my ProtoCrewMember-List wont change. :/

I would have to check constantly if the values have changed and match them, but this all would be very inefficient.

So I probably have to stick with creating a new list which contains my custom values for each Kerbal.

Link to comment
Share on other sites

You don't need to keep two separate lists. As they're the same base class, you can just replace the entry in the CrewRoster list with your new object.

The game would be none the wiser, and you now have the CrewRoster full of your expanded objects.

A thing to remember though is that if you do this, it could be in conflict with other mods that replace the entries in the CrewRoster list.

Link to comment
Share on other sites

But the CrewRoster List is a List of type ProtoCrewMember not MyNewKerbalMembers, so if I add an instance of MyNewKerbalMembers, this instance will be converted to ProtoCrewMembers, which means all my custom objects are gone. Same goes for retrieving the values from the CrewRoster. Since I am calling a method(like CrewRoster.Find(..)) of type ProtoCrewMember, I will receive a ProtoCrewMember-instance which I then have to convert back to MyNewKerbalMembers. As far as I know one of these conversions should lead to a loss of my custom objects.

If the CrewRoster-List would be defined like:

List<MyNewKerbalMembers> CrewRoster = ...

then it would be no problem, because conversion from ProtoCrewMember to MyNewKerbalMembers should result in no loss of objects(rather an addition of objects).

So if I am unable to edit the ProtoCrewMember class I don't see a way of getting this to work the way I wanted it to work in the beginning. :/

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