コード例 #1
0
        public static HashSet<ProtoPartResourceSnapshot> AddResource(VesselData data, float amount, string name, HashSet<ProtoPartResourceSnapshot> modified)
        {
            BackgroundProcessing.Debug("AddResource called, adding " + amount + " " + name, DebugLevel.ALL);

            if (!data.storage.ContainsKey(name)) { return modified; }

            bool reduce = amount < 0;

            List<ProtoPartResourceSnapshot> relevantStorage = data.storage[name];
            for (int i = 0; i < relevantStorage.Count; ++i)
            {
                ProtoPartResourceSnapshot r = relevantStorage[i];

                if (amount == 0) { break; }
                float n; float m;

                if (
                    float.TryParse(r.resourceValues.GetValue("amount"), out n) &&
                    float.TryParse(r.resourceValues.GetValue("maxAmount"), out m)
                )
                {
                    n += amount; amount = 0;

                    if (reduce) { if (n < 0 && i < relevantStorage.Count - 1) { amount = n; n = 0; } }
                    else { if (n > m && i < relevantStorage.Count - 1) { amount = n - m; n = m; } }

                    r.resourceValues.SetValue("amount", n.ToString());
                }

                modified.Add(r);
            }

            return modified;
        }
コード例 #2
0
            public VesselData(VesselData vd)
            {
                name = vd.name;
                id = vd.id;
                craftURL = vd.craftURL;
                craftPart = vd.craftPart;
                flagURL = vd.flagURL;
                vesselType = vd.vesselType;
                body = vd.body;
                orbit = vd.orbit;
                latitude = vd.latitude;
                longitude = vd.longitude;
                altitude = vd.altitude;
                height = vd.height;
                orbiting = vd.orbiting;
                owned = vd.owned;
                pqsCity = vd.pqsCity;
                pqsOffset = vd.pqsOffset;
                heading = vd.heading;
                pitch = vd.pitch;
                roll = vd.roll;

                foreach (CrewData cd in vd.crew)
                {
                    crew.Add(new CrewData(cd));
                }
            }
コード例 #3
0
    public void init()
    {
        Console.WriteLine ("UDPSend init().");

        ip = "127.0.0.1";
        port = 8051;

        endPoint = new IPEndPoint (IPAddress.Parse (ip), port);
        client = new UdpClient ();
        this.VData = new VesselData ();
        Console.WriteLine ("sending to " + ip + " : " + port);
    }
コード例 #4
0
 private VesselData GetVesselData(Vessel vessel)
 {
    Guid id = vessel.id;
    VesselData data;
    if (!vesselData.ContainsKey(id))
    {
       data = new VesselData();
       vesselData.Add(id, data);
    }
    else
    {
       data = vesselData[id];
    }
    return data;
 }
コード例 #5
0
        private void SpawnVessel(VesselData VesselData, List <ProtoCrewMember> crewData = null)
        {
            //      string gameDataDir = KSPUtil.ApplicationRootPath;

            // Set additional info for landed vessels
            bool landed = false;

            if (!landed)
            {
                landed = true;
                if (VesselData.altitude == null || VesselData.altitude < 0)
                {
                    VesselData.altitude = SpawnCoords.z;      //LocationUtil.TerrainHeight(VesselData.latitude, VesselData.longitude, VesselData.body);
                }

                //Vector3d pos = VesselData.body.GetWorldSurfacePosition(VesselData.latitude, VesselData.longitude, VesselData.altitude.Value);
                Vector3d pos = VesselData.body.GetRelSurfacePosition(VesselData.latitude, VesselData.longitude, VesselData.altitude.Value);

                VesselData.orbit = new Orbit(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, VesselData.body);
                VesselData.orbit.UpdateFromStateVectors(pos, VesselData.body.getRFrmVel(pos), VesselData.body, Planetarium.GetUniversalTime());
            }

            ConfigNode[]  partNodes;
            ShipConstruct shipConstruct = null;
            bool          hasClamp      = false;
            float         lcHeight      = 0;
            ConfigNode    craftNode;
            Quaternion    craftRotation = Quaternion.identity;

            if (!string.IsNullOrEmpty(VesselData.craftURL))
            {
                // Save the current ShipConstruction ship, otherwise the player will see the spawned ship next time they enter the VAB!
                ConfigNode currentShip = ShipConstruction.ShipConfig;

                shipConstruct = ShipConstruction.LoadShip(VesselData.craftURL);
                if (shipConstruct == null)
                {
                    return;//continue;
                }

                craftNode     = ConfigNode.Load(VesselData.craftURL);
                lcHeight      = ConfigNode.ParseVector3(craftNode.GetNode("PART").GetValue("pos")).y;
                craftRotation = ConfigNode.ParseQuaternion(craftNode.GetNode("PART").GetValue("rot"));

                // Restore ShipConstruction ship
                ShipConstruction.ShipConfig = currentShip;

                // Set the name
                if (string.IsNullOrEmpty(VesselData.name))
                {
                    VesselData.name = "";
                    ;
                }

                // Set some parameters that need to be at the part level
                uint missionID = (uint)Guid.NewGuid().GetHashCode();
                uint launchID  = HighLogic.CurrentGame.launchID++;
                foreach (Part p in shipConstruct.parts)
                {
                    p.flightID  = ShipConstruction.GetUniqueFlightID(HighLogic.CurrentGame.flightState);
                    p.missionID = missionID;
                    p.launchID  = launchID;
                    p.flagURL   = flagURL;

                    // Had some issues with this being set to -1 for some ships - can't figure out
                    // why.  End result is the vessel exploding, so let's just set it to a positive
                    // value.
                    p.temperature = 1.0;
                }

                // Create a Blank ProtoVessel, we will use this to dump the parts to a config node.
                // We can't use the config nodes from the .craft file, because they are in a
                // slightly different format than those required for a ProtoVessel (seriously
                // Squad?!?).
                ConfigNode  empty       = new ConfigNode();
                ProtoVessel BlankProto  = new ProtoVessel(empty, null);
                Vessel      BlankVessel = new Vessel();
                BlankVessel.parts    = shipConstruct.parts;
                BlankProto.vesselRef = BlankVessel;

                // Create the ProtoPartSnapshot objects and then initialize them
                foreach (Part p in shipConstruct.parts)
                {
                    BlankProto.protoPartSnapshots.Add(new ProtoPartSnapshot(p, BlankProto));
                }
                foreach (ProtoPartSnapshot p in BlankProto.protoPartSnapshots)
                {
                    p.storePartRefs();
                }

                // Create the ship's parts

                List <ConfigNode> partNodesL = new List <ConfigNode>();
                foreach (ProtoPartSnapshot snapShot in BlankProto.protoPartSnapshots)
                {
                    ConfigNode node = new ConfigNode("PART");
                    snapShot.Save(node);
                    partNodesL.Add(node);
                }
                partNodes = partNodesL.ToArray();
            }
            else
            {
                // Create crew member array
                ProtoCrewMember[] crewArray = new ProtoCrewMember[VesselData.crew.Count];

                /*
                 *      int i = 0;
                 *      foreach (CrewData cd in VesselData.crew)
                 *      {
                 * /*
                 *        // Create the ProtoCrewMember
                 *        ProtoCrewMember crewMember = HighLogic.CurrentGame.CrewRoster.GetNewKerbal(ProtoCrewMember.KerbalType.Crew);
                 *        if (cd.name != null)
                 *        {
                 *          crewMember.KerbalRef.name = cd.name;
                 *        }
                 *
                 *        crewArray[i++] = crewMember;
                 *
                 *      }
                 */
                // Create part nodes
                uint flightId = ShipConstruction.GetUniqueFlightID(HighLogic.CurrentGame.flightState);
                partNodes    = new ConfigNode[1];
                partNodes[0] = ProtoVessel.CreatePartNode(VesselData.craftPart.name, flightId, crewArray);

                // Default the size class
                //sizeClass = UntrackedObjectClass.A;

                // Set the name
                if (string.IsNullOrEmpty(VesselData.name))
                {
                    VesselData.name = VesselData.craftPart.name;
                }
            }

            // Create additional nodes
            ConfigNode[] additionalNodes = new ConfigNode[0];
            //DiscoveryLevels discoveryLevel = VesselData.owned ? DiscoveryLevels.Owned : DiscoveryLevels.Unowned;
            //additionalNodes[0] = ProtoVessel.CreateDiscoveryNode(discoveryLevel, sizeClass, contract.TimeDeadline, contract.TimeDeadline);

            // Create the config node representation of the ProtoVessel
            ConfigNode protoVesselNode = ProtoVessel.CreateVesselNode(VesselData.name, VesselData.vesselType, VesselData.orbit, 0, partNodes, additionalNodes);

            // Additional seetings for a landed vessel
            if (!VesselData.orbiting)
            {
                Vector3d norm = VesselData.body.GetRelSurfaceNVector(VesselData.latitude, VesselData.longitude);

                double terrainHeight = 0.0;
                if (VesselData.body.pqsController != null)
                {
                    terrainHeight = VesselData.body.pqsController.GetSurfaceHeight(norm) - VesselData.body.pqsController.radius;
                }
                bool splashed = false;// = landed && terrainHeight < 0.001;

                // Create the config node representation of the ProtoVessel
                // Note - flying is experimental, and so far doesn't worx
                protoVesselNode.SetValue("sit", (splashed ? Vessel.Situations.SPLASHED : landed ?
                                                 Vessel.Situations.LANDED : Vessel.Situations.FLYING).ToString());
                protoVesselNode.SetValue("landed", (landed && !splashed).ToString());
                protoVesselNode.SetValue("splashed", splashed.ToString());
                protoVesselNode.SetValue("lat", VesselData.latitude.ToString());
                protoVesselNode.SetValue("lon", VesselData.longitude.ToString());
                protoVesselNode.SetValue("alt", VesselData.altitude.ToString());
                protoVesselNode.SetValue("landedAt", VesselData.body.name);

                // Figure out the additional height to subtract
                float lowest = float.MaxValue;
                if (shipConstruct != null)
                {
                    foreach (Part p in shipConstruct.parts)
                    {
                        foreach (Collider collider in p.GetComponentsInChildren <Collider>())
                        {
                            if (collider.gameObject.layer != 21 && collider.enabled)
                            {
                                lowest = Mathf.Min(lowest, collider.bounds.min.y);
                            }
                        }
                    }
                }
                else
                {
                    foreach (Collider collider in VesselData.craftPart.partPrefab.GetComponentsInChildren <Collider>())
                    {
                        if (collider.gameObject.layer != 21 && collider.enabled)
                        {
                            lowest = Mathf.Min(lowest, collider.bounds.min.y);
                        }
                    }
                }

                if (lowest == float.MaxValue)
                {
                    lowest = 0;
                }

                // Figure out the surface height and rotation
                Quaternion normal   = Quaternion.LookRotation((Vector3)norm);// new Vector3((float)norm.x, (float)norm.y, (float)norm.z));
                Quaternion rotation = Quaternion.identity;
                float      heading  = VesselData.heading;
                rotation = rotation * Quaternion.FromToRotation(Vector3.up, Vector3.back);
                rotation = rotation * Quaternion.AngleAxis(heading, Vector3.back);
                rotation = rotation * Quaternion.AngleAxis(VesselData.roll, Vector3.down);
                rotation = rotation * Quaternion.AngleAxis(VesselData.pitch, Vector3.left);

                // Set the height and rotation
                if (landed || splashed)
                {
                    float hgt = (shipConstruct != null ? shipConstruct.parts[0] : VesselData.craftPart.partPrefab).localRoot.attPos0.y - lowest;
                    hgt += VesselData.height;
                    protoVesselNode.SetValue("hgt", hgt.ToString(), true);
                }
                protoVesselNode.SetValue("rot", KSPUtil.WriteQuaternion(normal * rotation), true);

                // Set the normal vector relative to the surface
                Vector3 nrm = (rotation * Vector3.forward);
                protoVesselNode.SetValue("nrm", nrm.x + "," + nrm.y + "," + nrm.z, true);

                protoVesselNode.SetValue("prst", false.ToString(), true);
            }

            // Add vessel to the game
            ProtoVessel protoVessel = HighLogic.CurrentGame.AddVessel(protoVesselNode);

            //protoVessel.vesselRef.transform.rotation = protoVessel.rotation;


            // Store the id for later use
            VesselData.id = protoVessel.vesselRef.id;
            protoVessel.vesselRef.isPersistent = true;
            protoVessel.vesselRef.Landed       = false;
            protoVessel.vesselRef.situation    = Vessel.Situations.FLYING;
            protoVessel.vesselRef.GoOffRails();
            StageManager.BeginFlight();

            //StartCoroutine(PlaceSpawnedVessel(protoVessel.vesselRef, !hasClamp));

            //destroy prefabs
            foreach (Part p in FindObjectsOfType <Part>())
            {
                if (!p.vessel)
                {
                    Destroy(p.gameObject);
                }
            }
        }
コード例 #6
0
ファイル: Utility.cs プロジェクト: Kramax/KramaxAutoPilot
 /// <summary>
 /// Plane normal vector from a given heading (surface right vector)
 /// </summary>
 public static Vector3 vecHeading(double target, VesselData vdata)
 {
     double angleDiff = target - vdata.heading;
     return Quaternion.AngleAxis((float)(angleDiff + 90), (Vector3)vdata.planetUp) * vdata.surfVesForward;
 }
コード例 #7
0
ファイル: Utility.cs プロジェクト: Kramax/KramaxAutoPilot
 /// <summary>
 /// calculate current heading from plane rotation
 /// </summary>
 public static double calculateTargetHeading(Quaternion rotation, Vessel vessel, VesselData vdata)
 {
     Vector3 fwd = Vector3.Cross(getPlaneNormal(rotation, vessel), vdata.planetUp);
     double heading = Vector3.Angle(fwd, vdata.planetNorth) * Math.Sign(Vector3.Dot(fwd, vdata.planetEast));
     return heading.headingClamp(360);
 }
