TAC Life Support

TAC Life Support

347k Downloads

Duplicate vessels being tracked when docking

SirBriguy opened this issue ยท 4 comments

commented

When docking 2 vessels, the life support tracking keeps the old vessel in the tracking list, even though the vessel no longer exists. This is easy to reproduce:

  1. Cheat an empty crew pod with a docking port and a science lab (needs to be heavier than the craft in step 2) into orbit
  2. Cheat a crew pod with a docking port and a little rcs control and 1 crew into a rendezvous with the first pod
  3. Dock them
  4. The life support list will have both pods in the list with crew, even though there is only 1 vessel now

Attached is a log file and a save from a stock + TAC-LS sandbox. There is a quick save from the point just before the 2 ships dock.

In testing, I noticed that it only has the problem when the crewed ship is lighter than the uncrewed ship. I think when KSP docks 2 vessels, the heavier one becomes the new vessel and the lighter one goes away. So if the crewed ship is lighter, it goes away and leave the entry in the tracking list.

I took a look through the code and I don't see any errors. I think there is just no event being handled for the old vessel going away. I made a change when updating the vessels to see if each vessel in the list still exists and if not, remove it and that seemed to make the extra vessel go away. I am not sure if there is a better way to handle the situation. I think you would have to handle some event for the docking (if there is one) and remove the old ship from the list.

Here is the snippet of code I added to LifeSupportController.cs in the FixedUpdate():

        bool DoesVesselExist(Guid id)
        {
            var allvessels = FlightGlobals.Vessels;
            for (int i = 0; i < allvessels.Count; ++i)
            {
                if (allvessels[i].id == id)
                {
                    return true;
                }
            }
            return false;
        }

        void FixedUpdate()
        {
...
            //Iterate the knownVessels dictionary
            foreach (var entry in gameSettings.knownVessels)
            {
                if (!DoesVesselExist(entry.Key))
                {
                    // vessel no longer exists, remove it from our list
                    RemoveVesselTracking(entry.Key);
                    // no more processing needed
                    continue;
                }
                //If vessel is a recovery vessel check if it's EVA (Kerbal) or not. If it isn't we skip it completely.
                //If it is EVA (rescue kerbal) we continue processing.
...

commented

No the code should simply handle it via a GameEvent. But in this case the simple line will suffice.

commented

Have you profiled this? Depending on how the FlightGlobals.Vessels property is implemented it might be heavy-handed to perform this on every single FixedUpdate(). An alternative would be to prune the tracking list only periodically and then also just before a significant action is triggered by TACLS (killing a Kerbal for example).

commented

No I did not profile it. However, there might be a simple case by adding and else case at line 270

                    //Did we find the unloaded vessel?
                    if (unloadedvessel != null)
                    {
...
                    }
                    else
                    {
                        // vessel no longer exists, remove it from our list
                        RemoveVesselTracking(entry.Key);
                    }
commented

Implemented in 0.12.8