public void HandleMessage(IServerMessageBase msg)
        {
            if (!(msg.Data is VesselFairingMsgData msgData) || !System.FairingSystemReady)
            {
                return;
            }

            //Vessel might exist in the store but not in game (if the vessel is in safety bubble for example)
            VesselsProtoStore.UpdateVesselProtoPartFairing(msgData);

            var vessel = FlightGlobals.FindVessel(msgData.VesselId);

            if (vessel == null)
            {
                return;
            }

            var part = VesselCommon.FindProtoPartInProtovessel(vessel.protoVessel, msgData.PartFlightId);

            if (part != null)
            {
                var module = VesselCommon.FindProtoPartModuleInProtoPart(part, "ModuleProceduralFairing");
                module?.moduleValues.SetValue("fsm", "st_flight_deployed");
                module?.moduleValues.RemoveNodesStartWith("XSECTION");

                (module?.moduleRef as ModuleProceduralFairing)?.DeployFairing();
            }
        }
Ejemplo n.º 2
0
        private void UpdateVesselFields(Vessel vessel)
        {
            if (vessel.protoVessel == null)
            {
                return;
            }

            for (var i = 0; i < ResourcesCount; i++)
            {
                var partSnapshot     = VesselCommon.FindProtoPartInProtovessel(vessel.protoVessel, Resources[i].PartFlightId);
                var resourceSnapshot = VesselCommon.FindResourceInProtoPart(partSnapshot, Resources[i].ResourceName);
                if (resourceSnapshot != null)
                {
                    resourceSnapshot.amount    = Resources[i].Amount;
                    resourceSnapshot.flowState = Resources[i].FlowState;

                    //Using "resourceSnapshot.resourceRef" sometimes returns null so we also try to get the resource from the part...
                    if (resourceSnapshot.resourceRef == null)
                    {
                        if (partSnapshot.partRef != null)
                        {
                            var foundResource = partSnapshot.partRef.FindResource(resourceSnapshot.resourceName);
                            foundResource.amount    = Resources[i].Amount;
                            foundResource.flowState = Resources[i].FlowState;
                        }
                    }
                    else
                    {
                        resourceSnapshot.resourceRef.amount    = Resources[i].Amount;
                        resourceSnapshot.resourceRef.flowState = Resources[i].FlowState;
                    }
                }
            }
        }
Ejemplo n.º 3
0
        public static void UpdateVesselProtoResources(VesselResourceMsgData msgData)
        {
            if (AllPlayerVessels.TryGetValue(msgData.VesselId, out var vesselProtoUpd))
            {
                if (vesselProtoUpd.ProtoVessel == null)
                {
                    return;
                }

                for (var i = 0; i < msgData.ResourcesCount; i++)
                {
                    var resource = msgData.Resources[i];

                    if (resource == null)
                    {
                        continue;
                    }

                    var partSnapshot     = VesselCommon.FindProtoPartInProtovessel(vesselProtoUpd.ProtoVessel, resource.PartFlightId);
                    var resourceSnapshot = VesselCommon.FindResourceInProtoPart(partSnapshot, resource.ResourceName);
                    if (resourceSnapshot != null)
                    {
                        resourceSnapshot.amount    = resource.Amount;
                        resourceSnapshot.flowState = resource.FlowState;
                    }
                }
            }
        }
        public void ProcessPartMethodCallSync()
        {
            var vessel = FlightGlobals.fetch.LmpFindVessel(VesselId);

            if (vessel == null || !vessel.loaded)
            {
                return;
            }

            if (!VesselCommon.DoVesselChecks(VesselId))
            {
                return;
            }

            var part = VesselCommon.FindProtoPartInProtovessel(vessel.protoVessel, PartFlightId);

            if (part != null)
            {
                var module = VesselCommon.FindProtoPartModuleInProtoPart(part, ModuleName);
                if (module != null)
                {
                    if (module.moduleRef != null)
                    {
                        module.moduleRef.GetType().GetMethod(MethodName, AccessTools.all)?.Invoke(module.moduleRef, null);
                        PartModuleEvent.onPartModuleMethodProcessed.Fire(module, MethodName);
                    }
                }
            }
        }
