Jump to content

The official unoffical "help a fellow plugin developer" thread


Recommended Posts


FlightGlobals.currentMainBody.BiomeMap.GetAtt(FlightGlobals.currentMainBody.position.x, FlightGlobals.currentMainBody.position.y).name

The position needs to be worked out mind you. The X and Y of the Launchpad gives me the Ice Cap as the name, but I'm sure it will be clearer when you figure out what the Latitude and Longitude is of your current location.

I've also discovered the answer to my own question regarding the GameEvents.


public override void OnStart(PartModule.StartState state)
{
base.OnStart(state);
GameEvents.onPartActionUICreate.Add(someEvent);
}
public void someEvent(Part p){
Debug.Log("This event occurred");
}

Link to comment
Share on other sites


TechRequired = start
entryCost = 50
cost = 800

The key being the "TechRequired = start" line, with 'start' being the name of the Tech node you want the part to be unlocked on. It just has to be on it's own line in the same scope of where the Part's name is (usually near the top).

Edit: This being located in the Part's "part.cfg" file.

Link to comment
Share on other sites

Is there a way to use ModuleManager to replace the name (and in turn the class) of a PartModule? I'm wanting to replace all instances of ModuleScienceExperiment with my own class ModuleResearchExperiment which extends ModuleScienceExperiment.

Here is what I have tried:


