Jump to content

[0.23.5] updated auto load on startup code?


Recommended Posts

Hello.

I am trying to use the popular automatically-load-some-savegame-on-KSP-start code that has been floating around. It looks like this:


using KSP;
using UnityEngine;


//This will kick us into the save called default and set the first vessel active
[KSPAddon(KSPAddon.Startup.MainMenu, false)]
public class Debug_AutoLoadPersistentSaveOnStartup : MonoBehaviour
{
//use this variable for first run to avoid the issue with when this is true and multiple addons use it
public static bool first = true;
public void Start()
{
//only do it on the first entry to the menu
if (first)
{
first = false;
HighLogic.SaveFolder = "default";
var game = GamePersistence.LoadGame("persistent", HighLogic.SaveFolder, true, false);
if (game != null && game.flightState != null && game.compatible) {
FlightDriver.StartAndFocusVessel(game, game.flightState.activeVesselIdx);
} // end if
//CheatOptions.InfiniteFuel = true;
//CheatOptions.InfiniteRCS = true;
}
}
}

The problem with this code after 0.23.5 is that the game is populated with asteroids, and they are Vessels, and they are usually in your game before your testing vessel.

So, I tried to find the first vessel with SCANsat equipment on it (which presumably would work fine). However, I can only see a way to get a Vessel or a GUID back from the Vessel. I don't know how to get the right vessel.

I did find a workaround, however, until someone suggests the correct way:


using KSP;
using UnityEngine;
using SCANsat;


//This will kick us into the save called default and set the first vessel active
[KSPAddon(KSPAddon.Startup.MainMenu, false)]
public class Debug_AutoLoadPersistentSaveOnStartup : MonoBehaviour
{
//use this variable for first run to avoid the issue with when this is true and multiple addons use it
public static bool first = true;
public void Start()
{
//only do it on the first entry to the menu
if (first)
{
first = false;
HighLogic.SaveFolder = "SCANsat Testing";
var game = GamePersistence.LoadGame([B]"quicksave"[/B], HighLogic.SaveFolder, true, false);
if (game != null && game.flightState != null && game.compatible) {
foreach(Vessel v in FlightGlobals.Vessels) {
if (SCANsat.SCANcontroller.controller.isVesselKnown(v)) {
FlightGlobals.ForceSetActiveVessel (v);
/* FIXME: we should set the active vessel here, or convert it into an int somehow */
break;
}
}
/* and we should use that int here */
FlightDriver.StartAndFocusVessel(game, game.flightState.activeVesselIdx);
} // end if
//CheatOptions.InfiniteFuel = true;
//CheatOptions.InfiniteRCS = true;
}
}
}

So just make a quicksave while the vessel in question is active, and load it instead of the persistent file.

Edited by technogeeky
Link to comment
Share on other sites

This is the update I made in my plugins. Using a for loop and breaking out when you find the vessel you want gives you the index to go to. In this code I am simply looking for the first vessel in the save that is not an unknown or spaceobject - if you want some more logic like your scansat check you could add it where I've made the comments

The #if DEBUG and #endif mean I never have to rem the code, I just build the release version for publishing and this is not included.

Reminds me I should update my blog post about that too


#if DEBUG
//This will kick us into the save called default and set the first vessel active
[KSPAddon(KSPAddon.Startup.MainMenu, false)]
public class Debug_AutoLoadPersistentSaveOnStartup : MonoBehaviour
{
//use this variable for first run to avoid the issue with when this is true and multiple addons use it
public static bool first = true;
public void Start()
{
//only do it on the first entry to the menu
if (first)
{
first = false;
HighLogic.SaveFolder = "default";
Game game = GamePersistence.LoadGame("persistent", HighLogic.SaveFolder, true, false);

if (game != null && game.flightState != null && game.compatible)
{
Int32 FirstVessel;
Boolean blnFoundVessel=false;
for (FirstVessel = 0; FirstVessel < game.flightState.protoVessels.Count; FirstVessel++)
{
if (game.flightState.protoVessels[FirstVessel].vesselType != VesselType.SpaceObject &&
game.flightState.protoVessels[FirstVessel].vesselType != VesselType.Unknown)
{
[COLOR="#008000"]////////////////////////////////////////////////////
//PUT ANY OTHER LOGIC YOU WANT IN HERE//
////////////////////////////////////////////////////[/COLOR]
blnFoundVessel = true;
break;
}
}
if (!blnFoundVessel)
FirstVessel = 0;
FlightDriver.StartAndFocusVessel(game, FirstVessel);
}

//CheatOptions.InfiniteFuel = true;
}
}
}
#endif