コード例 #8
0
        void SpawnVessel(string craftURL, CelestialBody orbitmainBodyName, double altitude, string stationName)
        {
            foreach (Vessel vessel in FlightGlobals.Vessels)
            {
                if (vessel.vesselName == stationName)
                {
                    vessel.Die();
                    break;
                }
            }
            VesselData vesselData = new VesselData();

            vesselData.craftURL = craftURL;
            vesselData.orbiting = true;
            vesselData.flagURL  = HighLogic.CurrentGame.flagURL;
            vesselData.owned    = true;
            string gameDataDir = KSPUtil.ApplicationRootPath;

            ConfigNode[]  partNodes;
            ShipConstruct shipConstruct = null;
            float         lcHeight      = 0;
            ConfigNode    craftNode;
            ConfigNode    currentShip = ShipConstruction.ShipConfig;

            shipConstruct = ShipConstruction.LoadShip(vesselData.craftURL);
            craftNode     = ConfigNode.Load(vesselData.craftURL);
            lcHeight      = ConfigNode.ParseVector3(craftNode.GetNode("PART").GetValue("pos")).y;
            ShipConstruction.ShipConfig = currentShip;
            ConfigNode  empty       = new ConfigNode();
            ProtoVessel dummyProto  = new ProtoVessel(empty, null);
            Vessel      dummyVessel = new Vessel();

            dummyVessel.parts    = shipConstruct.parts;
            dummyProto.vesselRef = dummyVessel;
            uint missionID = (uint)Guid.NewGuid().GetHashCode();
            uint launchID  = HighLogic.CurrentGame.launchID++;

            foreach (Part p in shipConstruct.parts)
            {
                p.missionID   = missionID;
                p.launchID    = launchID;
                p.flightID    = ShipConstruction.GetUniqueFlightID(HighLogic.CurrentGame.flightState);
                p.temperature = 1.0;
                dummyProto.protoPartSnapshots.Add(new ProtoPartSnapshot(p, dummyProto));
            }
            foreach (ProtoPartSnapshot p in dummyProto.protoPartSnapshots)
            {
                p.storePartRefs();
            }
            List <ConfigNode> partNodesL = new List <ConfigNode>();

            foreach (var snapShot in dummyProto.protoPartSnapshots)
            {
                ConfigNode node = new ConfigNode("PART");
                snapShot.Save(node);
                partNodesL.Add(node);
            }
            partNodes = partNodesL.ToArray();
            ConfigNode[] additionalNodes = new ConfigNode[0];
            ConfigNode   protoVesselNode = ProtoVessel.CreateVesselNode(stationName, VesselType.Station, new Orbit(0, 0, altitude + orbitmainBodyName.Radius, 0, 0, 0, 0, orbitmainBodyName), 0, partNodes, additionalNodes);
            ProtoVessel  protoVessel     = HighLogic.CurrentGame.AddVessel(protoVesselNode);

            vesselData.id = protoVessel.vesselRef.id;
            foreach (var p in FindObjectsOfType <Part>())
            {
                if (!p.vessel)
                {
                    Destroy(p.gameObject);
                }
            }
        }
コード例 #9
0
        public static SpawnVessel Create(ConfigNode configNode, SpawnVesselFactory factory)
        {
            SpawnVessel spawnVessel = new SpawnVessel();

            ConfigNodeUtil.ParseValue <bool>(configNode, "deferVesselCreation", x => spawnVessel.deferVesselCreation = x, factory, false);

            bool valid = true;
            int  index = 0;

            foreach (ConfigNode child in ConfigNodeUtil.GetChildNodes(configNode, "VESSEL"))
            {
                DataNode dataNode = new DataNode("VESSEL_" + index++, factory.dataNode, factory);
                try
                {
                    ConfigNodeUtil.SetCurrentDataNode(dataNode);

                    VesselData vessel = new VesselData();

                    // Get name
                    if (child.HasValue("name"))
                    {
                        valid &= ConfigNodeUtil.ParseValue <string>(child, "name", x => vessel.name = x, factory);
                    }

                    // Get craft details
                    if (child.HasValue("craftURL"))
                    {
                        valid &= ConfigNodeUtil.ParseValue <string>(child, "craftURL", x => vessel.craftURL = x, factory);
                    }
                    if (child.HasValue("craftPart"))
                    {
                        valid &= ConfigNodeUtil.ParseValue <AvailablePart>(child, "craftPart", x => vessel.craftPart = x, factory);
                    }
                    valid &= ConfigNodeUtil.AtLeastOne(child, new string[] { "craftURL", "craftPart" }, factory);

                    valid &= ConfigNodeUtil.ParseValue <string>(child, "flagURL", x => vessel.flagURL = x, factory, (string)null);
                    valid &= ConfigNodeUtil.ParseValue <VesselType>(child, "vesselType", x => vessel.vesselType = x, factory, VesselType.Ship);

                    // Use an expression to default - then it'll work for dynamic contracts
                    if (!child.HasValue("targetBody"))
                    {
                        child.AddValue("targetBody", "@/targetBody");
                    }
                    valid &= ConfigNodeUtil.ParseValue <CelestialBody>(child, "targetBody", x => vessel.body = x, factory);

                    // Get landed stuff
                    if (child.HasValue("pqsCity"))
                    {
                        string pqsCityStr = null;
                        valid &= ConfigNodeUtil.ParseValue <string>(child, "pqsCity", x => pqsCityStr = x, factory);
                        if (pqsCityStr != null)
                        {
                            try
                            {
                                vessel.pqsCity = vessel.body.GetComponentsInChildren <PQSCity>(true).Where(pqs => pqs.name == pqsCityStr).First();
                            }
                            catch (Exception e)
                            {
                                LoggingUtil.LogError(typeof(WaypointGenerator), "Couldn't load PQSCity with name '" + pqsCityStr + "'");
                                LoggingUtil.LogException(e);
                                valid = false;
                            }
                        }
                        valid &= ConfigNodeUtil.ParseValue <Vector3d>(child, "pqsOffset", x => vessel.pqsOffset = x, factory, new Vector3d());

                        // Don't expect these to load anything, but do it to mark as initialized
                        valid &= ConfigNodeUtil.ParseValue <double>(child, "lat", x => vessel.latitude = x, factory, 0.0);
                        valid &= ConfigNodeUtil.ParseValue <double>(child, "lon", x => vessel.longitude = x, factory, 0.0);

                        // Do load alt and height
                        valid &= ConfigNodeUtil.ParseValue <double?>(child, "alt", x => vessel.altitude = x, factory, (double?)null);
                        valid &= ConfigNodeUtil.ParseValue <float>(child, "height", x => vessel.height = x, factory,
                                                                   !string.IsNullOrEmpty(vessel.craftURL) ? 0.0f : 2.5f);
                        vessel.orbiting = false;
                    }
                    else if (child.HasValue("lat") && child.HasValue("lon"))
                    {
                        valid &= ConfigNodeUtil.ParseValue <double>(child, "lat", x => vessel.latitude = x, factory);
                        valid &= ConfigNodeUtil.ParseValue <double>(child, "lon", x => vessel.longitude = x, factory);
                        valid &= ConfigNodeUtil.ParseValue <double?>(child, "alt", x => vessel.altitude = x, factory, (double?)null);
                        valid &= ConfigNodeUtil.ParseValue <float>(child, "height", x => vessel.height = x, factory,
                                                                   !string.IsNullOrEmpty(vessel.craftURL) ? 0.0f : 2.5f);
                        vessel.orbiting = false;
                    }
                    // Get orbit
                    else
                    {
                        valid          &= ConfigNodeUtil.ParseValue <Orbit>(child, "ORBIT", x => vessel.orbit = x, factory);
                        vessel.orbiting = true;
                    }

                    valid &= ConfigNodeUtil.ParseValue <float>(child, "heading", x => vessel.heading = x, factory, 0.0f);
                    valid &= ConfigNodeUtil.ParseValue <float>(child, "pitch", x => vessel.pitch = x, factory, 0.0f);
                    valid &= ConfigNodeUtil.ParseValue <float>(child, "roll", x => vessel.roll = x, factory, 0.0f);

                    // Get additional flags
                    valid &= ConfigNodeUtil.ParseValue <bool>(child, "owned", x => vessel.owned = x, factory, false);

                    // Handle the CREW nodes
                    foreach (ConfigNode crewNode in ConfigNodeUtil.GetChildNodes(child, "CREW"))
                    {
                        int count = 1;
                        valid &= ConfigNodeUtil.ParseValue <int>(crewNode, "count", x => count = x, factory, 1);
                        for (int i = 0; i < count; i++)
                        {
                            CrewData cd = new CrewData();

                            // Read crew details
                            valid &= ConfigNodeUtil.ParseValue <string>(crewNode, "name", x => cd.name = x, factory, (string)null);
                            valid &= ConfigNodeUtil.ParseValue <bool>(crewNode, "addToRoster", x => cd.addToRoster = x, factory, true);

                            // Check for unexpected values
                            valid &= ConfigNodeUtil.ValidateUnexpectedValues(crewNode, factory);

                            // Add the record
                            vessel.crew.Add(cd);
                        }
                    }

                    // Check for unexpected values
                    valid &= ConfigNodeUtil.ValidateUnexpectedValues(child, factory);

                    // Add to the list
                    spawnVessel.vessels.Add(vessel);
                }
                finally
                {
                    ConfigNodeUtil.SetCurrentDataNode(factory.dataNode);
                }
            }

            if (!configNode.HasNode("VESSEL"))
            {
                valid = false;
                LoggingUtil.LogError(factory, "SpawnVessel requires at least one VESSEL node.");
            }

            return(valid ? spawnVessel : null);
        }
コード例 #10
0
ファイル: VesselSpawn.cs プロジェクト: BahamutoD/VesselMover
        void SpawnVesselFromCraftFile(string craftURL, Vector3d gpsCoords, float heading, float pitch)
        {
            VesselData newData = new VesselData();

            newData.craftURL = craftURL;
            newData.latitude = gpsCoords.x;
            newData.longitude = gpsCoords.y;
            newData.altitude = gpsCoords.z+35;

            newData.body = FlightGlobals.currentMainBody;
            newData.heading = heading;
            newData.pitch = pitch;
            newData.orbiting = false;
            newData.flagURL = HighLogic.CurrentGame.flagURL;
            newData.owned = true;
            newData.vesselType = VesselType.Ship;
            newData.crew = new List<CrewData>();

            SpawnVessel(newData);
        }
コード例 #11
0
        public RisksTabPage WaitForAddedVesselDisplayed(VesselData data)
        {
            this.WebDriverWrapper.Wait.Until(x => this.WebDriverWrapper.FindElementsByXPath($"//span[@title='VesselName'and text()='{data.VesselName}']").Any());

            return(this);
        }
コード例 #12
0
        public static void Config(this Panel p, Vessel v)
        {
            // avoid corner-case when this is called in a lambda after scene changes
            v = FlightGlobals.FindVessel(v.id);

            // if vessel doesn't exist anymore, leave the panel empty
            if (v == null)
            {
                return;
            }

            // get info from the cache
            Vessel_Info vi = Cache.VesselInfo(v);

            // if not a valid vessel, leave the panel empty
            if (!vi.is_valid)
            {
                return;
            }

            // set metadata
            p.Title(Lib.BuildString(Lib.Ellipsis(v.vesselName, 20), " <color=#cccccc>VESSEL CONFIG</color>"));

            // time-out simulation
            if (p.Timeout(vi))
            {
                return;
            }

            // get data from db
            VesselData vd = DB.Vessel(v);

            // toggle rendering
            string tooltip;

            if (Features.Signal || Features.Reliability)
            {
                p.SetSection("RENDERING");
            }
            if (Features.Signal)
            {
                tooltip = "Render the connection line\nin mapview and tracking station";
                p.SetContent("show links", string.Empty, tooltip);
                p.SetIcon(vd.cfg_showlink ? Icons.toggle_green : Icons.toggle_red, tooltip, () => p.Toggle(ref vd.cfg_showlink));
            }
            if (Features.Reliability)
            {
                tooltip = "Highlight failed components";
                p.SetContent("highlight malfunctions", string.Empty, tooltip);
                p.SetIcon(vd.cfg_highlights ? Icons.toggle_green : Icons.toggle_red, tooltip, () => p.Toggle(ref vd.cfg_highlights));
            }

            // toggle messages
            p.SetSection("MESSAGES");
            tooltip = "Receive a message when\nElectricCharge level is low";
            p.SetContent("battery", string.Empty, tooltip);
            p.SetIcon(vd.cfg_ec ? Icons.toggle_green : Icons.toggle_red, tooltip, () => p.Toggle(ref vd.cfg_ec));
            if (Features.Supplies)
            {
                tooltip = "Receive a message when\nsupply resources level is low";
                p.SetContent("supply", string.Empty, tooltip);
                p.SetIcon(vd.cfg_supply ? Icons.toggle_green : Icons.toggle_red, tooltip, () => p.Toggle(ref vd.cfg_supply));
            }
            if (Features.Signal || Features.KCommNet)
            {
                tooltip = "Receive a message when signal is lost or obtained";
                p.SetContent("signal", string.Empty, tooltip);
                p.SetIcon(vd.cfg_signal ? Icons.toggle_green : Icons.toggle_red, tooltip, () => p.Toggle(ref vd.cfg_signal));
            }
            if (Features.Reliability)
            {
                tooltip = "Receive a message\nwhen a component fail";
                p.SetContent("reliability", string.Empty, tooltip);
                p.SetIcon(vd.cfg_malfunction ? Icons.toggle_green : Icons.toggle_red, tooltip, () => p.Toggle(ref vd.cfg_malfunction));
            }
            if (Features.SpaceWeather)
            {
                tooltip = "Receive a message\nduring CME events";
                p.SetContent("storm", string.Empty, tooltip);
                p.SetIcon(vd.cfg_storm ? Icons.toggle_green : Icons.toggle_red, tooltip, () => p.Toggle(ref vd.cfg_storm));
            }
            if (Features.Automation)
            {
                tooltip = "Receive a message when\nscripts are executed";
                p.SetContent("script", string.Empty, tooltip);
                p.SetIcon(vd.cfg_script ? Icons.toggle_green : Icons.toggle_red, tooltip, () => p.Toggle(ref vd.cfg_script));
            }
        }
