예제 #1
0
 public void AddHackyInAtmoLoad(Vessel hackyVessel)
 {
     if (!loadingFlyingVessels.ContainsKey(hackyVessel.id))
     {
         HackyFlyingVesselLoad hfvl = new HackyFlyingVesselLoad();
         hfvl.lastUnpackTime = Client.realtimeSinceStartup;
         loadingFlyingVessels.Add(hackyVessel.id, hfvl);
     }
 }
예제 #2
0
 private void OnGameSceneLoadRequested(GameScenes scene)
 {
     iterateVessels.Clear();
     iterateVessels.AddRange(loadingFlyingVessels.Keys);
     foreach (Guid vesselID in iterateVessels)
     {
         HackyFlyingVesselLoad hfvl = loadingFlyingVessels[vesselID];
         vesselWorker.KillVessel(hfvl.flyingVessel);
     }
     loadingFlyingVessels.Clear();
 }
예제 #3
0
 public void AddHackyInAtmoLoad(Vessel hackyVessel)
 {
     if (!loadingFlyingVessels.ContainsKey(hackyVessel.id))
     {
         HackyFlyingVesselLoad hfvl = new HackyFlyingVesselLoad();
         hfvl.flyingVessel = hackyVessel;
         hfvl.flyingVessel.vesselRanges.landed.load = hfvl.flyingVessel.vesselRanges.flying.unload - 100f;
         DarkLog.Debug("Default landed unload: " + hfvl.flyingVessel.vesselRanges.landed.unload);
         hfvl.flyingVessel.vesselRanges.landed.unload = hfvl.flyingVessel.vesselRanges.flying.unload;
         hfvl.lastUnpackTime = Client.realtimeSinceStartup;
         loadingFlyingVessels.Add(hackyVessel.id, hfvl);
     }
 }
 public void AddHackyInAtmoLoad(Vessel hackyVessel)
 {
     if (!loadingFlyingVessels.ContainsKey(hackyVessel.id))
     {
         HackyFlyingVesselLoad hfvl = new HackyFlyingVesselLoad();
         hfvl.flyingVessel = hackyVessel;
         hfvl.flyingVessel.vesselRanges.landed.load = hfvl.flyingVessel.vesselRanges.flying.unload - 100f;
         DarkLog.Debug("Default landed unload: " + hfvl.flyingVessel.vesselRanges.landed.unload);
         hfvl.flyingVessel.vesselRanges.landed.unload = hfvl.flyingVessel.vesselRanges.flying.unload;
         hfvl.lastUnpackTime = Time.realtimeSinceStartup;
         loadingFlyingVessels.Add(hackyVessel.id, hfvl);
     }
 }
예제 #5
0
 private void OnVesselUnpack(Vessel vessel)
 {
     if (loadingFlyingVessels.ContainsKey(vessel.id))
     {
         DarkLog.Debug("Hacky load successful: Vessel is off rails");
         HackyFlyingVesselLoad hfvl = loadingFlyingVessels[vessel.id];
         hfvl.flyingVessel.Landed    = false;
         hfvl.flyingVessel.Splashed  = false;
         hfvl.flyingVessel.landedAt  = string.Empty;
         hfvl.flyingVessel.situation = Vessel.Situations.FLYING;
         loadingFlyingVessels.Remove(vessel.id);
     }
 }
예제 #6
0
 private void OnVesselUnpack(Vessel vessel)
 {
     if (loadingFlyingVessels.ContainsKey(vessel.id))
     {
         DarkLog.Debug("Hacky load successful: Vessel is off rails");
         HackyFlyingVesselLoad hfvl = loadingFlyingVessels[vessel.id];
         hfvl.flyingVessel.Landed    = false;
         hfvl.flyingVessel.Splashed  = false;
         hfvl.flyingVessel.landedAt  = string.Empty;
         hfvl.flyingVessel.situation = Vessel.Situations.FLYING;
         if (hfvl.lastVesselUpdate != null)
         {
             //Stop the vessel from exploding while in unpack range.
             hfvl.lastVesselUpdate.Apply();
         }
         loadingFlyingVessels.Remove(vessel.id);
     }
 }