Link to comment
Share on other sites

Updated my other stuff too, but forgot to say if you want to do your scansat test you keep your if statement and use the game.flightState.protoVessels[FirstVessel].vesselRef property to do the test.

eg. this part


if (game.flightState.protoVessels[FirstVessel].vesselType != VesselType.SpaceObject &&
game.flightState.protoVessels[FirstVessel].vesselType != VesselType.Unknown)
{
////////////////////////////////////////////////////
//PUT ANY OTHER LOGIC YOU WANT IN HERE//
////////////////////////////////////////////////////
blnFoundVessel = true;
break;
}

...becomes...


if (game.flightState.protoVessels[FirstVessel].vesselType != VesselType.SpaceObject &&
game.flightState.protoVessels[FirstVessel].vesselType != VesselType.Unknown)
{
if (SCANsat.SCANcontroller.controller.isVesselKnown(game.flightState.protoVessels[FirstVessel].vesselRef))
{
blnFoundVessel = true;
break;
}
}

I just added an internal if to the first one then you can change this check whenever you need

Edited by TriggerAu
Link to comment
Share on other sites

So just make a quicksave while the vessel in question is active, and load it instead of the persistent file.

That was the first change I made to this snippet when I came across it in a forum post months ago. Why would you load the persistent save anyway?

Link to comment
Share on other sites

Thanks!

I ran across ProtoVessels (and other Proto*-classes). What are those things for, in general?

No probs

For the proto stuff - TBH I am only guessing, but I think they are like a subset of a full object. So a protovessel contains a list of some vessel properties and a link to the actual vessel so you can dig deeper. It would make code quicker to iterate through a list of smaller objects. But like I said, I'm just guessing, only an actual game dev would know the real reason :)

Link to comment
Share on other sites

No probs

For the proto stuff - TBH I am only guessing, but I think they are like a subset of a full object. So a protovessel contains a list of some vessel properties and a link to the actual vessel so you can dig deeper. It would make code quicker to iterate through a list of smaller objects. But like I said, I'm just guessing, only an actual game dev would know the real reason :)

FYI, in the end I went with this:


using KSP;
using UnityEngine;
using SCANsat;
using System.Collections.Generic;


[KSPAddon(KSPAddon.Startup.MainMenu, false)]
public class Debug_AutoLoadPersistentSaveOnStartup : MonoBehaviour
{

public static bool first = true;
public static int vId = 0;
public void Start()
{

if (first)
{
first = false;
HighLogic.SaveFolder = "SCANsat Testing";
var game = GamePersistence.LoadGame("persistent", HighLogic.SaveFolder, true, false);
if (game != null && game.flightState != null && game.compatible) {

List<ProtoVessel> allVessels = game.flightState.protoVessels;
int suitableVessel = 0;

for (vId = 0; vId < allVessels.Count; vId++) {
switch (allVessels[vId].vesselType) {
case VesselType.SpaceObject: continue; // asteroids
case VesselType.Unknown: continue; // asteroids in facepaint
default: suitableVessel = vId; // this one will do
break;
}
/* If you want a more stringent filter than
* "vessel is not inert ball of space dirt", then you
* will want to do it here.
*/
}
FlightDriver.StartAndFocusVessel(game, suitableVessel);
}
}
}
}

Link to comment
Share on other sites

I ran across ProtoVessels (and other Proto*-classes). What are those things for, in general?

Proto* are a conversion layer from & towards config nodes. The game will use them whenever you load or save your game. Thus they can be pretty helpful to find out what some stuff in a savegame means, since they mostly hold the same data with a longer property name or even partially serialize data.

Link to comment
Share on other sites

Proto* are a conversion layer from & towards config nodes. The game will use them whenever you load or save your game. Thus they can be pretty helpful to find out what some stuff in a savegame means, since they mostly hold the same data with a longer property name or even partially serialize data.

Nice Faark.. good to know I was totally wrong :)

Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

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