コード例 #13
0
ファイル: VesselSpawn.cs プロジェクト: BahamutoD/VesselMover
        void SpawnVessel(VesselData vesselData)
        {
            string gameDataDir = KSPUtil.ApplicationRootPath;
            Debug.Log("Spawning a vessel named '" + vesselData.name + "'");

            // Set additional info for landed vessels
            bool landed = false;
            if (!vesselData.orbiting)
            {
                landed = true;
                if (vesselData.altitude == null)
                {
                    vesselData.altitude = 0;//LocationUtil.TerrainHeight(vesselData.latitude, vesselData.longitude, vesselData.body);
                }

                Vector3d pos = vesselData.body.GetWorldSurfacePosition(vesselData.latitude, vesselData.longitude, vesselData.altitude.Value);

                vesselData.orbit = new Orbit(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, vesselData.body);
                vesselData.orbit.UpdateFromStateVectors(pos, vesselData.body.getRFrmVel(pos), vesselData.body, Planetarium.GetUniversalTime());
            }
            else
            {
                vesselData.orbit.referenceBody = vesselData.body;
            }

            ConfigNode[] partNodes;
            UntrackedObjectClass sizeClass;
            ShipConstruct shipConstruct = null;
            bool hasClamp = false;
            float lcHeight = 0;
            ConfigNode craftNode;
            Quaternion craftRotation = Quaternion.identity;
            if (!string.IsNullOrEmpty(vesselData.craftURL))
            {
                // Save the current ShipConstruction ship, otherwise the player will see the spawned ship next time they enter the VAB!
                ConfigNode currentShip = ShipConstruction.ShipConfig;

                shipConstruct = ShipConstruction.LoadShip(vesselData.craftURL);
                if (shipConstruct == null)
                {
                    Debug.Log("ShipConstruct was null when tried to load '" + vesselData.craftURL +
                        "' (usually this means the file could not be found).");
                    return;//continue;
                }

                craftNode = ConfigNode.Load(vesselData.craftURL);
                lcHeight = ConfigNode.ParseVector3(craftNode.GetNode("PART").GetValue("pos")).y;
                craftRotation = ConfigNode.ParseQuaternion(craftNode.GetNode("PART").GetValue("rot"));

                // Restore ShipConstruction ship
                ShipConstruction.ShipConfig = currentShip;

                // Set the name
                if (string.IsNullOrEmpty(vesselData.name))
                {
                    vesselData.name = shipConstruct.shipName;
                }

                // Set some parameters that need to be at the part level
                uint missionID = (uint)Guid.NewGuid().GetHashCode();
                uint launchID = HighLogic.CurrentGame.launchID++;
                foreach (Part p in shipConstruct.parts)
                {
                    p.flightID = ShipConstruction.GetUniqueFlightID(HighLogic.CurrentGame.flightState);
                    p.missionID = missionID;
                    p.launchID = launchID;
                    p.flagURL = vesselData.flagURL ?? HighLogic.CurrentGame.flagURL;

                    // Had some issues with this being set to -1 for some ships - can't figure out
                    // why.  End result is the vessel exploding, so let's just set it to a positive
                    // value.
                    p.temperature = 1.0;
                }

                //add minimal crew
                {
                    bool success = false;
                    Part part = shipConstruct.parts.Find(p => p.protoModuleCrew.Count < p.CrewCapacity);

                    // Add the crew member
                    if (part != null)
                    {
                        // Create the ProtoCrewMember
                        ProtoCrewMember crewMember = HighLogic.CurrentGame.CrewRoster.GetNewKerbal(ProtoCrewMember.KerbalType.Unowned);

                        crewMember.gender = UnityEngine.Random.Range(0,100) > 50 ? ProtoCrewMember.Gender.Female : ProtoCrewMember.Gender.Male;

                        /*
                        if (cd.name != null)
                        {
                            crewMember.name = cd.name;
                        }
                        */

                        // Add them to the part
                        success = part.AddCrewmemberAt(crewMember, part.protoModuleCrew.Count);
                    }
                }

                /*
                foreach (CrewData cd in vesselData.crew)
                {
                    bool success = false;

                    // Find a seat for the crew
                    Part part = shipConstruct.parts.Find(p => p.protoModuleCrew.Count < p.CrewCapacity);

                    // Add the crew member
                    if (part != null)
                    {
                        // Create the ProtoCrewMember
                        ProtoCrewMember crewMember = HighLogic.CurrentGame.CrewRoster.GetNewKerbal(ProtoCrewMember.KerbalType.Unowned);
                        if (cd.gender != null)
                        {
                            crewMember.gender = cd.gender.Value;
                        }
                        if (cd.name != null)
                        {
                            crewMember.name = cd.name;
                        }

                        // Add them to the part
                        success = part.AddCrewmemberAt(crewMember, part.protoModuleCrew.Count);
                    }

                    if (!success)
                    {
                        Debug.Log("Unable to add crew to vessel named '" + vesselData.name + "'.  Perhaps there's no room?");
                        break;
                    }
                }
                */
                // Create a dummy ProtoVessel, we will use this to dump the parts to a config node.
                // We can't use the config nodes from the .craft file, because they are in a
                // slightly different format than those required for a ProtoVessel (seriously
                // Squad?!?).
                ConfigNode empty = new ConfigNode();
                ProtoVessel dummyProto = new ProtoVessel(empty, null);
                Vessel dummyVessel = new Vessel();
                dummyVessel.parts = shipConstruct.parts;
                dummyProto.vesselRef = dummyVessel;

                // Create the ProtoPartSnapshot objects and then initialize them
                foreach (Part p in shipConstruct.parts)
                {
                    dummyProto.protoPartSnapshots.Add(new ProtoPartSnapshot(p, dummyProto));
                }
                foreach (ProtoPartSnapshot p in dummyProto.protoPartSnapshots)
                {
                    p.storePartRefs();
                }

                // Create the ship's parts

                List<ConfigNode> partNodesL = new List<ConfigNode>();
                foreach(var snapShot in dummyProto.protoPartSnapshots)
                {
                    ConfigNode node = new ConfigNode("PART");
                    snapShot.Save(node);
                    partNodesL.Add(node);
                }
                partNodes = partNodesL.ToArray();

                // Estimate an object class, numbers are based on the in game description of the
                // size classes.
                float size = shipConstruct.shipSize.magnitude / 2.0f;
                if (size < 4.0f)
                {
                    sizeClass = UntrackedObjectClass.A;
                }
                else if (size < 7.0f)
                {
                    sizeClass = UntrackedObjectClass.B;
                }
                else if (size < 12.0f)
                {
                    sizeClass = UntrackedObjectClass.C;
                }
                else if (size < 18.0f)
                {
                    sizeClass = UntrackedObjectClass.D;
                }
                else
                {
                    sizeClass = UntrackedObjectClass.E;
                }
            }
            else
            {
                // Create crew member array
                ProtoCrewMember[] crewArray = new ProtoCrewMember[vesselData.crew.Count];
                int i = 0;
                foreach (CrewData cd in vesselData.crew)
                {
                    // Create the ProtoCrewMember
                    ProtoCrewMember crewMember = HighLogic.CurrentGame.CrewRoster.GetNewKerbal(ProtoCrewMember.KerbalType.Unowned);
                    if (cd.name != null)
                    {
                        crewMember.name = cd.name;
                    }

                    crewArray[i++] = crewMember;
                }

                // Create part nodes
                uint flightId = ShipConstruction.GetUniqueFlightID(HighLogic.CurrentGame.flightState);
                partNodes = new ConfigNode[1];
                partNodes[0] = ProtoVessel.CreatePartNode(vesselData.craftPart.name, flightId, crewArray);

                // Default the size class
                sizeClass = UntrackedObjectClass.A;

                // Set the name
                if (string.IsNullOrEmpty(vesselData.name))
                {
                    vesselData.name = vesselData.craftPart.name;
                }
            }

            // Create additional nodes
            ConfigNode[] additionalNodes = new ConfigNode[0];
            //DiscoveryLevels discoveryLevel = vesselData.owned ? DiscoveryLevels.Owned : DiscoveryLevels.Unowned;
            //additionalNodes[0] = ProtoVessel.CreateDiscoveryNode(discoveryLevel, sizeClass, contract.TimeDeadline, contract.TimeDeadline);

            // Create the config node representation of the ProtoVessel
            ConfigNode protoVesselNode = ProtoVessel.CreateVesselNode(vesselData.name, vesselData.vesselType, vesselData.orbit, 0, partNodes, additionalNodes);

            // Additional seetings for a landed vessel
            if (!vesselData.orbiting)
            {
                Vector3d norm = vesselData.body.GetRelSurfaceNVector(vesselData.latitude, vesselData.longitude);

                double terrainHeight = 0.0;
                if (vesselData.body.pqsController != null)
                {
                    terrainHeight = vesselData.body.pqsController.GetSurfaceHeight(norm) - vesselData.body.pqsController.radius;
                }
                bool splashed = false;// = landed && terrainHeight < 0.001;

                // Create the config node representation of the ProtoVessel
                // Note - flying is experimental, and so far doesn't work
                protoVesselNode.SetValue("sit", (splashed ? Vessel.Situations.SPLASHED : landed ?
                    Vessel.Situations.LANDED : Vessel.Situations.FLYING).ToString());
                protoVesselNode.SetValue("landed", (landed && !splashed).ToString());
                protoVesselNode.SetValue("splashed", splashed.ToString());
                protoVesselNode.SetValue("lat", vesselData.latitude.ToString());
                protoVesselNode.SetValue("lon", vesselData.longitude.ToString());
                protoVesselNode.SetValue("alt", vesselData.altitude.ToString());
                protoVesselNode.SetValue("landedAt", vesselData.body.name);

                // Figure out the additional height to subtract
                float lowest = float.MaxValue;
                if (shipConstruct != null)
                {
                    foreach (Part p in shipConstruct.parts)
                    {
                        foreach (Collider collider in p.GetComponentsInChildren<Collider>())
                        {
                            if (collider.gameObject.layer != 21 && collider.enabled)
                            {
                                lowest = Mathf.Min(lowest, collider.bounds.min.y);
                            }
                        }
                    }
                }
                else
                {
                    foreach (Collider collider in vesselData.craftPart.partPrefab.GetComponentsInChildren<Collider>())
                    {
                        if (collider.gameObject.layer != 21 && collider.enabled)
                        {
                            lowest = Mathf.Min(lowest, collider.bounds.min.y);
                        }
                    }
                }

                if (lowest == float.MaxValue)
                {
                    lowest = 0;
                }

                // Figure out the surface height and rotation
                Quaternion normal = Quaternion.LookRotation((Vector3)norm);// new Vector3((float)norm.x, (float)norm.y, (float)norm.z));
                Quaternion rotation = Quaternion.identity;
                float heading = vesselData.heading;
                if (shipConstruct == null)
                {
                    rotation = rotation * Quaternion.FromToRotation(Vector3.up, Vector3.back);
                }
                else if (shipConstruct.shipFacility == EditorFacility.SPH)
                {
                    rotation = rotation * Quaternion.FromToRotation(Vector3.forward, -Vector3.forward);
                    heading += 180.0f;
                }
                else
                {
                    rotation = rotation * Quaternion.FromToRotation(Vector3.up, Vector3.forward);
                    rotation = Quaternion.FromToRotation(Vector3.up, -Vector3.up) * rotation;

                    //rotation = craftRotation;

                    vesselData.heading = 0;
                    vesselData.pitch = 0;
                }

                rotation = rotation * Quaternion.AngleAxis(heading, Vector3.back);
                rotation = rotation * Quaternion.AngleAxis(vesselData.roll, Vector3.down);
                rotation = rotation * Quaternion.AngleAxis(vesselData.pitch, Vector3.left);

                // Set the height and rotation
                if (landed || splashed)
                {
                    float hgt = (shipConstruct != null ? shipConstruct.parts[0] : vesselData.craftPart.partPrefab).localRoot.attPos0.y - lowest;
                    hgt += vesselData.height;

                    foreach(var p in shipConstruct.Parts)
                    {
                        LaunchClamp lc = p.FindModuleImplementing<LaunchClamp>();
                        if(lc)
                        {
                            hasClamp = true;
                            break;
                        }
                    }

                    if(!hasClamp)
                    {
                        hgt += 35;
                    }
                    else
                    {
                        hgt += lcHeight;
                    }
                    protoVesselNode.SetValue("hgt", hgt.ToString(), true);
                }
                protoVesselNode.SetValue("rot", KSPUtil.WriteQuaternion(normal * rotation), true);

                // Set the normal vector relative to the surface
                Vector3 nrm = (rotation * Vector3.forward);
                protoVesselNode.SetValue("nrm", nrm.x + "," + nrm.y + "," + nrm.z, true);

                protoVesselNode.SetValue("prst", false.ToString(), true);
            }

            // Add vessel to the game
            ProtoVessel protoVessel = HighLogic.CurrentGame.AddVessel(protoVesselNode);
            //protoVessel.vesselRef.transform.rotation = protoVessel.rotation;

            // Store the id for later use
            vesselData.id = protoVessel.vesselRef.id;

            //protoVessel.vesselRef.currentStage = 0;

            StartCoroutine(PlaceSpawnedVessel(protoVessel.vesselRef, !hasClamp));

            // Associate it so that it can be used in contract parameters
            //ContractVesselTracker.Instance.AssociateVessel(vesselData.name, protoVessel.vesselRef);

            //destroy prefabs
            foreach(var p in FindObjectsOfType<Part>())
            {
                if(!p.vessel)
                {
                    Destroy(p.gameObject);
                }
            }
        }
