public void SendVesselMessage(Vessel vessel) { if (vessel == null) { return; } //Update the protovessel definition! vessel.BackupVessel(); //Defend against NaN orbits if (VesselHasNaNPosition(vessel.protoVessel)) { LunaLog.Log($"[LMP]: Vessel {vessel.id} has NaN position"); return; } foreach (var pps in vessel.protoVessel.protoPartSnapshots) { //Remove tourists from the vessel //TODO: Probably this can be done in the CleanUpVesselNode method foreach (var pcm in pps.protoModuleCrew.Where(pcm => pcm.type == ProtoCrewMember.KerbalType.Tourist).ToArray()) { pps.protoModuleCrew.Remove(pcm); } } var vesselNode = new ConfigNode(); try { vessel.protoVessel.Save(vesselNode); } catch (Exception) { LunaLog.LogError("[LMP]: Error while saving vessel"); return; } //Clean up the vessel so we send only the important data CleanUpVesselNode(vesselNode, vessel.id); var vesselBytes = ConfigNodeSerializer.Serialize(vesselNode); if (vesselBytes.Length > 0) { UniverseSyncCache.QueueToCache(vesselBytes); SendMessage(new VesselProtoMsgData { VesselId = vessel.id, VesselData = vesselBytes }); } else { LunaLog.LogError($"[LMP]: Failed to create byte[] data for {vessel.id}"); } }
private void OnVesselWillDestroy(Vessel vessel) { if (vesselWorker.VesselRecentlyKilled(vessel.id)) { return; } bool pilotedByAnotherPlayer = lockSystem.LockExists("control-" + vessel.id) && !lockSystem.LockIsOurs("control-" + vessel.id); bool updatedByAnotherPlayer = lockSystem.LockExists("update-" + vessel.id) && !lockSystem.LockIsOurs("update-" + vessel.id); bool updatedInTheFuture = vesselWorker.VesselUpdatedInFuture(vessel.id); //Vessel was packed within the last 5 seconds if (lastPackTime.ContainsKey(vessel.id) && (Client.realtimeSinceStartup - lastPackTime[vessel.id]) < 5f) { lastPackTime.Remove(vessel.id); if (vessel.situation == Vessel.Situations.FLYING && (pilotedByAnotherPlayer || updatedByAnotherPlayer || updatedInTheFuture)) { DarkLog.Debug("Hacky load: Saving player vessel getting packed in atmosphere"); ProtoVessel pv = vessel.BackupVessel(); ConfigNode savedNode = new ConfigNode(); pv.Save(savedNode); vesselWorker.LoadVessel(savedNode, vessel.id, true); } } if (lastPackTime.ContainsKey(vessel.id)) { lastPackTime.Remove(vessel.id); } }
public void SendVesselMessage(Vessel vessel, bool forceReload = false) { if (vessel == null || vessel.state == Vessel.State.DEAD || VesselRemoveSystem.Singleton.VesselWillBeKilled(vessel.id)) { return; } if (!vessel.orbitDriver) { LunaLog.LogWarning($"Cannot send vessel {vessel.vesselName} - {vessel.id}. It's orbit driver is null!"); return; } if (vessel.orbitDriver.Ready()) { vessel.protoVessel = vessel.BackupVessel(); SendVesselMessage(vessel.protoVessel, forceReload); } else { //Orbit driver is not ready so wait max 10 frames until it's ready CoroutineUtil.StartConditionRoutine("SendVesselMessage", () => SendVesselMessage(vessel), () => vessel.orbitDriver.Ready(), 10); } }
public void SendVesselMessage(Vessel vessel, bool forceSend, bool forceReloadOnReceive) { if (vessel == null || (!forceSend && VesselCommon.IsSpectating) || vessel.state == Vessel.State.DEAD || VesselRemoveSystem.Singleton.VesselWillBeKilled(vessel.id)) { return; } if (!forceSend && !LockSystem.LockQuery.UnloadedUpdateLockBelongsToPlayer(vessel.id, SettingsSystem.CurrentSettings.PlayerName)) { return; } if (!forceSend && !LockSystem.LockQuery.UpdateLockBelongsToPlayer(vessel.id, SettingsSystem.CurrentSettings.PlayerName)) { return; } var vesselHasChanges = VesselToProtoRefresh.RefreshVesselProto(vessel); if (forceSend || vesselHasChanges || !VesselsProtoStore.AllPlayerVessels.ContainsKey(vessel.id)) { SendVesselMessage(vessel.BackupVessel(), forceReloadOnReceive); } if (!VesselsProtoStore.AllPlayerVessels.ContainsKey(vessel.id)) { VesselsProtoStore.AddOrUpdateVesselToDictionary(vessel); } }
public void ExportSelectedCraft(Vessel vessel) { CreateFolder(); string filename = KSPUtil.ApplicationRootPath + "/Ships/export/" + HighLogic.SaveFolder + "_" + vessel.vesselName; Log($"Exporting vessel: {vessel.vesselName}\nExporting to file: {filename}"); ConfigNode nodeToSave = new ConfigNode(); //save vessel ConfigNode vesselNode = new ConfigNode("VESSEL"); ProtoVessel pVessel = vessel.BackupVessel(); pVessel.Save(vesselNode); nodeToSave.AddNode("VESSEL", vesselNode); //save active crew member info foreach (ProtoCrewMember pcm in pVessel.GetVesselCrew()) { ConfigNode pcmNode = new ConfigNode("CREW"); pcm.Save(pcmNode); nodeToSave.AddNode("CREW", pcmNode); } nodeToSave.Save(filename); ScreenMessage message = new ScreenMessage(vessel.vesselName + " exported to " + filename, 6, ScreenMessageStyle.UPPER_CENTER); ScreenMessages.PostScreenMessage(message); }
public static void UnhangarCraft(Vessel vVesselStored, StaticObject soHangar) { RemoveCorrectCraft(vVesselStored, soHangar); // Convert the stored protovessel to a new protovessel. // Use BackupVessel because that seems to work and protovessel does not. `\o/` ProtoVessel pVessel = vVesselStored.BackupVessel(); // Get rid of the original hidden vessel - even though it was unloaded KSP still 'sees' the original craft. // I do not care why. :| vVesselStored.state = Vessel.State.DEAD; foreach (Part p in vVesselStored.Parts) { if (p != null && p.gameObject != null) { p.gameObject.DestroyGameObject(); } } // Load the new protovessel we made. KSP won't reload (or rather render) a vessel that was unloaded - it will only load a protovessel. :$ pVessel.Load(FlightDriver.FlightStateCache.flightState); // I suspect this is actually a KSP bug since the same crap happens with newly spawned static objects. If you query the active state // of the invisible craft, it claims it is active. And no, forcing the renderers doesn't work either. // Convert protovessel to vessel Vessel vNewVessel = pVessel.vesselRef; // Unload then reload the vessel - this seems to be the way to properly re-initialise flightstate etc. // Don't do this and you get a craft with a stuck surface velocity reading. It looks like KSP transposes orbital // and surface velocity or some other stupid s**t. I don't care. // And yes, this time KSP does load an unloaded vessel with no need for protovessel b******t. I don't care why. vNewVessel.Unload(); vNewVessel.Load(); }
private static string GetInvalidVesselParts(Vessel checkVessel) { var bannedParts = checkVessel.BackupVessel().protoPartSnapshots .Where(p => !SystemsContainer.Get <ModSystem>().AllowedParts.Contains(p.partName.ToLower())).Distinct(); var bannedPartsStr = bannedParts.Aggregate("", (current, bannedPart) => current + $"{bannedPart}\n"); return(bannedPartsStr); }
public void SendDockInformation(Guid weakVesselId, Vessel dominantVessel, int subspaceId) { var vesselBytes = VesselSerializer.SerializeVessel(dominantVessel.BackupVessel()); if (vesselBytes.Length > 0) { CreateAndSendDockMessage(weakVesselId, dominantVessel.id, subspaceId, vesselBytes); } }
// static functions, that make live a lot easier /// <summary> /// Stores a Vessel into the specified Hangar /// </summary> internal static void StoreVessel(Vessel vessel, Hangar hangar) { StoredVessel storedVessel = new StoredVessel { uuid = vessel.protoVessel.vesselID, vesselName = vessel.GetDisplayName() }; //get the experience and assign the crew to the rooster foreach (Part part in vessel.parts) { int count = part.protoModuleCrew.Count; if (count != 0) { ProtoCrewMember[] crewList = part.protoModuleCrew.ToArray(); for (int i = 0; i < count; i++) { crewList[i].flightLog.AddEntryUnique(FlightLog.EntryType.Recover); crewList[i].flightLog.AddEntryUnique(FlightLog.EntryType.Land, FlightGlobals.currentMainBody.name); crewList[i].ArchiveFlightLog(); // remove the crew from the ship part.RemoveCrewmember(crewList[i]); } } } // save the ship storedVessel.vesselNode = new ConfigNode("VESSEL"); //create a backup of the current state, then save that state ProtoVessel backup = vessel.BackupVessel(); backup.Save(storedVessel.vesselNode); // save the stored information in the hangar hangar.storedVessels.Add(storedVessel); // remove the stored vessel from the game vessel.MakeInactive(); vessel.Unload(); //vessel.Die(); FlightGlobals.RemoveVessel(vessel); if (vessel != null) { vessel.protoVessel.Clean(); } //UnityEngine.Object.Destroy(vessel.gameObject); GamePersistence.SaveGame("persistent", HighLogic.SaveFolder, SaveMode.OVERWRITE); HighLogic.LoadScene(GameScenes.SPACECENTER); }
public void SendVesselMessage(Vessel vessel) { if (vessel == null || vessel.state == Vessel.State.DEAD || VesselRemoveSystem.Singleton.VesselWillBeKilled(vessel.id)) { return; } vessel.protoVessel = vessel.BackupVessel(); SendVesselMessage(vessel.protoVessel); }
private static string GetInvalidVesselParts(Vessel checkVessel) { var bannedParts = checkVessel.BackupVessel().protoPartSnapshots .Where(p => !ModSystem.Singleton.AllowedParts.Contains(p.partName.ToLower())).Distinct().ToArray(); var bannedPartsStr = bannedParts.Aggregate("", (current, bannedPart) => current + (bannedPart + "\n")); Debug.Log($"[LMP]: Checked vessel {checkVessel.id } for banned parts, is ok: {bannedParts.Length == 0}"); return(bannedPartsStr); }
private void OnVesselCreate(Vessel vessel) { ProtoVessel pv = vessel.BackupVessel(); List<uint> vesselParts = new List<uint>(); bool killShip = false; bool vesselOk = false; foreach (ProtoPartSnapshot pps in pv.protoPartSnapshots) { if (pps.flightID == 0) { loadGuid = vessel.id; //When you spawn a new vessel in all the part ID's are 0 until OnFlightReady. return; } vesselParts.Add(pps.flightID); if (partToVessel.ContainsKey(pps.flightID)) { killShip = true; foreach (Vessel otherVessel in partToVessel[pps.flightID]) { if (otherVessel.id == vessel.id) { vesselOk = true; } //Either of the locks are ours or neither of the locks exist if (LockSystem.fetch.LockIsOurs("control-" + otherVessel.id) || LockSystem.fetch.LockIsOurs("update-" + otherVessel.id) || (!LockSystem.fetch.LockExists("control-" + otherVessel.id) && !LockSystem.fetch.LockExists("update-" + otherVessel.id))) { vesselOk = true; } } } } if (killShip && !vesselOk) { DarkLog.Debug("PartKiller: Destroying vessel fragment"); vessel.Die(); } else { vesselToPart.Add(vessel, vesselParts); foreach (uint partID in vesselParts) { if (!partToVessel.ContainsKey(partID)) { partToVessel.Add(partID, new List<Vessel>()); } partToVessel[partID].Add(vessel); } } }
private void OnVesselCreate(Vessel vessel) { ProtoVessel pv = vessel.BackupVessel(); List <uint> vesselParts = new List <uint>(); bool killShip = false; bool vesselOk = false; foreach (ProtoPartSnapshot pps in pv.protoPartSnapshots) { if (pps.flightID == 0) { loadGuid = vessel.id; //When you spawn a new vessel in all the part ID's are 0 until OnFlightReady. return; } vesselParts.Add(pps.flightID); if (partToVessel.ContainsKey(pps.flightID)) { killShip = true; foreach (Vessel otherVessel in partToVessel[pps.flightID]) { if (otherVessel.id == vessel.id) { vesselOk = true; } //Either of the locks are ours or neither of the locks exist if (lockSystem.LockIsOurs("control-" + otherVessel.id) || lockSystem.LockIsOurs("update-" + otherVessel.id) || (!lockSystem.LockExists("control-" + otherVessel.id) && !lockSystem.LockExists("update-" + otherVessel.id))) { vesselOk = true; } } } } if (killShip && !vesselOk) { DarkLog.Debug("PartKiller: Destroying vessel fragment"); vessel.Die(); } else { vesselToPart.Add(vessel, vesselParts); foreach (uint partID in vesselParts) { if (!partToVessel.ContainsKey(partID)) { partToVessel.Add(partID, new List <Vessel>()); } partToVessel[partID].Add(vessel); } } }
public void ExportSelectedCraft(Vessel vessel) { CreateFolder(); string vname1 = vessel.vesselName; string vname = ""; Localizer.TryGetStringByTag(vname1, out vname); if (vname == "" || vname == null) { vname = vname1; } string filename = KSPUtil.ApplicationRootPath + "Ships/export/" + HighLogic.SaveFolder + "_" + vname; Log($"Exporting vessel: {vessel.vesselName}\nExporting to file: {filename}"); ConfigNode nodeToSave = new ConfigNode(); //save vessel ConfigNode vesselNode = new ConfigNode("VESSEL"); ProtoVessel pVessel = vessel.BackupVessel(); pVessel.Save(vesselNode); nodeToSave.AddNode("VESSEL", vesselNode); //save active crew member info foreach (ProtoCrewMember pcm in pVessel.GetVesselCrew()) { ConfigNode pcmNode = new ConfigNode("CREW"); pcm.Save(pcmNode); nodeToSave.AddNode("CREW", pcmNode); } nodeToSave.Save(filename); //ScreenMessage message = new ScreenMessage(vname+" exported to "+filename, 6, ScreenMessageStyle.UPPER_CENTER); //ScreenMessages.PostScreenMessage(message); PopupDialog.SpawnPopupDialog(new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), "Export", "Export Complete", "Vessel has been exported to:\n" + filename, "Ok", false, HighLogic.UISkin); }
public void SendVesselMessage(Vessel vessel, bool force) { if (vessel == null || VesselCommon.IsSpectating || vessel.state == Vessel.State.DEAD || VesselRemoveSystem.Singleton.VesselWillBeKilled(vessel.id)) { return; } var vesselHasChanges = VesselToProtoRefresh.RefreshVesselProto(vessel); if (force || vesselHasChanges || !VesselsProtoStore.AllPlayerVessels.ContainsKey(vessel.id)) { SendVesselMessage(vessel.BackupVessel()); } if (!VesselsProtoStore.AllPlayerVessels.ContainsKey(vessel.id)) { VesselsProtoStore.AddOrUpdateVesselToDictionary(vessel); } }
private void OnVesselWasModified(Vessel vessel) { if (!vesselToPart.ContainsKey(vessel)) { //Killed as a fragment. return; } List <uint> addList = new List <uint>(); List <uint> removeList = new List <uint>(vesselToPart[vessel]); ProtoVessel pv = vessel.BackupVessel(); foreach (ProtoPartSnapshot pps in pv.protoPartSnapshots) { if (removeList.Contains(pps.flightID)) { removeList.Remove(pps.flightID); } else { addList.Add(pps.flightID); } } foreach (uint partID in addList) { if (!partToVessel.ContainsKey(partID)) { partToVessel.Add(partID, new List <Vessel>()); } partToVessel[partID].Add(vessel); vesselToPart[vessel].Add(partID); } foreach (uint partID in removeList) { vesselToPart[vessel].Remove(partID); partToVessel[partID].Remove(vessel); if (partToVessel[partID].Count == 0) { partToVessel.Remove(partID); } } }
public void SendVesselMessage(Vessel vessel, bool force) { if (vessel == null || VesselCommon.IsSpectating || vessel.state == Vessel.State.DEAD) { return; } VesselProtoSystem.CurrentlyUpdatingVesselId = vessel.id; var vesselHasChanges = VesselToProtoRefresh.RefreshVesselProto(vessel); VesselProtoSystem.CurrentlyUpdatingVesselId = Guid.Empty; if (force || vesselHasChanges || !VesselsProtoStore.AllPlayerVessels.ContainsKey(vessel.id)) { SendVesselMessage(vessel.BackupVessel()); } if (!VesselsProtoStore.AllPlayerVessels.ContainsKey(vessel.id)) { VesselsProtoStore.AddVesselToDictionary(vessel); } }
public static void FlushVesselCache(string unloadedSeed, Guid unloadIgnoreID) { // Save a snapshot PersistenceGenerator.SaveSnapshot(unloadedSeed); // Cache the current system Vessel[] allVessels = GameObject.FindObjectsOfType <Vessel> (); List <Vessel> unclearableVessels = new List <Vessel> (); // Despawn all vessels Debugger.Log(allVessels.Length + " vessels need to be despawed."); if (unloadIgnoreID != Guid.Empty) { Debugger.Log("Vessel with ID " + unloadIgnoreID.ToString() + " will be ignored."); } for (int i = 0; i < allVessels.Length; i++) { Vessel vessel = allVessels [i]; // Clear the vessel unless we are asked to ignore it if (vessel.id != unloadIgnoreID || unloadIgnoreID == Guid.Empty) { vesselSeeds [vessel.id] = unloadedSeed; if (!RemoveVesselFromSystem(vessel)) { Debugger.LogWarning("Could not unload " + vessel.name); unclearableVessels.Add(vessel); } } } // Clear the vessel cache FlightGlobals.Vessels.Clear(); HighLogic.CurrentGame.flightState.protoVessels.Clear(); // If we couldn't unload something, ensure it's not duplicated foreach (Vessel vessel in unclearableVessels) { FlightGlobals.Vessels.Add(vessel); HighLogic.CurrentGame.flightState.protoVessels.Add(vessel.BackupVessel()); } }
private void OnVesselWillDestroy(Vessel vessel) { bool pilotedByAnotherPlayer = LockSystem.fetch.LockExists("control-" + vessel.id) && !LockSystem.fetch.LockIsOurs("control-" + vessel.id); bool updatedByAnotherPlayer = LockSystem.fetch.LockExists("update-" + vessel.id) && !LockSystem.fetch.LockIsOurs("update-" + vessel.id); bool updatedInTheFuture = VesselWorker.fetch.VesselUpdatedInFuture(vessel.id); //Vessel was packed within the last 5 seconds if (lastPackTime.ContainsKey(vessel.id) && (UnityEngine.Time.realtimeSinceStartup - lastPackTime[vessel.id]) < 5f) { lastPackTime.Remove(vessel.id); if (vessel.situation == Vessel.Situations.FLYING && (pilotedByAnotherPlayer || updatedByAnotherPlayer || updatedInTheFuture)) { DarkLog.Debug("Hacky load: Saving player vessel getting packed in atmosphere"); ProtoVessel pv = vessel.BackupVessel(); ConfigNode savedNode = new ConfigNode(); pv.Save(savedNode); VesselWorker.fetch.LoadVessel(savedNode, vessel.id, true); } } if (lastPackTime.ContainsKey(vessel.id)) { lastPackTime.Remove(vessel.id); } }
public static PersistentVessel CreateVessel(string seed, Vessel vessel) { return(CreateVessel(seed, vessel.BackupVessel())); }
public StoredVessel(Vessel vsl) { vessel = vsl.BackupVessel(); metric = new Metric(vsl); id = vessel.vesselID; CoM = vsl.findLocalCenterOfMass(); crew = vsl.GetVesselCrew(); resources = new VesselResources<ProtoVessel, ProtoPartSnapshot, ProtoPartResourceSnapshot>(vessel); // fixTripLogger(); //FIXME }
public void OnVesselCreate(Vessel createdVessel) { try { //DarkLog.Debug("Vessel creation detected: " + createdVessel.id + ", name: " + createdVessel.vesselName); ProtoVessel pv = createdVessel.BackupVessel(); bool killShip = false; bool spawnDebris = false; string partOwner = null; string createdVesselID = pv.vesselID.ToString(); foreach (ProtoPartSnapshot vesselPart in pv.protoPartSnapshots) { if (vesselPart != null) { if (vesselParts.ContainsKey(vesselPart.flightID.ToString())) { partOwner = vesselParts[vesselPart.flightID.ToString()]; if (!killShip && (createdVesselID != partOwner)) { if (LockSystem.fetch.LockIsOurs("control-" + partOwner) || LockSystem.fetch.LockIsOurs("update-" + partOwner) || !LockSystem.fetch.LockExists("update-" + partOwner)) { //Vessel is ours, update the part owner. spawnDebris = true; vesselParts[vesselPart.flightID.ToString()] = createdVesselID; } else { DarkLog.Debug("Detected debris for a vessel we do not control, removing " + createdVesselID); killShip = true; break; } } } } } if (killShip) { createdVessel.Die(); } if (spawnDebris) { //DarkLog.Debug("Spawned debris " + createdVesselID + " from " + partOwner); } } catch (Exception e) { DarkLog.Debug("Threw in OnVesselCreate: " + e); } }
private void CheckVesselParts(Vessel checkVessel) { List<string> allowedParts = ModWorker.fetch.GetAllowedPartsList(); List<string> bannedParts = new List<string>(); ProtoVessel checkProto = checkVessel.BackupVessel(); foreach (ProtoPartSnapshot part in checkProto.protoPartSnapshots) { if (!allowedParts.Contains(part.partName)) { if (!bannedParts.Contains(part.partName)) { bannedParts.Add(part.partName); } } } if (checkVessel.isActiveVessel) { bannedPartsString = ""; foreach (string bannedPart in bannedParts) { bannedPartsString += bannedPart + "\n"; } } DarkLog.Debug("Checked vessel " + checkVessel.id.ToString() + " for banned parts, is ok: " + (bannedParts.Count == 0)); vesselPartsOk[checkVessel.id] = (bannedParts.Count == 0); }
private bool loadVesselForRendezvous(ProtoVessel placeVessel, Vessel targetVessel) { targetVessel.BackupVessel(); placeVessel.orbitSnapShot = targetVessel.protoVessel.orbitSnapShot; placeVessel.orbitSnapShot.epoch = 0.0; tempID = RmmUtil.Rand.Next(1000000000).ToString(); //rename any vessels present with "AdministativeDockingName" foreach (Vessel ve in FlightGlobals.Vessels) { if (ve.vesselName == tempID) { Vessel NameVessel = null; NameVessel = ve; NameVessel.vesselName = "1"; } } placeVessel.vesselID = Guid.NewGuid(); placeVessel.vesselName = tempID; foreach (ProtoPartSnapshot p in placeVessel.protoPartSnapshots) { uint newFlightID = (UInt32)RmmUtil.Rand.Next(1000000000, 2147483647); // save flight ID of part which should dock if (p.flightID == _mission.flightIDDockPart) { missionFlightIDDockPart = newFlightID; } // update flight ID of each part and vessel reference transform id. if (placeVessel.refTransform == p.flightID) { p.flightID = newFlightID; placeVessel.refTransform = p.flightID; } else { p.flightID = newFlightID; } // clear out all crew if (p.protoModuleCrew != null && p.protoModuleCrew.Count() != 0) { List <ProtoCrewMember> cl = p.protoModuleCrew; List <ProtoCrewMember> clc = new List <ProtoCrewMember>(cl); foreach (ProtoCrewMember c in clc) { p.RemoveCrew(c); } } foreach (ProtoPartModuleSnapshot pm in p.modules) { if (pm.moduleName == "RMMModule") { pm.moduleValues.SetValue("trackingPrimary", false); pm.moduleValues.SetValue("trackingActive", false); } } } try { placeVessel.Load(HighLogic.CurrentGame.flightState); return(true); } catch { return(true); } }
private bool loadVesselForRendezvous(ProtoVessel placeVessel, Vessel targetVessel) { targetVessel.BackupVessel(); placeVessel.orbitSnapShot = targetVessel.protoVessel.orbitSnapShot; placeVessel.orbitSnapShot.epoch = 0.0; tempID = rand.Next(1000000000).ToString(); //rename any vessels present with "AdministativeDockingName" foreach (Vessel ve in FlightGlobals.Vessels) { if (ve.vesselName == tempID) { Vessel NameVessel = null; NameVessel = ve; NameVessel.vesselName = "1"; } } placeVessel.vesselID = Guid.NewGuid(); placeVessel.vesselName = tempID; foreach (ProtoPartSnapshot p in placeVessel.protoPartSnapshots) { if (placeVessel.refTransform == p.flightID) { p.flightID = (UInt32)rand.Next(1000000000, 2147483647); placeVessel.refTransform = p.flightID; } else { p.flightID = (UInt32)rand.Next(1000000000, 2147483647); } if (p.protoModuleCrew != null && p.protoModuleCrew.Count() != 0) { List<ProtoCrewMember> cl = p.protoModuleCrew; List<ProtoCrewMember> clc = new List<ProtoCrewMember>(cl); foreach (ProtoCrewMember c in clc) { p.RemoveCrew(c); //print("remove"); } } } try { placeVessel.Load(HighLogic.CurrentGame.flightState); return true; } catch { //abortArrival(); //return false; return true; } }
private void OnVesselWasModified(Vessel vessel) { if (!vesselToPart.ContainsKey(vessel)) { //Killed as a fragment. return; } List<uint> addList = new List<uint>(); List<uint> removeList = new List<uint>(vesselToPart[vessel]); ProtoVessel pv = vessel.BackupVessel(); foreach (ProtoPartSnapshot pps in pv.protoPartSnapshots) { if (removeList.Contains(pps.flightID)) { removeList.Remove(pps.flightID); } else { addList.Add(pps.flightID); } } foreach (uint partID in addList) { if (!partToVessel.ContainsKey(partID)) { partToVessel.Add(partID, new List<Vessel>()); } partToVessel[partID].Add(vessel); vesselToPart[vessel].Add(partID); } foreach (uint partID in removeList) { vesselToPart[vessel].Remove(partID); partToVessel[partID].Remove(vessel); if (partToVessel[partID].Count == 0) { partToVessel.Remove(partID); } } }
public StoredVessel(Vessel vsl, bool compute_hull=false) { proto_vessel = vsl.BackupVessel(); metric = new Metric(vsl, compute_hull); id = proto_vessel.vesselID; name = proto_vessel.vesselName; crew = vsl.GetVesselCrew(); resources = new VesselResources<ProtoVessel, ProtoPartSnapshot, ProtoPartResourceSnapshot>(proto_vessel); }
public static void UnhangarCraft(Vessel vVesselStored, StaticObject soHangar) { RemoveCorrectCraft(vVesselStored, soHangar); // Convert the stored protovessel to a new protovessel. // Use BackupVessel because that seems to work and protovessel does not. `\o/` ProtoVessel pVessel = vVesselStored.BackupVessel(); // Get rid of the original hidden vessel - even though it was unloaded KSP still 'sees' the original craft. // I do not care why. :| vVesselStored.state = Vessel.State.DEAD; foreach (Part p in vVesselStored.Parts) { if (p != null && p.gameObject != null) p.gameObject.DestroyGameObject(); } // Load the new protovessel we made. KSP won't reload (or rather render) a vessel that was unloaded - it will only load a protovessel. :$ pVessel.Load(FlightDriver.FlightStateCache.flightState); // I suspect this is actually a KSP bug since the same crap happens with newly spawned static objects. If you query the active state // of the invisible craft, it claims it is active. And no, forcing the renderers doesn't work either. // Convert protovessel to vessel Vessel vNewVessel = pVessel.vesselRef; // Unload then reload the vessel - this seems to be the way to properly re-initialise flightstate etc. // Don't do this and you get a craft with a stuck surface velocity reading. It looks like KSP transposes orbital // and surface velocity or some other stupid s**t. I don't care. // And yes, this time KSP does load an unloaded vessel with no need for protovessel b******t. I don't care why. vNewVessel.Unload(); vNewVessel.Load(); }
public void SendVesselUpdateIfNeeded(Vessel checkVessel) { //Check vessel parts if (ModWorker.fetch.modControl != ModControlMode.DISABLED) { if (!vesselPartsOk.ContainsKey(checkVessel.id)) { CheckVesselParts(checkVessel); } if (!vesselPartsOk[checkVessel.id]) { //Vessel with bad parts return; } } if (checkVessel.state == Vessel.State.DEAD) { //Don't send dead vessels return; } if (checkVessel.vesselType == VesselType.Flag && checkVessel.id == Guid.Empty && checkVessel.vesselName != "Flag") { DarkLog.Debug("Fixing flag GUID for " + checkVessel.vesselName); checkVessel.id = Guid.NewGuid(); } //Only send updates for craft we have update locks for. Request the lock if it's not taken. if (!LockSystem.fetch.LockExists("update-" + checkVessel.id.ToString())) { LockSystem.fetch.ThrottledAcquireLock("update-" + checkVessel.id.ToString()); } // Check if it isn't null before fetching it if (FlightGlobals.fetch.activeVessel != null) { //Take the update lock off another player if we have the control lock and it's our vessel if (checkVessel.id == FlightGlobals.fetch.activeVessel.id) { if (LockSystem.fetch.LockExists("update-" + checkVessel.id.ToString()) && !LockSystem.fetch.LockIsOurs("update-" + checkVessel.id.ToString()) && LockSystem.fetch.LockIsOurs("control-" + checkVessel.id.ToString())) { LockSystem.fetch.ThrottledAcquireLock("update-" + checkVessel.id.ToString()); //Wait until we have the update lock return; } } } //Send updates for unpacked vessels that aren't being flown by other players bool notRecentlySentProtoUpdate = serverVesselsProtoUpdate.ContainsKey(checkVessel.id) ? ((UnityEngine.Time.realtimeSinceStartup - serverVesselsProtoUpdate[checkVessel.id]) > VESSEL_PROTOVESSEL_UPDATE_INTERVAL) : true; bool notRecentlySentPositionUpdate = serverVesselsPositionUpdate.ContainsKey(checkVessel.id) ? ((UnityEngine.Time.realtimeSinceStartup - serverVesselsPositionUpdate[checkVessel.id]) > (1f / (float)DynamicTickWorker.fetch.sendTickRate)) : true; //Check that is hasn't been recently sent if (notRecentlySentProtoUpdate) { ProtoVessel checkProto = checkVessel.BackupVessel(); //TODO: Fix sending of flying vessels. if (checkProto != null) { if (checkProto.vesselID != Guid.Empty) { //Also check for kerbal state changes foreach (ProtoPartSnapshot part in checkProto.protoPartSnapshots) { foreach (ProtoCrewMember pcm in part.protoModuleCrew.ToArray()) { SendKerbalIfDifferent(pcm); } } RegisterServerVessel(checkProto.vesselID); //Mark the update as sent serverVesselsProtoUpdate[checkVessel.id] = UnityEngine.Time.realtimeSinceStartup; //Also delay the position send serverVesselsPositionUpdate[checkVessel.id] = UnityEngine.Time.realtimeSinceStartup; latestUpdateSent[checkVessel.id] = UnityEngine.Time.realtimeSinceStartup; bool isFlyingUpdate = (checkProto.situation == Vessel.Situations.FLYING); NetworkWorker.fetch.SendVesselProtoMessage(checkProto, false, isFlyingUpdate); } else { DarkLog.Debug(checkVessel.vesselName + " does not have a guid!"); } } } else if (notRecentlySentPositionUpdate && checkVessel.vesselType != VesselType.Flag) { //Send a position update - Except for flags. They aren't exactly known for their mobility. serverVesselsPositionUpdate[checkVessel.id] = UnityEngine.Time.realtimeSinceStartup; latestUpdateSent[checkVessel.id] = UnityEngine.Time.realtimeSinceStartup; VesselUpdate update = VesselUpdate.CopyFromVessel(checkVessel); if (update != null) { NetworkWorker.fetch.SendVesselUpdate(update); } } }