public WaldoAttackVesselData(WaldoAttackVesselData 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)); } }
private void SpawnVesselFromCraftFile(string craftURL, Vector3d gpsCoords, float heading, float pitch, List <ProtoCrewMember> crewData = null) { WaldoAttackVesselData newData = new WaldoAttackVesselData(); newData.craftURL = craftURL; newData.latitude = gpsCoords.x + _lat_; newData.longitude = gpsCoords.y + _lon_; newData.altitude = gpsCoords.z + 5; Debug.Log("[Spawn OrX Waldo Attack] 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; SpawnVessel(newData, crewData); }
private void SpawnVessel(WaldoAttackVesselData WaldoAttackVesselData, List <ProtoCrewMember> crewData = null) { // string gameDataDir = KSPUtil.ApplicationRootPath; Debug.Log("[Spawn OrX Waldo Attack] Spawning " + WaldoAttackVesselData.name); // Set additional info for landed vessels bool landed = false; if (!landed) { landed = true; if (WaldoAttackVesselData.altitude == null || WaldoAttackVesselData.altitude < 0) { WaldoAttackVesselData.altitude = 5;//LocationUtil.TerrainHeight(WaldoAttackVesselData.latitude, WaldoAttackVesselData.longitude, WaldoAttackVesselData.body); } Debug.Log("[Spawn OrX Waldo Attack] SpawnVessel Altitude: " + WaldoAttackVesselData.altitude); //Vector3d pos = WaldoAttackVesselData.body.GetWorldSurfacePosition(WaldoAttackVesselData.latitude, WaldoAttackVesselData.longitude, WaldoAttackVesselData.altitude.Value); Vector3d pos = WaldoAttackVesselData.body.GetRelSurfacePosition(WaldoAttackVesselData.latitude, WaldoAttackVesselData.longitude, WaldoAttackVesselData.altitude.Value); WaldoAttackVesselData.orbit = new Orbit(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, WaldoAttackVesselData.body); WaldoAttackVesselData.orbit.UpdateFromStateVectors(pos, WaldoAttackVesselData.body.getRFrmVel(pos), WaldoAttackVesselData.body, Planetarium.GetUniversalTime()); } ConfigNode[] partNodes; ShipConstruct shipConstruct = null; bool hasClamp = false; float lcHeight = 0; ConfigNode craftNode; Quaternion craftRotation = Quaternion.identity; if (!string.IsNullOrEmpty(WaldoAttackVesselData.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(WaldoAttackVesselData.craftURL); if (shipConstruct == null) { Debug.Log("[Spawn OrX Waldo Attack] ShipConstruct was null when tried to load '" + WaldoAttackVesselData.craftURL + "' (usually this means the file could not be found)."); return;//continue; } craftNode = ConfigNode.Load(WaldoAttackVesselData.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(WaldoAttackVesselData.name)) { WaldoAttackVesselData.name = WaldoVesselName; ; } // 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 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 (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[WaldoAttackVesselData.crew.Count]; /* * int i = 0; * foreach (CrewData cd in WaldoAttackVesselData.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(WaldoAttackVesselData.craftPart.name, flightId, crewArray); // Default the size class //sizeClass = UntrackedObjectClass.A; // Set the name if (string.IsNullOrEmpty(WaldoAttackVesselData.name)) { WaldoAttackVesselData.name = WaldoAttackVesselData.craftPart.name; } } // Create additional nodes ConfigNode[] additionalNodes = new ConfigNode[0]; //DiscoveryLevels discoveryLevel = WaldoAttackVesselData.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(WaldoAttackVesselData.name, WaldoAttackVesselData.vesselType, WaldoAttackVesselData.orbit, 0, partNodes, additionalNodes); // Additional seetings for a landed vessel if (!WaldoAttackVesselData.orbiting) { Vector3d norm = WaldoAttackVesselData.body.GetRelSurfaceNVector(WaldoAttackVesselData.latitude, WaldoAttackVesselData.longitude); double terrainHeight = 0.0; if (WaldoAttackVesselData.body.pqsController != null) { terrainHeight = WaldoAttackVesselData.body.pqsController.GetSurfaceHeight(norm) - WaldoAttackVesselData.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", WaldoAttackVesselData.latitude.ToString()); protoVesselNode.SetValue("lon", WaldoAttackVesselData.longitude.ToString()); protoVesselNode.SetValue("alt", WaldoAttackVesselData.altitude.ToString()); protoVesselNode.SetValue("landedAt", WaldoAttackVesselData.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 WaldoAttackVesselData.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 = WaldoAttackVesselData.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; WaldoAttackVesselData.heading = 0; WaldoAttackVesselData.pitch = 0; } rotation = rotation * Quaternion.AngleAxis(heading, Vector3.back); rotation = rotation * Quaternion.AngleAxis(WaldoAttackVesselData.roll, Vector3.down); rotation = rotation * Quaternion.AngleAxis(WaldoAttackVesselData.pitch, Vector3.left); // Set the height and rotation if (landed || splashed) { float hgt = (shipConstruct != null ? shipConstruct.parts[0] : WaldoAttackVesselData.craftPart.partPrefab).localRoot.attPos0.y - lowest; hgt += WaldoAttackVesselData.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 WaldoAttackVesselData.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(WaldoAttackVesselData.name, protoVessel.vesselRef); //destroy prefabs foreach (Part p in FindObjectsOfType <Part>()) { if (!p.vessel) { Destroy(p.gameObject); } } }