コード例 #14
0
        public void showVesselTrackingInfo()
        {
            trackingInfoScroll = GUILayout.BeginScrollView(trackingInfoScroll);
            GUILayout.BeginVertical();
            if (selectedVesselData != null)
            {
                if (selectedVesselData.vessel != null)
                {
                    /* Vessel Info: */
                    GUILayout.Label(selectedVesselData.vessel.name + ":", UIStyle.headingLabelStyle);

                    GUILayout.Space(UIStyle.separatorSpacing);

                    /* Basic info */
                    GUILayout.Label("Basic Information:", UIStyle.headingLabelStyle);
                    if (selectedVesselData.vessel.loaded)
                    {
                        GUILayout.Label("Mass: " + Math.Round(selectedVesselData.vessel.totalMass, 5).ToString() + " tons");
                        GUILayout.Label("Crew: " + selectedVesselData.vessel.GetCrewCount().ToString());
                        if (selectedVesselData.currentLocation != null)
                        {
                            GUILayout.Label("Current Location: " + selectedVesselData.currentLocation.name);
                        }
                        else
                        {
                            GUILayout.Label("Current Location: " + selectedVesselData.vessel.GetOrbit().referenceBody.name + " (not at supply point)");
                        }
                    }
                    else
                    {
                        GUILayout.Label(
                            "Mass: " +
                            selectedVesselData.vessel.protoVessel.protoPartSnapshots.Sum((ProtoPartSnapshot ps) => { return(ps.mass); }).ToString()
                            );

                        GUILayout.Label(
                            "Crew: " +
                            selectedVesselData.vessel.protoVessel.protoPartSnapshots.Sum((ProtoPartSnapshot ps) => { return(ps.protoModuleCrew.Count); }).ToString()
                            );

                        if (selectedVesselData.currentLocation != null)
                        {
                            GUILayout.Label("Current Location: " + selectedVesselData.currentLocation.name);
                        }
                        else
                        {
                            GUILayout.Label(
                                "Current Location: " +
                                FlightGlobals.Bodies[selectedVesselData.vessel.protoVessel.orbitSnapShot.ReferenceBodyIndex].name +
                                " (not at supply point)"
                                );
                        }
                    }

                    /* Vessel Resources */
                    Dictionary <int, double> currentResourceCounts;
                    Dictionary <int, double> maxResourceCounts;

                    GUILayout.Space(UIStyle.separatorSpacing);

                    GUILayout.Label("Vessel Resources:", UIStyle.headingLabelStyle);

                    selectedVesselData.getAllResourceCounts(out currentResourceCounts, out maxResourceCounts);
                    foreach (int rscID in maxResourceCounts.Keys)
                    {
                        GUILayout.Label(
                            PartResourceLibrary.Instance.GetDefinition(rscID).name + ": " +
                            currentResourceCounts[rscID].ToString() + " / " + maxResourceCounts[rscID].ToString()
                            );
                    }

                    GUILayout.Space(UIStyle.separatorSpacing);

                    /* Vessel Capabilities: */
                    GUILayout.Label("Vessel Capabilities:", UIStyle.headingLabelStyle);
                    if (selectedVesselData.orbitalDockingEnabled)
                    {
                        GUILayout.Label("Orbital Resource Transfer Enabled", UIStyle.passableLabelStyle);
                    }
                    else
                    {
                        GUILayout.Label("Orbital Resource Transfer Disabled", UIStyle.impassableLabelStyle);
                    }

                    GUILayout.Space(UIStyle.separatorSpacing);

                    /* Vessel Supply Links */
                    GUILayout.Label("Vessel Supply Links:", UIStyle.headingLabelStyle);
                    foreach (SupplyLink l in selectedVesselData.links)
                    {
                        SupplyLinkStatus.drawStatusLabel(l);
                    }
                }
                else
                {
                    GUILayout.Label("Unknown vessel selected.");
                }

                if (GUILayout.Button("Back"))
                {
                    selectedVesselData = null;
                }
            }
            else
            {
                foreach (VesselData vd in SupplyChainController.instance.trackedVessels)
                {
                    if (vd.vessel != null)
                    {
                        if (GUILayout.Button(
                                vd.vessel.name + " (MET T+" + UIStyle.formatTimespan(Math.Round(vd.vessel.missionTime), true).ToString() + ")"
                                ))
                        {
                            selectedVesselData = vd;
                            trackingInfoScroll = new Vector2();
                        }
                    }
                }
            }

            GUILayout.EndVertical();
            GUILayout.EndScrollView();
        }
コード例 #15
0
 public abstract HashSet<ProtoPartResourceSnapshot> HandleResource(Vessel v, VesselData data, HashSet<ProtoPartResourceSnapshot> modified);
コード例 #16
0
        public static void SpawnAsteroid(Vessel asteroidCopy)
        {
            VesselData vesselData = new VesselData();

            vesselData.body       = FlightGlobals.currentMainBody;
            vesselData.orbiting   = true;
            vesselData.flagURL    = HighLogic.CurrentGame.flagURL;
            vesselData.owned      = true;
            vesselData.vesselType = VesselType.SpaceObject;

            string gameDataDir = KSPUtil.ApplicationRootPath;

            vesselData.orbit                     = FlightGlobals.ActiveVessel.GetOrbit();
            vesselData.orbit.inclination         = UnityEngine.Random.Range(0, 360);
            vesselData.orbit.eccentricity        = UnityEngine.Random.Range(0, 0.3f);
            vesselData.orbit.semiMajorAxis       = UnityEngine.Random.Range(Convert.ToSingle(FlightGlobals.ActiveVessel.mainBody.Radius + FlightGlobals.ActiveVessel.mainBody.atmosphereDepth + 50000), Convert.ToSingle(FlightGlobals.ActiveVessel.mainBody.sphereOfInfluence));
            vesselData.orbit.LAN                 = UnityEngine.Random.Range(0, 360);
            vesselData.orbit.argumentOfPeriapsis = UnityEngine.Random.Range(0, 360);

            vesselData.orbit.meanAnomalyAtEpoch = 0;
            ConfigNode[] partNodes;
            ConfigNode   currentShip = ShipConstruction.ShipConfig;

            ShipConstruction.ShipConfig = currentShip;
            int i = 1;

            foreach (Vessel v in FlightGlobals.Vessels)
            {
                if (v.vesselType == VesselType.Unknown || v.vesselType == VesselType.SpaceObject)
                {
                    i++;
                }
            }
            vesselData.name = "asteroid #" + i;
            ConfigNode  empty       = new ConfigNode();
            ProtoVessel dummyProto  = new ProtoVessel(empty, null);
            Vessel      dummyVessel = new Vessel();

            dummyVessel.parts    = asteroidCopy.Parts;
            dummyProto.vesselRef = dummyVessel;
            foreach (Part p in asteroidCopy.Parts)
            {
                dummyProto.protoPartSnapshots.Add(new ProtoPartSnapshot(p, dummyProto));
            }
            foreach (ProtoPartSnapshot p in dummyProto.protoPartSnapshots)
            {
                p.storePartRefs();
            }
            List <ConfigNode> partNodesL = new List <ConfigNode>();

            foreach (var snapShot in dummyProto.protoPartSnapshots)
            {
                ConfigNode node = new ConfigNode("PART");
                snapShot.Save(node);
                partNodesL.Add(node);
            }
            partNodes = partNodesL.ToArray();
            ConfigNode[] additionalNodes = new ConfigNode[0];
            ConfigNode   protoVesselNode = ProtoVessel.CreateVesselNode(vesselData.name, vesselData.vesselType, vesselData.orbit, 0, partNodes, additionalNodes);
            ProtoVessel  protoVessel     = HighLogic.CurrentGame.AddVessel(protoVesselNode);

            vesselData.id = protoVessel.vesselRef.id;
            foreach (var p in FindObjectsOfType <Part>())
            {
                if (!p.vessel)
                {
                    Destroy(p.gameObject);
                }
            }
        }
コード例 #17
0
        public override HashSet <ProtoPartResourceSnapshot> HandleResource(Vessel v, VesselData data, HashSet <ProtoPartResourceSnapshot> modified)
        {
            BackgroundProcessing.Debug("Panel data, doing solar panel calcs", DebugLevel.ALL);

            Vector3d sun_dir;
            double   sun_dist;
            bool     in_sunlight = SolarPanel.RaytraceBody(v, FlightGlobals.Bodies[0], out sun_dir, out sun_dist);
            Vector3d partPos     = VesselPosition(v) + position;

            double orientationFactor = 1;

            if (tracks)
            {
                Vector3d localPivot = (v.transform.rotation * orientation * pivotAxis).normalized;
                orientationFactor = Math.Cos(Math.PI / 2.0 - Math.Acos(Vector3d.Dot(localPivot, sun_dir)));
            }
            else
            {
                Vector3d localSolarNormal = (v.transform.rotation * orientation * solarNormal).normalized;
                orientationFactor = Vector3d.Dot(localSolarNormal, sun_dir);
            }

            orientationFactor = Math.Max(orientationFactor, 0);

            if (in_sunlight)
            {
                double solarFlux = SolarPanel.SolarLuminosity / (12.566370614359172 * sun_dist * sun_dist);
                BackgroundProcessing.Debug("Pre-atmosphere flux: " + solarFlux + ", pre-atmosphere distance: " + sun_dist + ", solar luminosity: " + PhysicsGlobals.SolarLuminosity, DebugLevel.ALL);

                double staticPressure = v.mainBody.GetPressure(v.altitude);
                BackgroundProcessing.Debug("Static pressure: " + staticPressure, DebugLevel.ALL);

                if (staticPressure > 0.0)
                {
                    double density = v.mainBody.GetDensity(staticPressure, temperature);
                    BackgroundProcessing.Debug("density: " + density, DebugLevel.ALL);
                    Vector3 up       = FlightGlobals.getUpAxis(v.mainBody, v.vesselTransform.position).normalized;
                    double  sunPower = v.mainBody.radiusAtmoFactor * Vector3d.Dot(up, sun_dir);
                    double  sMult    = v.mainBody.GetSolarPowerFactor(density);
                    if (sunPower < 0)
                    {
                        sMult /= Math.Sqrt(2.0 * v.mainBody.radiusAtmoFactor + 1.0);
                    }
                    else
                    {
                        sMult /= Math.Sqrt(sunPower * sunPower + 2.0 * v.mainBody.radiusAtmoFactor + 1.0) - sunPower;
                    }

                    BackgroundProcessing.Debug("Atmospheric flux adjustment: " + sMult, DebugLevel.ALL);
                    solarFlux *= sMult;

                    BackgroundProcessing.Debug("Vessel solar flux: " + v.solarFlux, DebugLevel.ALL);
                }
                else
                {
                    BackgroundProcessing.Debug("No need for atmospheric adjustment", DebugLevel.ALL);
                }

                float multiplier = 1;
                if (usesCurve)
                {
                    multiplier = powerCurve.Evaluate((float)FlightGlobals.Bodies[0].GetAltitude(partPos));
                }
                else
                {
                    multiplier = (float)(solarFlux / PhysicsGlobals.SolarLuminosityAtHome);
                }

                BackgroundProcessing.Debug("Resource rate: " + chargeRate, DebugLevel.ALL);
                BackgroundProcessing.Debug("Vessel " + v.vesselName + " solar panel, orientation factor: " + orientationFactor + ", temperature: " + temperature + " solar flux: " + solarFlux, DebugLevel.ALL);
                float tempFactor = tempCurve.Evaluate(temperature);

                if (!BackgroundProcessing.config.solarOrientationMatters)
                {
                    orientationFactor = 1; BackgroundProcessing.Debug("Orientation disabled in config file", DebugLevel.ALL);
                }
                if (!BackgroundProcessing.config.solarTemperatureMatters)
                {
                    tempFactor = 1; BackgroundProcessing.Debug("Temperature disabled in config file", DebugLevel.ALL);
                }

                float resourceAmount = chargeRate * (float)orientationFactor * tempFactor * multiplier;
                BackgroundProcessing.Debug("Vessel " + v.vesselName + ", adding " + resourceAmount + " " + resourceName + " over time " + TimeWarp.fixedDeltaTime, DebugLevel.ALL);
                modified = AddResource(data, resourceAmount * TimeWarp.fixedDeltaTime, resourceName, modified);
            }
            else
            {
                BackgroundProcessing.Debug("Can't see Kerbol", DebugLevel.ALL);
            }

            return(modified);
        }
コード例 #18
0
        public static SpawnVessel Create(ConfigNode configNode, CelestialBody defaultBody, SpawnVesselFactory factory)
        {
            SpawnVessel spawnVessel = new SpawnVessel();

            bool valid = true;
            int  index = 0;

            foreach (ConfigNode child in ConfigNodeUtil.GetChildNodes(configNode, "VESSEL"))
            {
                DataNode dataNode = new DataNode("VESSEL_" + index++, factory.dataNode, factory);
                try
                {
                    ConfigNodeUtil.SetCurrentDataNode(dataNode);

                    VesselData vessel = new VesselData();

                    // Get name
                    if (child.HasValue("name"))
                    {
                        vessel.name = child.GetValue("name");
                    }

                    // Get paths
                    vessel.craftURL   = ConfigNodeUtil.ParseValue <string>(child, "craftURL");
                    vessel.flagURL    = ConfigNodeUtil.ParseValue <string>(child, "flagURL", (string)null);
                    vessel.vesselType = ConfigNodeUtil.ParseValue <VesselType>(child, "vesselType", VesselType.Ship);

                    // Get celestial body
                    valid &= ConfigNodeUtil.ParseValue <CelestialBody>(child, "targetBody", x => vessel.body = x, factory, defaultBody, Validation.NotNull);

                    // Get landed stuff
                    if (child.HasValue("lat") && child.HasValue("lon"))
                    {
                        valid        &= ConfigNodeUtil.ParseValue <double>(child, "lat", x => vessel.latitude = x, factory);
                        valid        &= ConfigNodeUtil.ParseValue <double>(child, "lon", x => vessel.longitude = x, factory);
                        valid        &= ConfigNodeUtil.ParseValue <double?>(child, "alt", x => vessel.altitude = x, factory, (double?)null);
                        vessel.landed = true;
                    }
                    // Get orbit
                    else
                    {
                        valid       &= ConfigNodeUtil.ValidateMandatoryChild(child, "ORBIT", factory);
                        vessel.orbit = new OrbitSnapshot(ConfigNodeUtil.GetChildNode(child, "ORBIT")).Load();
                        vessel.orbit.referenceBody = vessel.body;
                    }

                    // Get additional flags
                    valid &= ConfigNodeUtil.ParseValue <bool>(child, "owned", x => vessel.owned = x, factory, false);

                    // Handle the CREW nodes
                    foreach (ConfigNode crewNode in ConfigNodeUtil.GetChildNodes(child, "CREW"))
                    {
                        int count = 1;
                        valid &= ConfigNodeUtil.ParseValue <int>(crewNode, "count", x => count = x, factory, 1);
                        for (int i = 0; i < count; i++)
                        {
                            CrewData cd = new CrewData();

                            // Read crew details
                            valid &= ConfigNodeUtil.ParseValue <string>(crewNode, "name", x => cd.name = x, factory, (string)null);
                            valid &= ConfigNodeUtil.ParseValue <bool>(crewNode, "addToRoster", x => cd.addToRoster = x, factory, true);

                            // Add the record
                            vessel.crew.Add(cd);
                        }
                    }

                    // Add to the list
                    spawnVessel.vessels.Add(vessel);
                }
                finally
                {
                    ConfigNodeUtil.SetCurrentDataNode(factory.dataNode);
                }
            }

            return(valid ? spawnVessel : null);
        }