Ejemplo n.º 5
0
        private static void UpdateProtoVesselResources(ProtoVessel protoVessel, VesselResourceMsgData msgData)
        {
            if (protoVessel == null)
            {
                return;
            }

            for (var i = 0; i < msgData.ResourcesCount; i++)
            {
                var resource = msgData.Resources[i];

                var partSnapshot     = VesselCommon.FindProtoPartInProtovessel(protoVessel, resource.PartFlightId);
                var resourceSnapshot = VesselCommon.FindResourceInProtoPart(partSnapshot, resource.ResourceName);
                if (resourceSnapshot != null)
                {
                    resourceSnapshot.amount    = resource.Amount;
                    resourceSnapshot.flowState = resource.FlowState;

                    if (resourceSnapshot.resourceRef == null)
                    {
                        continue;
                    }

                    resourceSnapshot.resourceRef.amount    = resource.Amount;
                    resourceSnapshot.resourceRef.flowState = resource.FlowState;
                }
            }
        }
        public void ProcessPartMethodSync()
        {
            var vessel = FlightGlobals.fetch.LmpFindVessel(VesselId);

            if (vessel == null)
            {
                return;
            }

            if (!VesselCommon.DoVesselChecks(VesselId))
            {
                return;
            }

            var part = VesselCommon.FindProtoPartInProtovessel(vessel.protoVessel, PartFlightId);

            if (part != null)
            {
                var module = VesselCommon.FindProtoPartModuleInProtoPart(part, ModuleName);
                if (module != null)
                {
                    switch (FieldType)
                    {
                    case PartSyncFieldType.Boolean:
                        module.moduleValues.SetValue(FieldName, BoolValue);
                        if (module.moduleRef != null)
                        {
                            module.moduleRef.Fields[FieldName].SetValue(BoolValue, module.moduleRef);
                        }
                        PartModuleEvent.onPartModuleBoolFieldProcessed.Fire(module, FieldName, BoolValue);
                        break;

                    case PartSyncFieldType.Integer:
                        module.moduleValues.SetValue(FieldName, IntValue);
                        if (module.moduleRef != null)
                        {
                            module.moduleRef.Fields[FieldName].SetValue(IntValue, module.moduleRef);
                        }
                        PartModuleEvent.onPartModuleIntFieldProcessed.Fire(module, FieldName, IntValue);
                        break;

                    case PartSyncFieldType.Float:
                        module.moduleValues.SetValue(FieldName, FloatValue);
                        if (module.moduleRef != null)
                        {
                            module.moduleRef.Fields[FieldName].SetValue(FloatValue, module.moduleRef);
                        }
                        PartModuleEvent.onPartModuleFloatFieldProcessed.Fire(module, FieldName, FloatValue);
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                }
            }
        }
Ejemplo n.º 7
0
        private static ProtoPartModuleSnapshot GetKerbalEvaProtoModule(ProtoVessel protoVessel)
        {
            if (protoVessel == null)
            {
                return(null);
            }

            var partSnapshot = VesselCommon.FindProtoPartInProtovessel(protoVessel, "kerbalEVA");

            if (partSnapshot == null)
            {
                return(null);
            }

            return(VesselCommon.FindProtoPartModuleInProtoPart(partSnapshot, "KerbalEVA"));
        }
Ejemplo n.º 8
0
        private static void UpdateProtoVesselResources(ProtoVessel protoVessel, VesselResourceMsgData msgData)
        {
            if (protoVessel != null)
            {
                for (var i = 0; i < msgData.ResourcesCount; i++)
                {
                    var resource = msgData.Resources[i];

                    var partSnapshot     = VesselCommon.FindProtoPartInProtovessel(protoVessel, resource.PartFlightId);
                    var resourceSnapshot = VesselCommon.FindResourceInProtoPart(partSnapshot, resource.ResourceName);
                    if (resourceSnapshot != null)
                    {
                        resourceSnapshot.amount = resource.Amount;
                    }
                }
            }
        }
Ejemplo n.º 9
0
        public static void UpdateVesselProtoPartModules(VesselPartSyncMsgData msgData)
        {
            if (AllPlayerVessels.TryGetValue(msgData.VesselId, out var vesselProtoUpd))
            {
                if (vesselProtoUpd.ProtoVessel == null)
                {
                    return;
                }

                var partSnapshot = VesselCommon.FindProtoPartInProtovessel(vesselProtoUpd.ProtoVessel, msgData.PartFlightId);
                if (partSnapshot != null)
                {
                    var module = VesselCommon.FindProtoPartModuleInProtoPart(partSnapshot, msgData.ModuleName);
                    module?.moduleValues.SetValue(msgData.FieldName, msgData.Value);
                }
            }
        }
Ejemplo n.º 10
0
        public static void UpdateVesselProtoPartFairing(VesselFairingMsgData msgData)
        {
            if (AllPlayerVessels.TryGetValue(msgData.VesselId, out var vesselProtoUpd))
            {
                if (vesselProtoUpd.ProtoVessel == null)
                {
                    return;
                }

                var part = VesselCommon.FindProtoPartInProtovessel(vesselProtoUpd.ProtoVessel, msgData.PartFlightId);
                if (part != null)
                {
                    var module = VesselCommon.FindProtoPartModuleInProtoPart(part, "ModuleProceduralFairing");
                    module?.moduleValues.SetValue("fsm", "st_flight_deployed");
                    module?.moduleValues.RemoveNodesStartWith("XSECTION");
                }
            }
        }
        public string GetFairingStateFromStore(Guid vesselId, uint partFlightId)
        {
            if (VesselsProtoStore.AllPlayerVessels.TryGetValue(vesselId, out var vesselProtoUpd))
            {
                var protoVessel = vesselProtoUpd.ProtoVessel;

                var protoPart = VesselCommon.FindProtoPartInProtovessel(protoVessel, partFlightId);
                if (protoPart == null)
                {
                    return(null);
                }

                var protoModule = VesselCommon.FindProtoPartModuleInProtoPart(protoPart, "ModuleProceduralFairing");

                return(protoModule?.moduleValues.GetValue("fsm"));
            }

            return(null);
        }
Ejemplo n.º 12
0
        private static void UpdateVesselValues(ProtoVessel protoVessel, VesselPartSyncMsgData msgData)
        {
            if (protoVessel == null)
            {
                return;
            }

            var part = VesselCommon.FindProtoPartInProtovessel(protoVessel, msgData.PartFlightId);

            if (part != null)
            {
                var module = VesselCommon.FindProtoPartModuleInProtoPart(part, msgData.ModuleName);
                if (module != null)
                {
                    module.moduleValues.SetValue(msgData.FieldName, msgData.Value);
                    UpdateVesselModuleIfNeeded(protoVessel.vesselID, part.flightID, msgData, module, part);
                }
            }
        }
        public void HandleMessage(IServerMessageBase msg)
        {
            if (!(msg.Data is VesselFairingMsgData msgData) || !System.FairingSystemReady)
            {
                return;
            }

            //We received a msg for our own controlled/updated vessel so ignore it
            if (!VesselCommon.DoVesselChecks(msgData.VesselId))
            {
                return;
            }

            //Vessel might exist in the store but not in game (if the vessel is in safety bubble for example)
            VesselsProtoStore.UpdateVesselProtoPartFairing(msgData);

            var vessel = FlightGlobals.FindVessel(msgData.VesselId);

            if (vessel == null)
            {
                return;
            }

            var part = VesselCommon.FindProtoPartInProtovessel(vessel.protoVessel, msgData.PartFlightId);

            if (part != null)
            {
                var module = VesselCommon.FindProtoPartModuleInProtoPart(part, "ModuleProceduralFairing");
                module?.moduleValues.SetValue("fsm", "st_flight_deployed");
                module?.moduleValues.RemoveNodesStartWith("XSECTION");

                try
                {
                    (module?.moduleRef as ModuleProceduralFairing)?.DeployFairing();
                }
                catch (Exception)
                {
                    //TODO reload the module
                }
            }
        }
Ejemplo n.º 14
0
        public void ProcessFairing()
        {
            if (!VesselCommon.DoVesselChecks(VesselId))
            {
                return;
            }

            //Finding using persistentId failed, try searching it with the flightId...
            var vessel = FlightGlobals.fetch.LmpFindVessel(VesselId);

            if (vessel == null)
            {
                return;
            }

            var protoPart = VesselCommon.FindProtoPartInProtovessel(vessel.protoVessel, PartFlightId);

            if (protoPart != null)
            {
                ProcessFairingChange(protoPart);
            }
        }
        public void UpdateFairingsValuesInProtoVessel(ProtoVessel protoVessel, uint partFlightId)
        {
            if (protoVessel == null)
            {
                return;
            }

            var protoPart = VesselCommon.FindProtoPartInProtovessel(protoVessel, partFlightId);

            if (protoPart == null)
            {
                return;
            }

            var protoModule = VesselCommon.FindProtoPartModuleInProtoPart(protoPart, "ModuleProceduralFairing");

            if (protoModule == null)
            {
                return;
            }

            protoModule.moduleValues.SetValue("fsm", "st_flight_deployed");
            protoModule.moduleValues.RemoveNodesStartWith("XSECTION");
        }
Ejemplo n.º 16
0
        public void ProcessPartMethodSync()
        {
            var vessel = FlightGlobals.fetch.LmpFindVessel(VesselId);

            if (vessel == null)
            {
                return;
            }

            if (!VesselCommon.DoVesselChecks(VesselId))
            {
                return;
            }

            var part = VesselCommon.FindProtoPartInProtovessel(vessel.protoVessel, PartFlightId);

            if (part != null)
            {
                var module = VesselCommon.FindProtoPartModuleInProtoPart(part, ModuleName);
                if (module != null)
                {
                    switch (FieldType)
                    {
                    case PartSyncFieldType.Boolean:
                        module.moduleValues.SetValue(FieldName, BoolValue);
                        PartModuleEvent.onPartModuleBoolFieldProcessed.Fire(module, FieldName, BoolValue);
                        break;

                    case PartSyncFieldType.Integer:
                        module.moduleValues.SetValue(FieldName, IntValue);
                        PartModuleEvent.onPartModuleIntFieldProcessed.Fire(module, FieldName, IntValue);
                        break;

                    case PartSyncFieldType.Float:
                        module.moduleValues.SetValue(FieldName, FloatValue);
                        PartModuleEvent.onPartModuleFloatFieldProcessed.Fire(module, FieldName, FloatValue);
                        break;

                    case PartSyncFieldType.Double:
                        module.moduleValues.SetValue(FieldName, DoubleValue);
                        PartModuleEvent.onPartModuleDoubleFieldProcessed.Fire(module, FieldName, DoubleValue);
                        break;

                    case PartSyncFieldType.Vector3:
                        module.moduleValues.SetValue(FieldName, VectorValue);
                        PartModuleEvent.onPartModuleVectorFieldProcessed.Fire(module, FieldName, VectorValue);
                        break;

                    case PartSyncFieldType.Quaternion:
                        module.moduleValues.SetValue(FieldName, QuaternionValue);
                        PartModuleEvent.onPartModuleQuaternionFieldProcessed.Fire(module, FieldName, QuaternionValue);
                        break;

                    case PartSyncFieldType.String:
                        module.moduleValues.SetValue(FieldName, StrValue);
                        PartModuleEvent.onPartModuleStringFieldProcessed.Fire(module, FieldName, StrValue);
                        break;

                    case PartSyncFieldType.Enum:
                        module.moduleValues.SetValue(FieldName, StrValue);
                        PartModuleEvent.onPartModuleEnumFieldProcessed.Fire(module, FieldName, IntValue, StrValue);
                        break;

                    case PartSyncFieldType.Object:
                        module.moduleValues.SetValue(FieldName, StrValue);
                        PartModuleEvent.onPartModuleObjectFieldProcessed.Fire(module, FieldName, StrValue);
                        //We do not set the value of objects in the module as we cannot be sure if they can be transformed from a string back to the object
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                }
            }
        }
Ejemplo n.º 17
0
        /// <summary>
        /// This method will take a vessel and update all it's parts and proto based on a protovessel we received
        /// Protovessel --------------> Vessel & ProtoVessel
        /// This way we avoid having to unload and reload a vessel with it's terrible performance
        /// </summary>
        public static void UpdateVesselPartsFromProtoVessel(Vessel vessel, ProtoVessel protoVessel, IEnumerable <uint> vesselPartsId = null)
        {
            if (vessel == null || protoVessel == null || vessel.state == Vessel.State.DEAD)
            {
                return;
            }

            if (vessel.id != protoVessel.vesselID)
            {
                LunaLog.LogError($"Tried to update a vessel id {vessel.id} with a protovessel of vessel id {protoVessel.vesselID}");
                return;
            }

            var vesselProtoPartIds = vesselPartsId ?? protoVessel.protoPartSnapshots.Select(p => p.flightID);

            //If vessel is UNLOADED it won't have parts so we must take them from the proto...
            var vesselPartsIds = vessel.loaded ? vessel.parts.Select(p => p.flightID) : vessel.protoVessel.protoPartSnapshots.Select(p => p.flightID);

            var hasMissingparts = vesselProtoPartIds.Except(vesselPartsIds).Any();

            if (hasMissingparts || !VesselCommon.IsSpectating && (vessel.isEVA && vessel.situation != protoVessel.situation ||
                                                                  !vessel.Landed && protoVessel.landed || !vessel.Splashed && protoVessel.splashed ||
                                                                  vessel.situation != protoVessel.situation && HighLogic.LoadedScene == GameScenes.TRACKSTATION))
            {
                //Reload the whole vessel if vessel lands/splashes as otherwise map view puts the vessel next to the other player.
                //Also reload the whole vesse if it's a EVA and situation changed or in track station....
                //Better to reload if has missing parts as creating them dinamically is a PIA
                VesselLoader.ReloadVessel(protoVessel);
                return;
            }

            var hasCrewChanges = false;

            //Never do vessel.protoVessel = protoVessel; not even if the vessel is not loaded as when it gets loaded the parts are created in the active vessel
            //and not on the target vessel

            //Run trough all the vessel parts and protoparts.
            //Vessel.parts will be empty if vessel is unloaded.
            var protoPartsToRemove = new List <ProtoPartSnapshot>();

            for (var i = 0; i < vessel.protoVessel.protoPartSnapshots.Count; i++)
            {
                var protoPartToUpdate = vessel.protoVessel.protoPartSnapshots[i];
                var partSnapshot      = VesselCommon.FindProtoPartInProtovessel(protoVessel, protoPartToUpdate.flightID);
                if (partSnapshot == null) //Part does not exist in the protovessel definition so kill it
                {
                    protoPartsToRemove.Add(protoPartToUpdate);
                    continue;
                }

                AdjustCrewMembersInProtoPart(protoPartToUpdate, partSnapshot);
                protoPartToUpdate.state = partSnapshot.state;
                UpdatePartModulesInProtoPart(protoPartToUpdate, partSnapshot);
                UpdateProtoVesselResources(protoPartToUpdate, partSnapshot);

                var part = protoPartToUpdate.partRef;
                if (part != null) //Part can be null if the vessel is unloaded!!
                {
                    //Remove or add crew members in given part and detect if there have been any change
                    hasCrewChanges |= AdjustCrewMembersInPart(part, partSnapshot);

                    //Set part "state" field... Important for fairings for example...
                    StateField?.SetValue(part, partSnapshot.state);
                    part.ResumeState = part.State;

                    UpdatePartModules(partSnapshot, part);
                    UpdateVesselResources(partSnapshot, part);
                    UpdatePartFairings(partSnapshot, part);
                }
            }

            //Now kill both parts and protoparts that don't exist
            for (var i = 0; i < protoPartsToRemove.Count; i++)
            {
                //Part can be null if the vessel is unloaded.  In this case, no need to kill it as it's already gone from the game.
                if (protoPartsToRemove[i].partRef != null)
                {
                    if (protoPartsToRemove[i].partRef.FindModuleImplementing <ModuleDecouple>() != null)
                    {
                        protoPartsToRemove[i].partRef.decouple();
                    }
                    else
                    {
                        protoPartsToRemove[i].partRef.Die();
                    }
                }

                vessel.protoVessel.protoPartSnapshots.Remove(protoPartsToRemove[i]);
            }

            if (hasCrewChanges)
            {
                //We must always refresh the crew in every part of the vessel, even if we don't spectate
                vessel.RebuildCrewList();

                //IF we are spectating we must fix the portraits of the kerbals
                if (FlightGlobals.ActiveVessel?.id == vessel.id)
                {
                    //If you don't call spawn crew and you do a crew transfer the transfered crew won't appear in the portraits...
                    Client.Singleton.StartCoroutine(CallbackUtil.DelayedCallback(0.25f, () => { FlightGlobals.ActiveVessel?.SpawnCrew(); }));
                    //If you don't call this the kerbal portraits appear in black...
                    Client.Singleton.StartCoroutine(CallbackUtil.DelayedCallback(0.5f, () => { KerbalPortraitGallery.Instance?.SetActivePortraitsForVessel(FlightGlobals.ActiveVessel); }));
                }
            }
        }