コード例 #1
0
            public ODSTVesselData(ODSTVesselData 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));
                }
            }
コード例 #2
0
        private void SpawnVesselFromCraftFile(string craftURL, Vector3d gpsCoords, float heading, float pitch, List <ProtoCrewMember> crewData = null)
        {
            ODSTVesselData newData = new ODSTVesselData();

            var _random = new System.Random().Next(0, 10);
            var random  = _random / 5;

            if (_random <= 5)
            {
                _lat_ = random / 1000;
                _lon_ = random / 1000;
            }
            else
            {
                _lat_ = random / -1000;
                _lon_ = random / -1000;
            }

            newData.craftURL  = craftURL;
            newData.latitude  = gpsCoords.x + _lat_;
            newData.longitude = gpsCoords.y + _lon_;
            newData.altitude  = gpsCoords.z + 10000;

            Debug.Log("[Spawn OrX ODST] SpawnVesselFromCraftFile Altitude: " + newData.altitude);

            newData.body     = FlightGlobals.currentMainBody;
            newData.heading  = heading;
            newData.pitch    = pitch;
            newData.orbiting = false;

            newData.flagURL    = flagURL;
            newData.owned      = true;
            newData.vesselType = VesselType.SpaceObject;
            newData.crew       = new List <CrewData>();

            SpawnVessel(newData, crewData);
        }
コード例 #3
0
        private void SpawnVessel(ODSTVesselData ODSTVesselData, List <ProtoCrewMember> crewData = null)
        {
            //      string gameDataDir = KSPUtil.ApplicationRootPath;
            Debug.Log("[Spawn OrX ODST] Spawning ODST Enemey: " + ODSTVesselData.name);

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

            if (!landed)
            {
                landed = true;
                if (ODSTVesselData.altitude == null || ODSTVesselData.altitude < 0)
                {
                    if (FlightGlobals.ActiveVessel.LandedOrSplashed)
                    {
                        var _random = new System.Random().Next(4000, 6000);
                        var random  = _random + FlightGlobals.ActiveVessel.altitude;

                        ODSTVesselData.altitude = random;//LocationUtil.TerrainHeight(ODSTVesselData.latitude, ODSTVesselData.longitude, ODSTVesselData.body);
                    }
                    else
                    {
                        var _random = new System.Random().Next(4000, 8000);
                        //var random = _random + FlightGlobals.ActiveVessel.altitude;

                        ODSTVesselData.altitude = _random;
                    }
                }
                Debug.Log("[Spawn OrX ODST] SpawnVessel Altitude: " + ODSTVesselData.altitude);

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

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

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

            if (!string.IsNullOrEmpty(ODSTVesselData.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(ODSTVesselData.craftURL);
                if (shipConstruct == null)
                {
                    Debug.Log("[Spawn OrX ODST] ShipConstruct was null when tried to load '" + ODSTVesselData.craftURL +
                              "' (usually this means the file could not be found).");
                    return;//continue;
                }

                craftNode     = ConfigNode.Load(ODSTVesselData.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(ODSTVesselData.name))
                {
                    ODSTVesselData.name = "OrX ODST Enemy";
                }

                // 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;
                    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;

                // 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 (ProtoPartSnapshot snapShot in dummyProto.protoPartSnapshots)
                {
                    ConfigNode node = new ConfigNode("PART");
                    snapShot.Save(node);
                    partNodesL.Add(node);
                }
                partNodes = partNodesL.ToArray();
            }
            else
            {
                // Create crew member array
                ProtoCrewMember[] crewArray = new ProtoCrewMember[ODSTVesselData.crew.Count];

                int i = 0;
                foreach (CrewData cd in ODSTVesselData.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(ODSTVesselData.craftPart.name, flightId, crewArray);

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

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

            // Create additional nodes
            ConfigNode[] additionalNodes = new ConfigNode[0];
            //DiscoveryLevels discoveryLevel = ODSTVesselData.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(ODSTVesselData.name, ODSTVesselData.vesselType, ODSTVesselData.orbit, 0, partNodes, additionalNodes);

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

                double terrainHeight = 0.0;
                if (ODSTVesselData.body.pqsController != null)
                {
                    terrainHeight = ODSTVesselData.body.pqsController.GetSurfaceHeight(norm) - ODSTVesselData.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", ODSTVesselData.latitude.ToString());
                protoVesselNode.SetValue("lon", ODSTVesselData.longitude.ToString());
                protoVesselNode.SetValue("alt", ODSTVesselData.altitude.ToString());
                protoVesselNode.SetValue("landedAt", ODSTVesselData.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 ODSTVesselData.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;
                 * }
                 */

                float 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  = ODSTVesselData.heading;
                if (shipConstruct == null)
                {
                    rotation = rotation * Quaternion.FromToRotation(Vector3.up, Vector3.back);
                }
                else
                {
                    rotation = rotation * Quaternion.FromToRotation(Vector3.forward, -Vector3.forward);
                    heading += 180.0f;
                }

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

                // Set the height and rotation
                float hgt = (shipConstruct != null ? shipConstruct.parts[0] : ODSTVesselData.craftPart.partPrefab).localRoot.attPos0.y - lowest;
                hgt += ODSTVesselData.height;
                protoVesselNode.SetValue("hgt", hgt.ToString(), true);

                Debug.Log("[Spawn OrX ODST] SpawnVessel setting vessel height in protovessel: " + hgt);

                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);

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

            //protoVessel.vesselRef.currentStage = 0;
            hasClamp = false;

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

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


            //destroy prefabs
            foreach (Part p in FindObjectsOfType <Part>())
            {
                if (!p.vessel)
                {
                    Destroy(p.gameObject);
                }
            }
        }