コード例 #19
0
        private void RemoveCrew(VesselData vd)
        {
            foreach (CrewData cd in vd.crew)
            {
                ProtoCrewMember crewMember = HighLogic.CurrentGame.CrewRoster.AllKerbals().Where(pcm => pcm.name == cd.name).FirstOrDefault();
                if (!cd.addToRoster && crewMember != null)
                {
                    Vessel otherVessel = FlightGlobals.Vessels.Where(v => v.GetVesselCrew().Contains(crewMember)).FirstOrDefault();
                    if (otherVessel != null)
                    {
                        // If it's an EVA make them disappear...
                        if (otherVessel.isEVA)
                        {
                            FlightGlobals.Vessels.Remove(otherVessel);
                        }
                        else
                        {
                            if (otherVessel.loaded)
                            {
                                foreach (Part p in otherVessel.parts)
                                {
                                    if (p.protoModuleCrew.Contains(crewMember))
                                    {
                                        p.RemoveCrewmember(crewMember);
                                        break;
                                    }
                                }
                            }
                            else
                            {
                                foreach (ProtoPartSnapshot pps in otherVessel.protoVessel.protoPartSnapshots)
                                {
                                    if (pps.HasCrew(crewMember.name))
                                    {
                                        pps.RemoveCrew(crewMember);
                                    }
                                }
                            }
                        }
                    }

                    // Remove the kerbal from the roster
                    HighLogic.CurrentGame.CrewRoster.Remove(cd.name);
                }
            }
        }
コード例 #20
0
        /// <summary>
        /// Plane normal vector from a given heading (surface right vector)
        /// </summary>
        public static Vector3 vecHeading(double target, VesselData vdata)
        {
            double angleDiff = target - vdata.heading;

            return(Quaternion.AngleAxis((float)(angleDiff + 90), (Vector3)vdata.planetUp) * vdata.surfVesForward);
        }
コード例 #21
0
 public override HashSet <ProtoPartResourceSnapshot> HandleResource(Vessel v, VesselData data, HashSet <ProtoPartResourceSnapshot> modified)
 {
     return(AddResource(data, resourceRate * TimeWarp.fixedDeltaTime, resourceName, modified));
 }
コード例 #22
0
        /// <summary>
        /// calculate current heading from plane rotation
        /// </summary>
        public static double calculateTargetHeading(Quaternion rotation, Vessel vessel, VesselData vdata)
        {
            Vector3 fwd     = Vector3.Cross(getPlaneNormal(rotation, vessel), vdata.planetUp);
            double  heading = Vector3.Angle(fwd, vdata.planetNorth) * Math.Sign(Vector3.Dot(fwd, vdata.planetEast));

            return(heading.headingClamp(360));
        }
コード例 #23
0
        void SpawnVessel(VesselData vesselData)
        {
            string gameDataDir = KSPUtil.ApplicationRootPath;

            vesselData.orbit     = vessel.GetOrbit();
            vesselData.orbit.vel = vessel.orbit.vel;
            vesselData.orbit.meanAnomalyAtEpoch = vesselData.orbit.meanAnomalyAtEpoch + Math.Atan(UnityEngine.Random.Range(200, 300) / vesselData.orbit.semiMajorAxis);
            ConfigNode[]  partNodes;
            ShipConstruct shipConstruct = null;
            float         lcHeight      = 0;
            ConfigNode    craftNode;
            ConfigNode    currentShip = ShipConstruction.ShipConfig;

            shipConstruct = ShipConstruction.LoadShip(vesselData.craftURL);
            float dryCost = 0;
            float cost    = 0;

            shipConstruct.GetShipCosts(out dryCost, out cost);
            cost = cost + dryCost;
            if (cost > Funding.Instance.Funds)
            {
                foreach (var p in FindObjectsOfType <Part>())
                {
                    if (!p.vessel)
                    {
                        Destroy(p.gameObject);
                    }
                }
                ScreenMessages.PostScreenMessage("not enought funds", 5.0f, ScreenMessageStyle.UPPER_CENTER);
                return;
            }
            craftNode = ConfigNode.Load(vesselData.craftURL);
            lcHeight  = ConfigNode.ParseVector3(craftNode.GetNode("PART").GetValue("pos")).y;
            ShipConstruction.ShipConfig = currentShip;
            vesselData.name             = shipConstruct.shipName;

            uint missionID = (uint)Guid.NewGuid().GetHashCode();
            uint launchID  = HighLogic.CurrentGame.launchID++;

            foreach (Part p in shipConstruct.parts)
            {
                p.missionID   = missionID;
                p.launchID    = launchID;
                p.flightID    = ShipConstruction.GetUniqueFlightID(HighLogic.CurrentGame.flightState);
                p.temperature = 1.0;
            }
            ConfigNode  empty       = new ConfigNode();
            ProtoVessel dummyProto  = new ProtoVessel(empty, null);
            Vessel      dummyVessel = new Vessel();

            dummyVessel.parts    = shipConstruct.parts;
            dummyProto.vesselRef = dummyVessel;

            foreach (Part p in shipConstruct.parts)
            {
                dummyProto.protoPartSnapshots.Add(new ProtoPartSnapshot(p, dummyProto));
            }
            foreach (ProtoPartSnapshot p in dummyProto.protoPartSnapshots)
            {
                p.storePartRefs();
            }
            List <ConfigNode> partNodesL = new List <ConfigNode>();

            foreach (var snapShot in dummyProto.protoPartSnapshots)
            {
                ConfigNode node = new ConfigNode("PART");
                snapShot.Save(node);
                partNodesL.Add(node);
            }
            partNodes = partNodesL.ToArray();
            ConfigNode[] additionalNodes = new ConfigNode[0];
            ConfigNode   protoVesselNode = ProtoVessel.CreateVesselNode(vesselData.name, VesselType.Ship, vesselData.orbit, 0, partNodes, additionalNodes);
            ProtoVessel  protoVessel     = HighLogic.CurrentGame.AddVessel(protoVesselNode);

            vesselData.id = protoVessel.vesselRef.id;
            protoVessel.vesselRef.Load();
            Funding.Instance.AddFunds(-cost, TransactionReasons.Vessels);
            ScreenMessages.PostScreenMessage("vessel buy !", 5.0f, ScreenMessageStyle.UPPER_CENTER);
            foreach (var p in FindObjectsOfType <Part>())
            {
                if (!p.vessel)
                {
                    Destroy(p.gameObject);
                }
            }
        }
コード例 #24
0
        public static Quaternion getPlaneRotation(double heading, Vessel vessel, VesselData vdata)
        {
            Vector3 planeNormal = vecHeading(heading, vdata);

            return(getPlaneRotation(planeNormal, vessel));
        }
コード例 #25
0
ファイル: Utility.cs プロジェクト: Kramax/KramaxAutoPilot
 public static Quaternion getPlaneRotation(double heading, Vessel vessel, VesselData vdata)
 {
     Vector3 planeNormal = vecHeading(heading, vdata);
     return getPlaneRotation(planeNormal, vessel);
 }
コード例 #26
0
        public static SpawnVessel Create(ConfigNode configNode, SpawnVesselFactory factory)
        {
            SpawnVessel spawnVessel = new SpawnVessel();

            ConfigNodeUtil.ParseValue<bool>(configNode, "deferVesselCreation", x => spawnVessel.deferVesselCreation = x, factory, false);

            bool valid = true;
            int index = 0;
            foreach (ConfigNode child in ConfigNodeUtil.GetChildNodes(configNode, "VESSEL"))
            {
                DataNode dataNode = new DataNode("VESSEL_" + index++, factory.dataNode, factory);
                try
                {
                    ConfigNodeUtil.SetCurrentDataNode(dataNode);

                    VesselData vessel = new VesselData();

                    // Get name
                    if (child.HasValue("name"))
                    {
                        valid &= ConfigNodeUtil.ParseValue<string>(child, "name", x => vessel.name = x, factory);
                    }

                    // Get craft details
                    if (child.HasValue("craftURL"))
                    {
                        valid &= ConfigNodeUtil.ParseValue<string>(child, "craftURL", x => vessel.craftURL = x, factory);
                    }
                    if (child.HasValue("craftPart"))
                    {
                        valid &= ConfigNodeUtil.ParseValue<AvailablePart>(child, "craftPart", x => vessel.craftPart = x, factory);
                    }
                    valid &= ConfigNodeUtil.AtLeastOne(child, new string[] { "craftURL", "craftPart" }, factory);

                    valid &= ConfigNodeUtil.ParseValue<string>(child, "flagURL", x => vessel.flagURL = x, factory, (string)null);
                    valid &= ConfigNodeUtil.ParseValue<VesselType>(child, "vesselType", x => vessel.vesselType = x, factory, VesselType.Ship);

                    // Use an expression to default - then it'll work for dynamic contracts
                    if (!child.HasValue("targetBody"))
                    {
                        child.AddValue("targetBody", "@/targetBody");
                    }
                    valid &= ConfigNodeUtil.ParseValue<CelestialBody>(child, "targetBody", x => vessel.body = x, factory);

                    // Get landed stuff
                    if (child.HasValue("lat") && child.HasValue("lon"))
                    {
                        valid &= ConfigNodeUtil.ParseValue<double>(child, "lat", x => vessel.latitude = x, factory);
                        valid &= ConfigNodeUtil.ParseValue<double>(child, "lon", x => vessel.longitude = x, factory);
                        valid &= ConfigNodeUtil.ParseValue<double?>(child, "alt", x => vessel.altitude = x, factory, (double?)null);
                        valid &= ConfigNodeUtil.ParseValue<float>(child, "height", x => vessel.height = x, factory,
                            !string.IsNullOrEmpty(vessel.craftURL) ? 0.0f : 2.5f);
                        vessel.orbiting = false;
                    }
                    // Get orbit
                    else
                    {
                        valid &= ConfigNodeUtil.ParseValue<Orbit>(child, "ORBIT", x => vessel.orbit = x, factory);
                        vessel.orbiting = true;
                    }

                    valid &= ConfigNodeUtil.ParseValue<float>(child, "heading", x => vessel.heading = x, factory, 0.0f);
                    valid &= ConfigNodeUtil.ParseValue<float>(child, "pitch", x => vessel.pitch = x, factory, 0.0f);
                    valid &= ConfigNodeUtil.ParseValue<float>(child, "roll", x => vessel.roll = x, factory, 0.0f);

                    // Get additional flags
                    valid &= ConfigNodeUtil.ParseValue<bool>(child, "owned", x => vessel.owned = x, factory, false);

                    // Handle the CREW nodes
                    foreach (ConfigNode crewNode in ConfigNodeUtil.GetChildNodes(child, "CREW"))
                    {
                        int count = 1;
                        valid &= ConfigNodeUtil.ParseValue<int>(crewNode, "count", x => count = x, factory, 1);
                        for (int i = 0; i < count; i++)
                        {
                            CrewData cd = new CrewData();

                            // Read crew details
                            valid &= ConfigNodeUtil.ParseValue<string>(crewNode, "name", x => cd.name = x, factory, (string)null);
                            valid &= ConfigNodeUtil.ParseValue<bool>(crewNode, "addToRoster", x => cd.addToRoster = x, factory, true);

                            // Check for unexpected values
                            valid &= ConfigNodeUtil.ValidateUnexpectedValues(crewNode, factory);

                            // Add the record
                            vessel.crew.Add(cd);
                        }
                    }

                    // Check for unexpected values
                    valid &= ConfigNodeUtil.ValidateUnexpectedValues(child, factory);

                    // Add to the list
                    spawnVessel.vessels.Add(vessel);
                }
                finally
                {
                    ConfigNodeUtil.SetCurrentDataNode(factory.dataNode);
                }
            }

            if (!configNode.HasNode("VESSEL"))
            {
                valid = false;
                LoggingUtil.LogError(factory, "SpawnVessel requires at least one VESSEL node.");
            }

            return valid ? spawnVessel : null;
        }
コード例 #27
0
ファイル: Utility.cs プロジェクト: Kramax/KramaxAutoPilot
 /// <summary>
 /// calculate current heading from plane normal vector
 /// </summary>
 public static double calculateTargetHeading(Vector3 direction, VesselData vdata)
 {
     Vector3 fwd = Vector3.Cross(direction, vdata.planetUp);
     double heading = Vector3.Angle(fwd, vdata.planetNorth) * Math.Sign(Vector3.Dot(fwd, vdata.planetEast));
     return heading.headingClamp(360);
 }