예제 #7
0
        //Also called from QuickSaveLoader
        public void LoadVessel(ConfigNode vesselNode)
        {
            if (vesselNode != null)
            {
                //Fix crew value numbers to Kerbal Names
                bool kerbalsDodged = DodgeVesselCrewValues(vesselNode);

                //Fix the "cannot control actiongroups bug" by dodging the last used time.
                DodgeVesselActionGroups(vesselNode);

                //Can be used for debugging incoming vessel config nodes.
                //vesselNode.Save(Path.Combine(KSPUtil.ApplicationRootPath, Path.Combine("DMP-RX", Planetarium.GetUniversalTime() + ".txt")));
                ProtoVessel currentProto = new ProtoVessel(vesselNode, HighLogic.CurrentGame);

                if (kerbalsDodged && (NetworkWorker.fetch.state == ClientState.STARTING) && !LockSystem.fetch.LockExists("control-" + currentProto.vesselID) && !LockSystem.fetch.LockExists("update-" + currentProto.vesselID))
                {
                    DarkLog.Debug("Sending kerbal-dodged vessel " + currentProto.vesselID + ", name: " + currentProto.vesselName);
                    NetworkWorker.fetch.SendVesselProtoMessage(currentProto, false, false);
                    foreach (ProtoPartSnapshot pps in currentProto.protoPartSnapshots)
                    {
                        if (pps.protoModuleCrew != null)
                        {
                            foreach (ProtoCrewMember pcm in pps.protoModuleCrew)
                            {
                                if (pcm != null)
                                {
                                    NetworkWorker.fetch.SendKerbalProtoMessage(pcm);
                                }
                            }
                        }
                    }
                }

                if (currentProto != null)
                {
                    //Skip already loaded EVA's
                    if ((currentProto.vesselType == VesselType.EVA) && (FlightGlobals.fetch.vessels.Find(v => v.id == currentProto.vesselID) != null))
                    {
                        return;
                    }

                    //Register asteroids from other players
                    if (currentProto.vesselType == VesselType.SpaceObject)
                    {
                        if (currentProto.protoPartSnapshots != null)
                        {
                            if (currentProto.protoPartSnapshots.Count == 1)
                            {
                                if (currentProto.protoPartSnapshots[0].partName == "PotatoRoid")
                                {
                                    DarkLog.Debug("Registering remote server asteroid");
                                    AsteroidWorker.fetch.RegisterServerAsteroid(currentProto.vesselID.ToString());
                                }
                            }
                        }
                    }

                    //Skip vessels that try to load in the safety bubble
                    if (isProtoVesselInSafetyBubble(currentProto))
                    {
                        DarkLog.Debug("Skipped loading protovessel " + currentProto.vesselID.ToString() + ", name: " + currentProto.vesselName + " because it is inside the safety bubble");
                        return;
                    }

                    //Skip flying vessel that are too far away
                    bool usingHackyAtmoLoad = false;
                    if (currentProto.situation == Vessel.Situations.FLYING)
                    {
                        DarkLog.Debug("Got a flying update for " + currentProto.vesselID + ", name: " + currentProto.vesselName);
                        if (currentProto.orbitSnapShot == null)
                        {
                            DarkLog.Debug("Skipping flying vessel load - Protovessel does not have an orbit snapshot");
                            return;
                        }
                        CelestialBody updateBody = FlightGlobals.fetch.bodies[currentProto.orbitSnapShot.ReferenceBodyIndex];
                        if (updateBody == null)
                        {
                            DarkLog.Debug("Skipping flying vessel load - Could not find celestial body index " + currentProto.orbitSnapShot.ReferenceBodyIndex);
                            return;
                        }
                        bool willGetKilledInAtmo = false;
                        if (updateBody.atmosphere)
                        {
                            double atmoPressure = updateBody.staticPressureASL * Math.Pow(Math.E, ((-currentProto.altitude) / (updateBody.atmosphereScaleHeight * 1000)));
                            //KSP magic cut off limit for killing vessels. Works out to be ~23km on kerbin.
                            if (atmoPressure > 0.01f)
                            {
                                willGetKilledInAtmo = true;
                            }
                        }
                        if (willGetKilledInAtmo)
                        {
                            if (HighLogic.LoadedScene == GameScenes.FLIGHT)
                            {
                                if ((FlightGlobals.fetch.vessels.Find(v => v.id == currentProto.vesselID) != null) && vesselPartCount.ContainsKey(currentProto.vesselID.ToString()) ? currentProto.protoPartSnapshots.Count == vesselPartCount[currentProto.vesselID.ToString()] : false)
                                {
                                    DarkLog.Debug("Skipping flying vessel load - Vessel has the same part count");
                                    return;
                                }
                                if (FlightGlobals.fetch.activeVessel == null)
                                {
                                    DarkLog.Debug("Skipping flying vessel load - We do not have an active vessel");
                                    return;
                                }
                                if (FlightGlobals.fetch.activeVessel.mainBody != updateBody)
                                {
                                    DarkLog.Debug("Skipping flying vessel load - We are on a different celestial body");
                                    return;
                                }
                                Vector3d ourPos = FlightGlobals.fetch.activeVessel.mainBody.GetWorldSurfacePosition(FlightGlobals.fetch.activeVessel.latitude, FlightGlobals.fetch.activeVessel.longitude, FlightGlobals.fetch.activeVessel.altitude);
                                Vector3d protoPos = updateBody.GetWorldSurfacePosition(currentProto.latitude, currentProto.longitude, currentProto.altitude);
                                double distance = Vector3d.Distance(ourPos, protoPos);
                                //We'll load the vessel if possible
                                if (distance > Vessel.loadDistance)
                                {
                                    DarkLog.Debug("Skipping flying vessel load - We are not close enough, distance: " + distance);
                                    return;
                                }
                                else
                                {
                                    DarkLog.Debug("Enabling FLYING vessel load!");
                                    //If the vessel is landed it won't be killed by the atmosphere
                                    currentProto.landed = true;
                                    usingHackyAtmoLoad = true;
                                }
                            }
                            else
                            {
                                DarkLog.Debug("Skipping flying vessel load - We cannot load vessels that will get killed in atmosphere while not in flight");
                                return;
                            }
                        }
                    }

                    RegisterServerVessel(currentProto.vesselID.ToString());
                    DarkLog.Debug("Loading " + currentProto.vesselID + ", name: " + currentProto.vesselName + ", type: " + currentProto.vesselType);

                    foreach (ProtoPartSnapshot part in currentProto.protoPartSnapshots)
                    {
                        //This line doesn't actually do anything useful, but if you get this reference, you're officially the most geeky person darklight knows.
                        part.temperature = ((part.temperature + 273.15f) * 0.8f) - 273.15f;

                        //Fix up flag URLS.
                        if (part.flagURL.Length != 0)
                        {
                            string flagFile = Path.Combine(Path.Combine(KSPUtil.ApplicationRootPath, "GameData"), part.flagURL + ".png");
                            if (!File.Exists(flagFile))
                            {
                                DarkLog.Debug("Flag '" + part.flagURL + "' doesn't exist, setting to default!");
                                part.flagURL = "Squad/Flags/default";
                            }
                        }
                    }

                    bool wasActive = false;
                    bool wasTarget = false;

                    if (HighLogic.LoadedScene == GameScenes.FLIGHT)
                    {
                        if (FlightGlobals.fetch.VesselTarget != null ? FlightGlobals.fetch.VesselTarget.GetVessel() != null : false)
                        {
                            wasTarget = FlightGlobals.fetch.VesselTarget.GetVessel().id == currentProto.vesselID;
                        }
                        if (wasTarget)
                        {
                            DarkLog.Debug("ProtoVessel update for target vessel!");
                        }
                        wasActive = (FlightGlobals.fetch.activeVessel != null) ? (FlightGlobals.fetch.activeVessel.id == currentProto.vesselID) : false;
                    }

                    for (int vesselID = FlightGlobals.fetch.vessels.Count - 1; vesselID >= 0; vesselID--)
                    {
                        Vessel oldVessel = FlightGlobals.fetch.vessels[vesselID];
                        if (oldVessel.id.ToString() == currentProto.vesselID.ToString())
                        {
                            //Don't replace the vessel if it's unpacked, not landed, close to the ground, and has the same amount of parts.
                            double hft = oldVessel.GetHeightFromTerrain();
                            if (oldVessel.loaded && !oldVessel.packed && !oldVessel.Landed && (hft != -1) && (hft < 1000) && (currentProto.protoPartSnapshots.Count == oldVessel.parts.Count))
                            {
                                DarkLog.Debug("Skipped loading protovessel " + currentProto.vesselID.ToString() + " because it is flying close to the ground and may get destroyed");
                                return;
                            }
                            //Don't kill the active vessel - Kill it after we switch.
                            //Killing the active vessel causes all sorts of crazy problems.
                            if (wasActive)
                            {
                                delayKillVessels.Add(oldVessel);
                            }
                            else
                            {
                                /*
                                 * Sorry guys - KSP's protovessel positioning is not as accurate as it could be.
                                 *
                                 * The loading vessel needs to come off rails in order for the error to be corrected,
                                 * but taking it off rails will allow the vessel to collide with others while it's in the incorrect spot for that fixed update.
                                 *
                                 * If the vessel is the selected target, close (unpacked), and has the same number of parts, we'll skip the protovessel load.
                                 */

                                if (wasTarget && !oldVessel.LandedOrSplashed && oldVessel.loaded && !oldVessel.packed && (oldVessel.parts.Count == currentProto.protoPartSnapshots.Count))
                                {

                                    DarkLog.Debug("Skipping loading protovessel " + currentProto.vesselID.ToString() + " because it is the selected target and may crash into us");
                                    return;
                                }

                                KillVessel(oldVessel);
                            }
                        }
                    }

                    vesselPartCount[currentProto.vesselID.ToString()] = currentProto.protoPartSnapshots.Count;
                    serverVesselsProtoUpdate[currentProto.vesselID.ToString()] = UnityEngine.Time.realtimeSinceStartup;
                    lastLoadVessel[currentProto.vesselID.ToString()] = UnityEngine.Time.realtimeSinceStartup;
                    currentProto.Load(HighLogic.CurrentGame.flightState);

                    if (currentProto.vesselRef != null)
                    {
                        if (usingHackyAtmoLoad)
                        {
                            //Dodge unpack/pack distances
                            currentProto.vesselRef.distanceUnpackThreshold = Vessel.loadDistance - 300;
                            currentProto.vesselRef.distanceLandedUnpackThreshold = Vessel.loadDistance - 300;
                            currentProto.vesselRef.distancePackThreshold = Vessel.loadDistance - 100;
                            currentProto.vesselRef.distanceLandedPackThreshold = Vessel.loadDistance - 100;
                            HackyFlyingVesselLoad hfvl = new HackyFlyingVesselLoad();
                            hfvl.flyingVessel = currentProto.vesselRef;
                            hfvl.loadTime = UnityEngine.Time.realtimeSinceStartup;
                            loadingFlyingVessels.Add(hfvl);
                        }

                        if (wasActive)
                        {
                            DarkLog.Debug("ProtoVessel update for active vessel!");
                            try
                            {
                                OrbitPhysicsManager.HoldVesselUnpack(5);
                                FlightGlobals.fetch.activeVessel.GoOnRails();
                                //Put our vessel on rails so we don't collide with the new copy
                            }
                            catch
                            {
                                DarkLog.Debug("WARNING: Something very bad happened trying to replace the vessel, skipping update!");
                                return;
                            }
                            newActiveVessel = currentProto.vesselRef;
                        }
                        if (wasTarget)
                        {
                            DarkLog.Debug("Set docking target");
                            FlightGlobals.fetch.SetVesselTarget(currentProto.vesselRef);
                        }
                        DarkLog.Debug("Protovessel Loaded");
                    }
                    else
                    {
                        DarkLog.Debug("Protovessel " + currentProto.vesselID + " failed to create a vessel!");
                    }
                }
                else
                {
                    DarkLog.Debug("protoVessel is null!");
                }
            }
            else
            {
                DarkLog.Debug("vesselNode is null!");
            }
        }