@PART[*]:HAS[@MODULE[ModuleScienceExperiment]]
{
@MODULE[*].HAS[#name[ModuleScienceExperiment]
{
@name = ModuleResearchExperiment
}
}

But I believe the key problem is that by the time ModuleManager does its thing, the names are already set in stone (or so I think).

Link to comment
Share on other sites

So I'm all out of ideas for this problem I've been having - it probably won't affect too much, but it's been annoying me.

Here's my code:


public void OnLevelWasLoaded ()
{
LoopPreventer = false;

}

public void FixedUpdate()
{

if (!LoopPreventer) {
LoopPreventer = true;

if (HighLogic.LoadedScene == GameScenes.FLIGHT) {
Debug.Log ("You're in FLIGHT!");
VesselChecker ();

} else if (HighLogic.LoadedScene == GameScenes.EDITOR) {
Debug.Log ("You're in EDITOR!");
} else if (HighLogic.LoadedScene == GameScenes.TRACKSTATION) {
Debug.Log ("You're in TRACKINGSTATION!");
}

}
}

When I jump into the Flight scene, it should ideally only print out "You're in FLIGHT!" once, but instead, this little thing happens:



[WRN 01:20:54.507] [HighLogic]: =========================== Scene Change : From TRACKSTATION to FLIGHT =====================
[EXC 01:20:54.898] KeyNotFoundException: The given key was not present in the dictionary.
[LOG 01:20:55.119] You're in FLIGHT!
[LOG 01:20:55.121] ====================
[LOG 01:20:55.124] VesselChecker initiated!
[LOG 01:20:55.126] Vessel is...
[EXC 01:20:55.128] NullReferenceException: Object reference not set to an instance of an object
[LOG 01:20:56.126] ------------------- initializing flight mode... ------------------
[LOG 01:20:56.138] Target vessel index: 0 vessel count: 2
[LOG 01:20:56.142] [FLIGHT GLOBALS]: Switching To Vessel Untitled Space Craft ----------------------
[LOG 01:20:56.148] setting new dominant body: Kerbin
FlightGlobals.mainBody: Kerbin
[LOG 01:20:56.201] Camera Mode: AUTO
[LOG 01:20:56.257] stage manager resuming...
[LOG 01:20:57.209] all systems started
[LOG 01:20:57.233] You're in FLIGHT!
[LOG 01:20:57.235] ====================
[LOG 01:20:57.238] VesselChecker initiated!
[LOG 01:20:57.240] Vessel is...Mark1-2Pod (Untitled Space Craft) (Vessel)
[LOG 01:20:57.242] Vessel name is...Mark1-2Pod (Untitled Space Craft)

etc etc

As you can see, the printout occurs twice.

Likewise, for the Tracking Station:


[WRN 01:22:15.514] [HighLogic]: =========================== Scene Change : From SPACECENTER to TRACKSTATION =====================
[WRN 01:22:15.544] Cannot find preset 'Default' for pqs 'Eeloo'
[WRN 01:22:15.555] Cannot find preset 'Default' for pqs 'Pol'
[WRN 01:22:15.601] Cannot find preset 'Default' for pqs 'Dres'
[LOG 01:22:16.793] You're in TRACKINGSTATION!
[LOG 01:22:17.540] Performing cleanup of PluginData flights (2 flights loaded)...
[LOG 01:22:17.552] You're in TRACKINGSTATION!
[LOG 01:22:17.688] [PlanetariumCamera]: Focus: Kerbin

Help?

Link to comment
Share on other sites

So I'm all out of ideas for this problem I've been having - it probably won't affect too much, but it's been annoying me.

[...]

As you can see, the printout occurs twice.

[...]

Help?

Rather than using OnLevelWasLoaded, save the current loaded scene outside of your methods, then check if the current loaded scene is different to your previously saved one before running the rest of the FixedUpdate method.

Link to comment
Share on other sites

Okay, slight hitch, this new way won't work for when I'm switching vessels through the map view. Is there something I can use to detect when vessels are switched?

By that do you mean simply focusing on the map view or literally switching vessels? If you do mean switching vessels, simply store the current vessel in a variable and then check if (FlightGlobals.ActiveVessel == lastVessel).

If you meant focusing, I recommend you take a look at the PlanetariumCamera class, you'll have to deal with stuff there.

Link to comment
Share on other sites

Garrrr, two little questions! :(

1. I've managed to control the fact that I check whenever I switch vessels in the map view using the LastVessel thing, but my next problem is when you jump between vessels that are in range of the current vessel (e.g. pressing '[' and ']'). I've looked into FlightGlobals and couldn't find anything; maybe I missed something? The log says [FLIGHT GLOBALS]: Switching To Vessel Untitled Space Craft every time I do switch to the other craft close-by.

2. How do I go about detecting if there has been a docking or undocking - if possible, in a way where it can simply be a boolean return? (e.g. if (something has docked))

Link to comment
Share on other sites

It sounds like you would be best served by looking at GameEvents. You can add a void function to GameEvents.onVesselChanged and whatever the docking Event is to be called whenever that event happens.

I'm sorry, can you post an example please?

Link to comment
Share on other sites

Is there any way to get in the VAB the name of the ship?

I tried to access EditorLogic.shipNameField but it did not work.

EditorLogic.fetch.ship.name should do it iirc

I'm sorry, can you post an example please?

I believe GameEvents.onVesselDocked is what you are looking for. Add a fucntion to it. But FlightGlobals.ActiveVessel should change when you pres the [ and ] keys. So simply checking FlightGlobls.ActiveVessel == lastVessel in Update should be more than enough. Of course GameEvents are nicer but it can be done without here.

Link to comment
Share on other sites

I'm sorry, can you post an example please?


[KSPAddon(KSPAddon.Startup.MainMenu, true)]
public class DoingStuff : MonoBehaviour
{
public void Start()
{
GameEvents.onVesselChange.Add(somethingOnVesselChange);
}

public void OnDestroy()
{
GameEvents.onVesselChange.Remove(somethingOnVesselChange);
}

public void somethingOnVesselChange(Vessel v)
{
Debug.Log("Assuming Direct Control");
}
}

Something like that.

Link to comment
Share on other sites

EditorLogic.fetch.ship.name should do it iirc

Thanks for the fast answer. Here are the details.

EditorLogic.fetch.shipNameField.Text

String that is in the name field on top of the screen

EditorLogic.fetch.ship.shipName

Name of the ships save-file without ".craft" ending

Link to comment
Share on other sites

Will


public void OnDestroy()
{
GameEvents.onVesselChange.Remove(somethingOnVesselChange);
}

Not conflict with DontDestroyOnLoad(this);?

It depends what you mean by conflict. The code should just remove the eventhandler when the monobehaviour is destroyed - if its never destroyed (because of the DontDestroyOnLoad command) then OnDestroy is never called and the event handler would stay there till the app quits. You'd have to be careful around using the DontDestroyOnLoad and event registrations as if OnStart is called each load and onDestroy is never called you'll have the event handler registered multiple times. (I did this by mistake once in early code and it was driving me mad... but I got better :) )

Link to comment
Share on other sites

TBH I think thats determined by the purpose of your code, If you do have something where DontDestroyOnLoad is a requirement then you could separate the events stuff into another Monobehaviour that is destroyed on scene load, or alternately you could declare a static variable in the monobehaviour that you use to record your state of event registration. Think of it like a flag. Heres some sample code (but I havent tested it as I am on a train right now)

[KSPAddon(KSPAddon.Startup.MainMenu, true)]
public class DoingStuff : MonoBehaviour
{
private static Boolean EventsRegisteredFlag=false;
public void Start()
{
if (!EvenstRegisteredFlag)
{
GameEvents.onVesselChange.Add(somethingOnVesselChange);
EventsRegisteredFlag = true;
}
}

public void OnDestroy()
{
if (EventsRegisteredFlag)
{
GameEvents.onVesselChange.Remove(somethingOnVesselChange);
EventsRegisteredFlag = false;
}
}

public void somethingOnVesselChange(Vessel v)
{
Debug.Log("Assuming Direct Control");
}
}

This "should" manage your events :P

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