コード例 #28
0
        public static SpawnVessel Create(ConfigNode configNode, SpawnVesselFactory factory)
        {
            SpawnVessel spawnVessel = new SpawnVessel();

            ConfigNodeUtil.ParseValue<bool>(configNode, "deferVesselCreation", x => spawnVessel.deferVesselCreation = x, factory, false);

            bool valid = true;
            int index = 0;
            foreach (ConfigNode child in ConfigNodeUtil.GetChildNodes(configNode, "VESSEL"))
            {
                DataNode dataNode = new DataNode("VESSEL_" + index++, factory.dataNode, factory);
                try
                {
                    ConfigNodeUtil.SetCurrentDataNode(dataNode);

                    VesselData vessel = new VesselData();

                    // Get name
                    if (child.HasValue("name"))
                    {
                        valid &= ConfigNodeUtil.ParseValue<string>(child, "name", x => vessel.name = x, factory);
                    }

                    // Get craft details
                    if (child.HasValue("craftURL"))
                    {
                        valid &= ConfigNodeUtil.ParseValue<string>(child, "craftURL", x => vessel.craftURL = x, factory);
                    }
                    if (child.HasValue("craftPart"))
                    {
                        valid &= ConfigNodeUtil.ParseValue<AvailablePart>(child, "craftPart", x => vessel.craftPart = x, factory);
                    }
                    valid &= ConfigNodeUtil.AtLeastOne(child, new string[] { "craftURL", "craftPart" }, factory);

                    valid &= ConfigNodeUtil.ParseValue<string>(child, "flagURL", x => vessel.flagURL = x, factory, (string)null);
                    valid &= ConfigNodeUtil.ParseValue<VesselType>(child, "vesselType", x => vessel.vesselType = x, factory, VesselType.Ship);

                    // Use an expression to default - then it'll work for dynamic contracts
                    if (!child.HasValue("targetBody"))
                    {
                        child.AddValue("targetBody", "@/targetBody");
                    }
                    valid &= ConfigNodeUtil.ParseValue<CelestialBody>(child, "targetBody", x => vessel.body = x, factory);

                    // Get landed stuff
                    if (child.HasValue("pqsCity"))
                    {
                        string pqsCityStr = null;
                        valid &= ConfigNodeUtil.ParseValue<string>(child, "pqsCity", x => pqsCityStr = x, factory);
                        if (pqsCityStr != null)
                        {
                            try
                            {
                                vessel.pqsCity = vessel.body.GetComponentsInChildren<PQSCity>(true).Where(pqs => pqs.name == pqsCityStr).First();
                            }
                            catch (Exception e)
                            {
                                LoggingUtil.LogError(typeof(WaypointGenerator), "Couldn't load PQSCity with name '" + pqsCityStr + "'");
                                LoggingUtil.LogException(e);
                                valid = false;
                            }
                        }
                        valid &= ConfigNodeUtil.ParseValue<Vector3d>(child, "pqsOffset", x => vessel.pqsOffset = x, factory, new Vector3d());

                        // Don't expect these to load anything, but do it to mark as initialized
                        valid &= ConfigNodeUtil.ParseValue<double>(child, "lat", x => vessel.latitude = x, factory, 0.0);
                        valid &= ConfigNodeUtil.ParseValue<double>(child, "lon", x => vessel.longitude = x, factory, 0.0);

                        // Do load alt and height
                        valid &= ConfigNodeUtil.ParseValue<double?>(child, "alt", x => vessel.altitude = x, factory, (double?)null);
                        valid &= ConfigNodeUtil.ParseValue<float>(child, "height", x => vessel.height = x, factory,
                            !string.IsNullOrEmpty(vessel.craftURL) ? 0.0f : 2.5f);
                        vessel.orbiting = false;

                        // Generate PQS city coordinates
                        LoggingUtil.LogVerbose(factory, "Generating coordinates from PQS city for Vessel " + vessel.name);

                        // Translate by the PQS offset (inverse transform of coordinate system)
                        Vector3d position = vessel.pqsCity.transform.position;
                        Vector3d v = vessel.pqsOffset;
                        Vector3d i = vessel.pqsCity.transform.right;
                        Vector3d j = vessel.pqsCity.transform.forward;
                        Vector3d k = vessel.pqsCity.transform.up;
                        Vector3d offsetPos = new Vector3d(
                            (j.y * k.z - j.z * k.y) * v.x + (i.z * k.y - i.y * k.z) * v.y + (i.y * j.z - i.z * j.y) * v.z,
                            (j.z * k.x - j.x * k.z) * v.x + (i.x * k.z - i.z * k.x) * v.y + (i.z * j.x - i.x * j.z) * v.z,
                            (j.x * k.y - j.y * k.x) * v.x + (i.y * k.x - i.x * k.y) * v.y + (i.x * j.y - i.y * j.x) * v.z
                        );
                        offsetPos *= (i.x * j.y * k.z) + (i.y * j.z * k.x) + (i.z * j.x * k.y) - (i.z * j.y * k.x) - (i.y * j.x * k.z) - (i.x * j.z * k.y);
                        vessel.latitude = vessel.body.GetLatitude(position + offsetPos);
                        vessel.longitude = vessel.body.GetLongitude(position + offsetPos);
                    }
                    else if (child.HasValue("lat") && child.HasValue("lon"))
                    {
                        valid &= ConfigNodeUtil.ParseValue<double>(child, "lat", x => vessel.latitude = x, factory);
                        valid &= ConfigNodeUtil.ParseValue<double>(child, "lon", x => vessel.longitude = x, factory);
                        valid &= ConfigNodeUtil.ParseValue<double?>(child, "alt", x => vessel.altitude = x, factory, (double?)null);
                        valid &= ConfigNodeUtil.ParseValue<float>(child, "height", x => vessel.height = x, factory,
                            !string.IsNullOrEmpty(vessel.craftURL) ? 0.0f : 2.5f);
                        vessel.orbiting = false;
                    }
                    // Get orbit
                    else
                    {
                        valid &= ConfigNodeUtil.ParseValue<Orbit>(child, "ORBIT", x => vessel.orbit = x, factory);
                        vessel.orbiting = true;
                    }

                    valid &= ConfigNodeUtil.ParseValue<float>(child, "heading", x => vessel.heading = x, factory, 0.0f);
                    valid &= ConfigNodeUtil.ParseValue<float>(child, "pitch", x => vessel.pitch = x, factory, 0.0f);
                    valid &= ConfigNodeUtil.ParseValue<float>(child, "roll", x => vessel.roll = x, factory, 0.0f);

                    // Get additional flags
                    valid &= ConfigNodeUtil.ParseValue<bool>(child, "owned", x => vessel.owned = x, factory, false);

                    // Handle the CREW nodes
                    foreach (ConfigNode crewNode in ConfigNodeUtil.GetChildNodes(child, "CREW"))
                    {
                        int count = 1;
                        valid &= ConfigNodeUtil.ParseValue<int>(crewNode, "count", x => count = x, factory, 1);
                        for (int i = 0; i < count; i++)
                        {
                            CrewData cd = new CrewData();

                            // Read crew details
                            valid &= ConfigNodeUtil.ParseValue<string>(crewNode, "name", x => cd.name = x, factory, (string)null);
                            valid &= ConfigNodeUtil.ParseValue<bool>(crewNode, "addToRoster", x => cd.addToRoster = x, factory, true);

                            // Check for unexpected values
                            valid &= ConfigNodeUtil.ValidateUnexpectedValues(crewNode, factory);

                            // Add the record
                            vessel.crew.Add(cd);
                        }
                    }

                    // Check for unexpected values
                    valid &= ConfigNodeUtil.ValidateUnexpectedValues(child, factory);

                    // Add to the list
                    spawnVessel.vessels.Add(vessel);
                }
                finally
                {
                    ConfigNodeUtil.SetCurrentDataNode(factory.dataNode);
                }
            }

            if (!configNode.HasNode("VESSEL"))
            {
                valid = false;
                LoggingUtil.LogError(factory, "SpawnVessel requires at least one VESSEL node.");
            }

            return valid ? spawnVessel : null;
        }
コード例 #29
0
 public override HashSet<ProtoPartResourceSnapshot> HandleResource(Vessel v, VesselData data, HashSet<ProtoPartResourceSnapshot> modified)
 {
     return AddResource(data, resourceRate * TimeWarp.fixedDeltaTime, resourceName, modified);
 }
コード例 #30
0
        static void SpawnVessel(VesselData vesselData)
        {
            string gameDataDir = KSPUtil.ApplicationRootPath;

            if (vesselData.vesselType == VesselType.Ship)
            {
                vesselData.name = "abandoned ship " + UnityEngine.Random.Range(1000, 10000);
            }
            else
            {
                vesselData.name = "abandoned science station " + UnityEngine.Random.Range(1000, 10000);
            }
            vesselData.orbit                     = FlightGlobals.ActiveVessel.GetOrbit();
            vesselData.orbit.inclination         = UnityEngine.Random.Range(0, 360);
            vesselData.orbit.eccentricity        = UnityEngine.Random.Range(0, 0.3f);
            vesselData.orbit.semiMajorAxis       = UnityEngine.Random.Range(Convert.ToSingle(FlightGlobals.ActiveVessel.mainBody.Radius + FlightGlobals.ActiveVessel.mainBody.atmosphereDepth + 50000), Convert.ToSingle(FlightGlobals.ActiveVessel.mainBody.sphereOfInfluence));
            vesselData.orbit.LAN                 = UnityEngine.Random.Range(0, 360);
            vesselData.orbit.argumentOfPeriapsis = UnityEngine.Random.Range(0, 360);
            vesselData.orbit.meanAnomalyAtEpoch  = 0;
            ConfigNode[]  partNodes;
            ShipConstruct shipConstruct = null;
            float         lcHeight      = 0;
            ConfigNode    craftNode;
            ConfigNode    currentShip = ShipConstruction.ShipConfig;

            shipConstruct = ShipConstruction.LoadShip(vesselData.craftURL);
            craftNode     = ConfigNode.Load(vesselData.craftURL);
            lcHeight      = ConfigNode.ParseVector3(craftNode.GetNode("PART").GetValue("pos")).y;
            ShipConstruction.ShipConfig = currentShip;
            ConfigNode  empty       = new ConfigNode();
            ProtoVessel dummyProto  = new ProtoVessel(empty, null);
            Vessel      dummyVessel = new Vessel();

            dummyVessel.parts    = shipConstruct.parts;
            dummyProto.vesselRef = dummyVessel;
            uint missionID = (uint)Guid.NewGuid().GetHashCode();
            uint launchID  = HighLogic.CurrentGame.launchID++;

            foreach (Part p in shipConstruct.parts)
            {
                p.missionID   = missionID;
                p.launchID    = launchID;
                p.flightID    = ShipConstruction.GetUniqueFlightID(HighLogic.CurrentGame.flightState);
                p.temperature = 1.0;
                dummyProto.protoPartSnapshots.Add(new ProtoPartSnapshot(p, dummyProto));
            }
            foreach (ProtoPartSnapshot p in dummyProto.protoPartSnapshots)
            {
                p.storePartRefs();
            }
            List <ConfigNode> partNodesL = new List <ConfigNode>();

            foreach (var snapShot in dummyProto.protoPartSnapshots)
            {
                ConfigNode node = new ConfigNode("PART");
                snapShot.Save(node);
                partNodesL.Add(node);
            }
            partNodes = partNodesL.ToArray();
            ConfigNode[] additionalNodes = new ConfigNode[0];
            ConfigNode   protoVesselNode = ProtoVessel.CreateVesselNode(vesselData.name, vesselData.vesselType, vesselData.orbit, 0, partNodes, additionalNodes);
            ProtoVessel  protoVessel     = HighLogic.CurrentGame.AddVessel(protoVesselNode);

            vesselData.id = protoVessel.vesselRef.id;
            foreach (var p in FindObjectsOfType <Part>())
            {
                if (!p.vessel)
                {
                    Destroy(p.gameObject);
                }
            }
            if (vesselData.vesselType == VesselType.Ship)
            {
                setResourcesAmount(protoVessel.vesselRef);
            }
            if (vesselData.vesselType == VesselType.Station)
            {
                setScience(protoVessel.vesselRef);
            }
        }