예제 #8
0
        private void UpdateVessels()
        {
            iterateVessels.Clear();
            iterateVessels.AddRange(loadingFlyingVessels.Keys);
            foreach (Guid vesselID in iterateVessels)
            {
                if (!loadingFlyingVessels.ContainsKey(vesselID))
                {
                    continue;
                }
                HackyFlyingVesselLoad hfvl = loadingFlyingVessels[vesselID];

                if (hfvl.flyingVessel == null || hfvl.flyingVessel.state == Vessel.State.DEAD)
                {
                    DarkLog.Debug("Hacky load failed: Vessel destroyed");
                    loadingFlyingVessels.Remove(vesselID);
                    continue;
                }

                if (!FlightGlobals.fetch.vessels.Contains(hfvl.flyingVessel))
                {
                    DarkLog.Debug("Hacky load failed: Vessel destroyed");
                    loadingFlyingVessels.Remove(vesselID);
                    continue;
                }

                if (!lockSystem.LockExists("update-" + vesselID) || lockSystem.LockIsOurs("update-" + vesselID))
                {
                    DarkLog.Debug("Hacky load removed: Vessel stopped being controlled by another player");
                    loadingFlyingVessels.Remove(vesselID);
                    vesselWorker.KillVessel(hfvl.flyingVessel);
                    continue;
                }

                if (hfvl.flyingVessel.loaded)
                {
                    if ((Client.realtimeSinceStartup - hfvl.lastUnpackTime) > UNPACK_INTERVAL)
                    {
                        DarkLog.Debug("Hacky load attempting to take loaded vessel off rails");
                        hfvl.lastUnpackTime = Client.realtimeSinceStartup;
                        try
                        {
                            hfvl.flyingVessel.GoOffRails();
                        }
                        catch (Exception e)
                        {
                            //Just in case, I don't think this can throw but you never really know with KSP.
                            DarkLog.Debug("Hacky load failed to take vessel of rails: " + e.Message);
                        }
                        continue;
                    }
                }

                if (!hfvl.flyingVessel.packed)
                {
                    DarkLog.Debug("Hacky load successful: Vessel is off rails");
                    loadingFlyingVessels.Remove(vesselID);
                    hfvl.flyingVessel.Landed    = false;
                    hfvl.flyingVessel.Splashed  = false;
                    hfvl.flyingVessel.landedAt  = string.Empty;
                    hfvl.flyingVessel.situation = Vessel.Situations.FLYING;
                    hfvl.flyingVessel.vesselRanges.landed.load   = LANDED_LOAD_DISTANCE_DEFAULT;
                    hfvl.flyingVessel.vesselRanges.landed.unload = LANDED_UNLOAD_DISTANCE_DEFAULT;
                    continue;
                }

                double atmoPressure = hfvl.flyingVessel.mainBody.GetPressure(hfvl.flyingVessel.altitude);
                if (atmoPressure < 0.01d)
                {
                    DarkLog.Debug("Hacky load successful: Vessel is now safe from atmo");
                    loadingFlyingVessels.Remove(vesselID);
                    hfvl.flyingVessel.Landed    = false;
                    hfvl.flyingVessel.Splashed  = false;
                    hfvl.flyingVessel.landedAt  = string.Empty;
                    hfvl.flyingVessel.situation = Vessel.Situations.FLYING;
                    hfvl.flyingVessel.vesselRanges.landed.load   = LANDED_LOAD_DISTANCE_DEFAULT;
                    hfvl.flyingVessel.vesselRanges.landed.unload = LANDED_UNLOAD_DISTANCE_DEFAULT;
                    continue;
                }

                if (hfvl.lastVesselUpdate != null)
                {
                    hfvl.lastVesselUpdate.Apply();
                }
            }
        }