コード例 #31
0
        private void SpawnVessel(VesselData vesselData, List <ProtoCrewMember> crewData = null)
        {
            string gameDataDir = KSPUtil.ApplicationRootPath;

            Debug.Log("Spawning a vessel named '" + vesselData.name + "'");

            // Set additional info for landed vessels
            bool landed = false;

            if (!vesselData.orbiting)
            {
                landed = true;
                if (vesselData.altitude == null || vesselData.altitude < 0)
                {
                    vesselData.altitude = 35;//LocationUtil.TerrainHeight(vesselData.latitude, vesselData.longitude, vesselData.body);
                }

                //Vector3d pos = vesselData.body.GetWorldSurfacePosition(vesselData.latitude, vesselData.longitude, vesselData.altitude.Value);
                Vector3d pos = vesselData.body.GetRelSurfacePosition(vesselData.latitude, vesselData.longitude, vesselData.altitude.Value);

                vesselData.orbit = new Orbit(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, vesselData.body);
                vesselData.orbit.UpdateFromStateVectors(pos, vesselData.body.getRFrmVel(pos), vesselData.body, Planetarium.GetUniversalTime());
            }
            else
            {
                vesselData.orbit.referenceBody = vesselData.body;
            }

            ConfigNode[] partNodes;
            //UntrackedObjectClass sizeClass;
            ShipConstruct shipConstruct = null;
            bool          hasClamp      = false;
            float         lcHeight      = 0;
            ConfigNode    craftNode;
            Quaternion    craftRotation = Quaternion.identity;

            if (!string.IsNullOrEmpty(vesselData.craftURL))
            {
                // Save the current ShipConstruction ship, otherwise the player will see the spawned ship next time they enter the VAB!
                ConfigNode currentShip = ShipConstruction.ShipConfig;

                shipConstruct = ShipConstruction.LoadShip(vesselData.craftURL);
                if (shipConstruct == null)
                {
                    Debug.Log("ShipConstruct was null when tried to load '" + vesselData.craftURL +
                              "' (usually this means the file could not be found).");
                    return;//continue;
                }

                craftNode     = ConfigNode.Load(vesselData.craftURL);
                lcHeight      = ConfigNode.ParseVector3(craftNode.GetNode("PART").GetValue("pos")).y;
                craftRotation = ConfigNode.ParseQuaternion(craftNode.GetNode("PART").GetValue("rot"));

                // Restore ShipConstruction ship
                ShipConstruction.ShipConfig = currentShip;

                // Set the name
                if (string.IsNullOrEmpty(vesselData.name))
                {
                    vesselData.name = shipConstruct.shipName;
                }

                // Set some parameters that need to be at the part level
                uint missionID = (uint)Guid.NewGuid().GetHashCode();
                uint launchID  = HighLogic.CurrentGame.launchID++;
                foreach (Part p in shipConstruct.parts)
                {
                    p.flightID  = ShipConstruction.GetUniqueFlightID(HighLogic.CurrentGame.flightState);
                    p.missionID = missionID;
                    p.launchID  = launchID;
                    p.flagURL   = vesselData.flagURL ?? HighLogic.CurrentGame.flagURL;

                    // Had some issues with this being set to -1 for some ships - can't figure out
                    // why.  End result is the vessel exploding, so let's just set it to a positive
                    // value.
                    p.temperature = 1.0;
                }

                //add minimal crew
                //bool success = false;
                Part part = shipConstruct.parts.Find(p => p.protoModuleCrew.Count < p.CrewCapacity);

                // Add the crew member
                if (part != null && VesselMoverToolbar.addCrewMembers)
                {
                    if (VesselMoverToolbar.selectCrewMembers)
                    {
                        ProtoCrewMember crewMember = crewData.FirstOrDefault();
                        if (crewMember != null)
                        {
                            part.AddCrewmemberAt(crewMember, part.protoModuleCrew.Count);
                        }
                        VesselMoverToolbar.SelectedCrewMembers.Clear();
                    }
                    else
                    {
                        // Create the ProtoCrewMember
                        ProtoCrewMember crewMember = HighLogic.CurrentGame.CrewRoster.GetNewKerbal();
                        crewMember.gender = UnityEngine.Random.Range(0, 100) > 50
              ? ProtoCrewMember.Gender.Female
              : ProtoCrewMember.Gender.Male;
                        //crewMember.trait = "Pilot";

                        // Add them to the part
                        part.AddCrewmemberAt(crewMember, part.protoModuleCrew.Count);
                    }
                }

                // Create a dummy ProtoVessel, we will use this to dump the parts to a config node.
                // We can't use the config nodes from the .craft file, because they are in a
                // slightly different format than those required for a ProtoVessel (seriously
                // Squad?!?).
                ConfigNode  empty       = new ConfigNode();
                ProtoVessel dummyProto  = new ProtoVessel(empty, null);
                Vessel      dummyVessel = new Vessel();
                dummyVessel.parts    = shipConstruct.Parts;
                dummyProto.vesselRef = dummyVessel;

                // Create the ProtoPartSnapshot objects and then initialize them
                foreach (Part p in shipConstruct.parts)
                {
                    dummyVessel.loaded = false;
                    p.vessel           = dummyVessel;

                    dummyProto.protoPartSnapshots.Add(new ProtoPartSnapshot(p, dummyProto, true));
                }
                foreach (ProtoPartSnapshot p in dummyProto.protoPartSnapshots)
                {
                    p.storePartRefs();
                }

                // Create the ship's parts

                List <ConfigNode> partNodesL = new List <ConfigNode>();
                foreach (ProtoPartSnapshot snapShot in dummyProto.protoPartSnapshots)
                {
                    ConfigNode node = new ConfigNode("PART");
                    snapShot.Save(node);
                    partNodesL.Add(node);
                }
                partNodes = partNodesL.ToArray();



                // Estimate an object class, numbers are based on the in game description of the
                // size classes.
                //float size = shipConstruct.shipSize.magnitude / 2.0f;
                //if (size < 4.0f)
                //{
                //  sizeClass = UntrackedObjectClass.A;
                //}
                //else if (size < 7.0f)
                //{
                //  sizeClass = UntrackedObjectClass.B;
                //}
                //else if (size < 12.0f)
                //{
                //  sizeClass = UntrackedObjectClass.C;
                //}
                //else if (size < 18.0f)
                //{
                //  sizeClass = UntrackedObjectClass.D;
                //}
                //else
                //{
                //  sizeClass = UntrackedObjectClass.E;
                //}
            }
            else
            {
                // Create crew member array
                ProtoCrewMember[] crewArray = new ProtoCrewMember[vesselData.crew.Count];
                int i = 0;
                foreach (CrewData cd in vesselData.crew)
                {
                    // Create the ProtoCrewMember
                    ProtoCrewMember crewMember = HighLogic.CurrentGame.CrewRoster.GetNewKerbal(ProtoCrewMember.KerbalType.Crew);
                    if (cd.name != null)
                    {
                        crewMember.KerbalRef.name = cd.name;
                    }

                    crewArray[i++] = crewMember;
                }

                // Create part nodes
                uint flightId = ShipConstruction.GetUniqueFlightID(HighLogic.CurrentGame.flightState);
                partNodes    = new ConfigNode[1];
                partNodes[0] = ProtoVessel.CreatePartNode(vesselData.craftPart.name, flightId, crewArray);

                // Default the size class
                //sizeClass = UntrackedObjectClass.A;

                // Set the name
                if (string.IsNullOrEmpty(vesselData.name))
                {
                    vesselData.name = vesselData.craftPart.name;
                }
            }

            // Create additional nodes
            ConfigNode[] additionalNodes = new ConfigNode[0];
            //DiscoveryLevels discoveryLevel = vesselData.owned ? DiscoveryLevels.Owned : DiscoveryLevels.Unowned;
            //additionalNodes[0] = ProtoVessel.CreateDiscoveryNode(discoveryLevel, sizeClass, contract.TimeDeadline, contract.TimeDeadline);

            // Create the config node representation of the ProtoVessel
            ConfigNode protoVesselNode = ProtoVessel.CreateVesselNode(vesselData.name, vesselData.vesselType, vesselData.orbit, 0, partNodes, additionalNodes);

            // Additional seetings for a landed vessel
            if (!vesselData.orbiting)
            {
                Vector3d norm = vesselData.body.GetRelSurfaceNVector(vesselData.latitude, vesselData.longitude);

                double terrainHeight = 0.0;
                if (vesselData.body.pqsController != null)
                {
                    terrainHeight = vesselData.body.pqsController.GetSurfaceHeight(norm) - vesselData.body.pqsController.radius;
                }
                bool splashed = false;// = landed && terrainHeight < 0.001;

                // Create the config node representation of the ProtoVessel
                // Note - flying is experimental, and so far doesn't work
                protoVesselNode.SetValue("sit", (splashed ? Vessel.Situations.SPLASHED : landed ?
                                                 Vessel.Situations.LANDED : Vessel.Situations.FLYING).ToString());
                protoVesselNode.SetValue("landed", (landed && !splashed).ToString());
                protoVesselNode.SetValue("splashed", splashed.ToString());
                protoVesselNode.SetValue("lat", vesselData.latitude.ToString());
                protoVesselNode.SetValue("lon", vesselData.longitude.ToString());
                protoVesselNode.SetValue("alt", vesselData.altitude.ToString());
                protoVesselNode.SetValue("landedAt", vesselData.body.name);

                // Figure out the additional height to subtract
                float lowest = float.MaxValue;
                if (shipConstruct != null)
                {
                    foreach (Part p in shipConstruct.parts)
                    {
                        foreach (Collider collider in p.GetComponentsInChildren <Collider>())
                        {
                            if (collider.gameObject.layer != 21 && collider.enabled)
                            {
                                lowest = Mathf.Min(lowest, collider.bounds.min.y);
                            }
                        }
                    }
                }
                else
                {
                    foreach (Collider collider in vesselData.craftPart.partPrefab.GetComponentsInChildren <Collider>())
                    {
                        if (collider.gameObject.layer != 21 && collider.enabled)
                        {
                            lowest = Mathf.Min(lowest, collider.bounds.min.y);
                        }
                    }
                }

                if (lowest == float.MaxValue)
                {
                    lowest = 0;
                }

                // Figure out the surface height and rotation
                Quaternion normal   = Quaternion.LookRotation((Vector3)norm);// new Vector3((float)norm.x, (float)norm.y, (float)norm.z));
                Quaternion rotation = Quaternion.identity;
                float      heading  = vesselData.heading;
                if (shipConstruct == null)
                {
                    rotation = rotation * Quaternion.FromToRotation(Vector3.up, Vector3.back);
                }
                else if (shipConstruct.shipFacility == EditorFacility.SPH)
                {
                    rotation = rotation * Quaternion.FromToRotation(Vector3.forward, -Vector3.forward);
                    heading += 180.0f;
                }
                else
                {
                    rotation = rotation * Quaternion.FromToRotation(Vector3.up, Vector3.forward);
                    rotation = Quaternion.FromToRotation(Vector3.up, -Vector3.up) * rotation;

                    //rotation = craftRotation;


                    vesselData.heading = 0;
                    vesselData.pitch   = 0;
                }

                rotation = rotation * Quaternion.AngleAxis(heading, Vector3.back);
                rotation = rotation * Quaternion.AngleAxis(vesselData.roll, Vector3.down);
                rotation = rotation * Quaternion.AngleAxis(vesselData.pitch, Vector3.left);

                // Set the height and rotation
                if (landed || splashed)
                {
                    float hgt = (shipConstruct != null ? shipConstruct.parts[0] : vesselData.craftPart.partPrefab).localRoot.attPos0.y - lowest;
                    hgt += vesselData.height;

                    foreach (Part p in shipConstruct.Parts)
                    {
                        LaunchClamp lc = p.FindModuleImplementing <LaunchClamp>();
                        if (lc)
                        {
                            hasClamp = true;
                            break;
                        }
                    }

                    if (!hasClamp)
                    {
                        hgt += 35;
                    }
                    else
                    {
                        hgt += lcHeight;
                    }
                    protoVesselNode.SetValue("hgt", hgt.ToString(), true);
                }
                protoVesselNode.SetValue("rot", KSPUtil.WriteQuaternion(normal * rotation), true);

                // Set the normal vector relative to the surface
                Vector3 nrm = (rotation * Vector3.forward);
                protoVesselNode.SetValue("nrm", nrm.x + "," + nrm.y + "," + nrm.z, true);

                protoVesselNode.SetValue("prst", false.ToString(), true);
            }

            // Add vessel to the game
            ProtoVessel protoVessel = HighLogic.CurrentGame.AddVessel(protoVesselNode);

            //protoVessel.vesselRef.transform.rotation = protoVessel.rotation;


            // Store the id for later use
            vesselData.id = protoVessel.vesselRef.id;

            //protoVessel.vesselRef.currentStage = 0;

            StartCoroutine(PlaceSpawnedVessel(protoVessel.vesselRef, !hasClamp));

            // Associate it so that it can be used in contract parameters
            //ContractVesselTracker.Instance.AssociateVessel(vesselData.name, protoVessel.vesselRef);



            //destroy prefabs
            foreach (Part p in FindObjectsOfType <Part>())
            {
                if (!p.vessel)
                {
                    Destroy(p.gameObject);
                }
            }
        }
コード例 #32
0
        protected override void OnLoad(ConfigNode configNode)
        {
            base.OnLoad(configNode);
            vesselsCreated = ConfigNodeUtil.ParseValue<bool>(configNode, "vesselsCreated");
            deferVesselCreation = ConfigNodeUtil.ParseValue<bool?>(configNode, "deferVesselCreation", (bool?)false).Value;

            foreach (ConfigNode child in configNode.GetNodes("VESSEL_DETAIL"))
            {
                // Read all the orbit data
                VesselData vd = new VesselData();
                vd.name = child.GetValue("name");
                vd.id = ConfigNodeUtil.ParseValue<Guid?>(child, "id", (Guid?)null);
                vd.craftURL = child.GetValue("craftURL");
                vd.flagURL = ConfigNodeUtil.ParseValue<string>(child, "flagURL", (string)null);
                vd.vesselType = ConfigNodeUtil.ParseValue<VesselType>(child, "vesselType");
                vd.body = ConfigNodeUtil.ParseValue<CelestialBody>(child, "body");
                vd.latitude = ConfigNodeUtil.ParseValue<double>(child, "lat");
                vd.longitude = ConfigNodeUtil.ParseValue<double>(child, "lon");
                vd.altitude = ConfigNodeUtil.ParseValue<double?>(child, "alt", (double?)null);
                vd.heading = ConfigNodeUtil.ParseValue<float>(child, "heading", 0.0f);
                vd.pitch = ConfigNodeUtil.ParseValue<float>(child, "pitch", 0.0f);
                vd.roll = ConfigNodeUtil.ParseValue<float>(child, "roll", 0.0f);
                vd.orbiting = ConfigNodeUtil.ParseValue<bool?>(child, "orbiting", (bool?)child.HasNode("ORBIT")).Value;
                vd.owned = ConfigNodeUtil.ParseValue<bool>(child, "owned");

                if (child.HasNode("ORBIT"))
                {
                    vd.orbit = new OrbitSnapshot(child.GetNode("ORBIT")).Load();
                }

                // Load crew data
                foreach (ConfigNode crewNode in child.GetNodes("CREW"))
                {
                    CrewData cd = new CrewData();

                    cd.name = ConfigNodeUtil.ParseValue<string>(crewNode, "name", (string)null);
                    cd.addToRoster = ConfigNodeUtil.ParseValue<bool>(crewNode, "addToRoster");

                    vd.crew.Add(cd);
                }

                // Add to the global list
                vessels.Add(vd);
            }
        }
コード例 #33
0
        public static Guid?CreateVessel(VesselData vesselData)
        {
            String gameDataDir = KSPUtil.ApplicationRootPath;

            gameDataDir = gameDataDir.Replace("\\", "/");
            if (!gameDataDir.EndsWith("/"))
            {
                gameDataDir += "/";
            }
            gameDataDir += "GameData";

            // Spawn the vessel in the game world
            // Set additional info for landed vessels
            bool landed = false;

            if (!vesselData.orbiting)
            {
                landed = true;
                if (vesselData.altitude == null)
                {
                    vesselData.altitude = TerrainHeight(vesselData.latitude, vesselData.longitude, vesselData.body);
                }

                Vector3d pos = vesselData.body.GetWorldSurfacePosition(vesselData.latitude, vesselData.longitude, vesselData.altitude.Value);

                vesselData.orbit = new Orbit(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, vesselData.body);
                vesselData.orbit.UpdateFromStateVectors(pos, vesselData.body.getRFrmVel(pos), vesselData.body, Planetarium.GetUniversalTime());
            }
            else
            {
                vesselData.orbit.referenceBody = vesselData.body;
            }
            ConfigNode[] partNodes;
            //UntrackedObjectClass sizeClass;
            ShipConstruct shipConstruct = null;

            if (vesselData.shipConstruct != null)
            {
                // Save the current ShipConstruction ship, otherwise the player will see the spawned ship next time they enter the VAB!
                //ConfigNode currentShip = ShipConstruction.ShipConfig;

                //shipConstruct = ShipConstruction.LoadShip(vesselData.craftURL);
                //if (shipConstruct == null)
                //{
                //    return false;
                //}

                // Restore ShipConstruction ship
                //ShipConstruction.ShipConfig = currentShip;

                shipConstruct = vesselData.shipConstruct;
                // Set the name
                if (string.IsNullOrEmpty(vesselData.name))
                {
                    vesselData.name = shipConstruct.shipName;
                }

                // Set some parameters that need to be at the part level
                uint missionID = (uint)Guid.NewGuid().GetHashCode();
                uint launchID  = HighLogic.CurrentGame.launchID++;
                foreach (Part p in shipConstruct.parts)
                {
                    p.flightID  = ShipConstruction.GetUniqueFlightID(HighLogic.CurrentGame.flightState);
                    p.missionID = missionID;
                    p.launchID  = launchID;
                    p.flagURL   = vesselData.flagURL ?? HighLogic.CurrentGame.flagURL;

                    // Had some issues with this being set to -1 for some ships - can't figure out
                    // why.  End result is the vessel exploding, so let's just set it to a positive
                    // value.
                    p.temperature = 1.0;
                }
                // Estimate an object class, numbers are based on the in game description of the
                // size classes.
                float size = shipConstruct.shipSize.magnitude / 2.0f;
                //if (size < 4.0f)
                //{
                //    sizeClass = UntrackedObjectClass.A;
                //}
                //else if (size < 7.0f)
                //{
                //    sizeClass = UntrackedObjectClass.B;
                //}
                //else if (size < 12.0f)
                //{
                //    sizeClass = UntrackedObjectClass.C;
                //}
                //else if (size < 18.0f)
                //{
                //    sizeClass = UntrackedObjectClass.D;
                //}
                //else
                //{
                //    sizeClass = UntrackedObjectClass.E;
                //}
                foreach (CrewData cd in vesselData.crew)
                {
                    bool success = false;

                    // Find a seat for the crew
                    Part part = shipConstruct.parts.Find(p => p.protoModuleCrew.Count < p.CrewCapacity);

                    // Add the crew member
                    if (part != null)
                    {
                        // Get the ProtoCrewMember
                        ProtoCrewMember crewMember = HighLogic.CurrentGame.CrewRoster.Crew.FirstOrDefault(pcm => pcm.name == cd.name);

                        // Add them to the part
                        success = part.AddCrewmemberAt(crewMember, part.protoModuleCrew.Count);
                    }

                    if (!success)
                    {
                        break;
                    }
                }
                // Create a dummy ProtoVessel, we will use this to dump the parts to a config node.
                // We can't use the config nodes from the .craft file, because they are in a
                // slightly different format than those required for a ProtoVessel.
                ConfigNode  empty       = new ConfigNode();
                ProtoVessel dummyProto  = new ProtoVessel(empty, null);
                Vessel      dummyVessel = new GameObject().AddComponent <Vessel>();
                dummyVessel.parts    = shipConstruct.parts;
                dummyProto.vesselRef = dummyVessel;
                // Create the ProtoPartSnapshot objects and then initialize them
                foreach (Part p in shipConstruct.parts)
                {
                    dummyProto.protoPartSnapshots.Add(new ProtoPartSnapshot(p, dummyProto));
                }
                foreach (ProtoPartSnapshot p in dummyProto.protoPartSnapshots)
                {
                    p.storePartRefs();
                }
                // Create the ship's parts
                partNodes = dummyProto.protoPartSnapshots.Select <ProtoPartSnapshot, ConfigNode>(GetNodeForPart).ToArray();

                // Clean up
                GameObject.Destroy(dummyVessel.gameObject);
            }
            else
            {
                // Create crew member array
                ProtoCrewMember[] crewArray = new ProtoCrewMember[vesselData.crew.Count];
                int i = 0;
                foreach (CrewData cd in vesselData.crew)
                {
                    // Create the ProtoCrewMember
                    ProtoCrewMember crewMember = HighLogic.CurrentGame.CrewRoster.GetNewKerbal(ProtoCrewMember.KerbalType.Unowned);
                    if (cd.name != null)
                    {
                        crewMember.ChangeName(cd.name);
                    }

                    crewArray[i++] = crewMember;
                }

                // Create part nodes
                uint flightId = ShipConstruction.GetUniqueFlightID(HighLogic.CurrentGame.flightState);
                partNodes    = new ConfigNode[1];
                partNodes[0] = ProtoVessel.CreatePartNode(vesselData.craftPart.name, flightId, crewArray);

                // Default the size class
                //sizeClass = UntrackedObjectClass.A;

                // Set the name
                if (string.IsNullOrEmpty(vesselData.name))
                {
                    vesselData.name = vesselData.craftPart.name;
                }
            }

            // Create additional nodes //not needed?
            //ConfigNode[] additionalNodes = new ConfigNode[1];
            //DiscoveryLevels discoveryLevel = vesselData.owned ? DiscoveryLevels.Owned : DiscoveryLevels.Unowned;
            //additionalNodes[0] = ProtoVessel.CreateDiscoveryNode(discoveryLevel, sizeClass, , contract.TimeDeadline);

            // Create the config node representation of the ProtoVessel
            ConfigNode protoVesselNode = ProtoVessel.CreateVesselNode(vesselData.name, vesselData.vesselType, vesselData.orbit, 0, partNodes);

            // Additional seetings for a landed vessel
            if (!vesselData.orbiting)
            {
                Vector3d norm = vesselData.body.GetRelSurfaceNVector(vesselData.latitude, vesselData.longitude);

                double terrainHeight = 0.0;
                if (vesselData.body.pqsController != null)
                {
                    terrainHeight = vesselData.body.pqsController.GetSurfaceHeight(norm) - vesselData.body.pqsController.radius;
                }
                bool splashed = landed && terrainHeight < 0.001;

                // Create the config node representation of the ProtoVessel
                // Note - flying is experimental, and so far doesn't work
                protoVesselNode.SetValue("sit", (splashed ? Vessel.Situations.SPLASHED : landed ?
                                                 Vessel.Situations.LANDED : Vessel.Situations.FLYING).ToString());
                protoVesselNode.SetValue("landed", (landed && !splashed).ToString());
                protoVesselNode.SetValue("splashed", splashed.ToString());
                protoVesselNode.SetValue("lat", vesselData.latitude.ToString());
                protoVesselNode.SetValue("lon", vesselData.longitude.ToString());
                protoVesselNode.SetValue("alt", vesselData.altitude.ToString());
                protoVesselNode.SetValue("landedAt", vesselData.body.name);

                // Figure out the additional height to subtract
                float lowest = float.MaxValue;
                if (shipConstruct != null)
                {
                    foreach (Part p in shipConstruct.parts)
                    {
                        foreach (Collider collider in p.GetComponentsInChildren <Collider>())
                        {
                            if (collider.gameObject.layer != 21 && collider.enabled)
                            {
                                lowest = Mathf.Min(lowest, collider.bounds.min.y);
                            }
                        }
                    }
                }
                else
                {
                    foreach (Collider collider in vesselData.craftPart.partPrefab.GetComponentsInChildren <Collider>())
                    {
                        if (collider.gameObject.layer != 21 && collider.enabled)
                        {
                            lowest = Mathf.Min(lowest, collider.bounds.min.y);
                        }
                    }
                }

                if (lowest == float.MaxValue)
                {
                    lowest = 0;
                }

                // Figure out the surface height and rotation
                Quaternion normal   = Quaternion.LookRotation(new Vector3((float)norm.x, (float)norm.y, (float)norm.z));
                Quaternion rotation = Quaternion.identity;
                float      heading  = vesselData.heading;
                if (shipConstruct == null)
                {
                    rotation = rotation * Quaternion.FromToRotation(Vector3.up, Vector3.back);
                }
                else if (shipConstruct.shipFacility == EditorFacility.SPH) //TODO: I need this for KCT
                {
                    rotation = rotation * Quaternion.FromToRotation(Vector3.forward, -Vector3.forward);
                    heading += 180.0f;
                }
                else
                {
                    rotation = rotation * Quaternion.FromToRotation(Vector3.up, Vector3.forward);
                }

                rotation = rotation * Quaternion.AngleAxis(vesselData.pitch, Vector3.right);
                rotation = rotation * Quaternion.AngleAxis(vesselData.roll, Vector3.down);
                rotation = rotation * Quaternion.AngleAxis(heading, Vector3.forward);

                // Set the height and rotation
                if (landed || splashed)
                {
                    float hgt = (shipConstruct != null ? shipConstruct.parts[0] : vesselData.craftPart.partPrefab).localRoot.attPos0.y - lowest;
                    hgt += vesselData.height;
                    protoVesselNode.SetValue("hgt", hgt.ToString());
                }
                protoVesselNode.SetValue("rot", KSPUtil.WriteQuaternion(rotation * normal));

                // Set the normal vector relative to the surface
                Vector3 nrm = (rotation * Vector3.forward);
                protoVesselNode.SetValue("nrm", nrm.x + "," + nrm.y + "," + nrm.z);

                protoVesselNode.SetValue("prst", false.ToString());
            }


            // Add vessel to the game
            ProtoVessel protoVessel = new ProtoVessel(protoVesselNode, HighLogic.CurrentGame);

            protoVessel.Load(HighLogic.CurrentGame.flightState);
            HighLogic.CurrentGame.flightState.protoVessels.Add(protoVessel);
            // Store the id for later use
            vesselData.id = protoVessel.vesselRef.id;
            // Associate it so that it can be used in contract parameters
            //ContractVesselTracker.Instance.AssociateVessel(vesselData.name, protoVessel.vesselRef);

            return(vesselData.id);
        }
コード例 #34
0
        public void Reset(
            VesselData vessel_data,
            double altitude_step,
            double velocity_step, double velocity_max,
            double aoa,
            bool init_simple = true)
        {
            double aoa_cos = Math.Cos(aoa);
            double aoa_sin = Math.Sin(aoa);

            double altitude_max;

            if (body_.HasAtmosphere)
            {
                altitude_max = body_.AtmosphereDepth;
            }
            else
            {
                altitude_max  = 1d;
                altitude_step = 1d;
            }

            uint altitude_n = (uint)Math.Ceiling(altitude_max / altitude_step);
            uint velocity_n = (uint)Math.Ceiling(velocity_max / velocity_step);

            var    flight = vessel_.Flight(body_.ReferenceFrame);
            double radius = body_.EquatorialRadius;

            /*var stream_pos = conn_.AddStream(() => vessel_.Position(body_.ReferenceFrame));
             * var stream_backward = conn_.AddStream(() => sc_.TransformDirection(
             *  new Tuple<double, double, double>(0, -1, 0),
             *  vessel_.ReferenceFrame, body_.ReferenceFrame));
             * var stream_right = conn_.AddStream(() => sc_.TransformDirection(
             *  new Tuple<double, double, double>(1, 0, 0),
             *  vessel_.ReferenceFrame, body_.ReferenceFrame));*/

            atm_ = new LinearTable(
                0d, altitude_step, altitude_n,
                (double altitude) =>
            {
                double atm = body_.PressureAt(altitude) / Constants.Common.STANDARD_ATMOSPHERIC_PRESSURE;
                return(atm);
            },
                init_simple);

            available_thrust_ = new LinearTable(
                0d, altitude_step, altitude_n,
                (double altitude) =>
            {
                double atm = atm_[altitude];
                double thr = vessel_.AvailableThrustAt(atm);
                return(thr);
            },
                init_simple);

            density_ = new LinearTable(
                0d, altitude_step, altitude_n,
                (double altitude) =>
            {
                double density = body_.DensityAt(altitude);
                return(density);
            },
                init_simple);

            sim_drift_ = new BiLinearTable(
                0d, altitude_step, altitude_n,
                0d, velocity_step, velocity_n,
                (double altitude, double velocity) =>
            {
                /*Vector3d pos_now = new Vector3d(stream_pos.Get());
                 * Vector3d backward = new Vector3d(stream_backward.Get());*/
                Vector3d pos          = vessel_data.Vessel.Position.Norm() * (radius + altitude);
                Vector3d vel_backward = -velocity * vessel_data.Vessel.Forward;
                var sim = flight.SimulateAerodynamicForceAt(body_, pos.ToTuple(), vel_backward.ToTuple());
                return(new Vector3d(sim).Length());
            });

            sim_lift_ = new BiLinearTable(
                0d, altitude_step, altitude_n,
                0d, velocity_step, velocity_n,
                (double altitude, double velocity) =>
            {
                /*Vector3d pos_now = new Vector3d(stream_pos.Get());
                *  Vector3d backward = new Vector3d(stream_backward.Get());
                *  Vector3d right = new Vector3d(stream_right.Get());*/
                Vector3d pos          = vessel_data.Vessel.Position.Norm() * (radius + altitude);
                Vector3d vel_backward = -velocity * vessel_data.Vessel.Forward;
                Vector3d vel_tilt     = velocity * (vessel_data.Vessel.Right * aoa_sin - vessel_data.Vessel.Forward * aoa_cos);
                var sim = flight.SimulateAerodynamicForceAt(body_, pos.ToTuple(), vel_tilt.ToTuple());
                return(-(new Vector3d(sim) * vessel_data.Vessel.Right));
            });
        }