private static void AddModule(ConfigNode configNode, StaticObject staticObject) { string namespaceName = configNode.GetValue("namespace"); string className = configNode.GetValue("name"); if (string.IsNullOrEmpty(namespaceName) || string.IsNullOrEmpty(className)) { Extensions.LogError( string.Format( "Could not add a module to the static object because the node has no name{0} parameter.", string.IsNullOrEmpty(namespaceName) ? "space" : "")); return; } if (namespaceName == "KerbTown") { AddNativeComponent(staticObject.StaticGameObject, configNode, className); return; } Type moduleClass = AssemblyLoader.loadedAssemblies.SelectMany(asm => asm.assembly.GetTypes()) .FirstOrDefault(t => t.Namespace == namespaceName && t.Name == className); if (moduleClass == null) { Extensions.LogError("Could not obtain module of type \"" + namespaceName + "." + className + "\" from AssemblyLoader."); return; } var moduleComponent = staticObject.StaticGameObject.AddComponent(moduleClass) as MonoBehaviour; if (moduleComponent == null) { Extensions.LogError("Could not add the obtained module \"" + moduleClass.Name + "\" to the static game object."); return; } // Assign variables specified in the config for the module. AssignVariables(configNode, moduleComponent); // Add the module to the module list. Creating the list if it hasn't been created already. if (staticObject.ModuleList == null) staticObject.ModuleList = new List<KtComponent>(); staticObject.ModuleList.Add(new KtComponent(moduleComponent)); }
private void DrawAvailAssetWindow(int windowID) { GUI.Box(new Rect(10, 30, 580, 290), ""); _availAssetScrollPos = GUI.BeginScrollView(new Rect(10, 30, 580, 290), _availAssetScrollPos, new Rect(0, 0, 560, _modelList.Count * 28 + 5)); int i = 0; // Model = ModelURL // Model[x] = ConfigURL foreach (string model in _modelList.Keys) { bool itemMatches = (model == _currentModelUrl); GUI.backgroundColor = new Color(0.3f, itemMatches ? 1f : 0.3f, 0.3f); if (GUI.Button(new Rect(5, (i * 28) + 5, 550, 25), itemMatches ? string.Format("[ {0} ]", model) : model)) { _currentModelUrl = itemMatches ? "" : model; // Select / Deselect _currentConfigUrl = _currentConfigUrl == _modelList[model] ? "" : _modelList[model]; } i++; } GUI.EndScrollView(); GUI.Label(new Rect(20, 330, 300, 25), "Current body: " + _currentBodyName); GUI.backgroundColor = new Color(0.0f, _currentModelUrl != "" ? 0.7f : 0.0f, 0.0f); if (GUI.Button(new Rect(480, 330, 100, 30), "Create") && _currentModelUrl != "") { // Clear old vis/position/scale info. //_visRange = _xScale = _yScale = _zScale = _xPosition = _rPosition = _yPosition = _zPosition = ""; _visRange = _xPosition = _rPosition = _yPosition = _zPosition = ""; // Set the current celestial object. (Needs to be set before GetDefaultStaticObject). _currentBodyName = FlightGlobals.ActiveVessel.mainBody.bodyName; _currentCelestialObj = GetCelestialObject(_currentBodyName); StaticObject newObject = GetDefaultStaticObject(_currentModelUrl, _currentConfigUrl); if (_instancedList.ContainsKey(_currentModelUrl)) { _instancedList[_currentModelUrl].Add(newObject); } else { _instancedList.Add(_currentModelUrl, new List <StaticObject> { newObject }); } newObject.CelestialBodyName = _currentCelestialObj.CelestialBodyComponent.name; // _currentCelestialObj assigned above. InstantiateStatic(_currentCelestialObj.PQSComponent, newObject, true); // Remove previously highlighted object if there is one. if (_currentSelectedObject != null) { _currentSelectedObject.Manipulate(false); } _currentObjectID = newObject.ObjectID; _currentSelectedObject = newObject; // Highlight new selected object. if (_currentSelectedObject != null) { _currentSelectedObject.Manipulate(true); } } GUI.backgroundColor = new Color(0.5f, 0.5f, 0.5f); if (GUI.Button(new Rect(410, 335, 60, 25), "Close")) { _availAssetsVisible = false; } GUI.DragWindow(new Rect(0, 0, 10000, 10000)); }
private void InstantiateStatic(PQS celestialPQS, StaticObject stObject, bool freshObject = false) { #region Staitc Object Core Parameters float visibilityRange = stObject.VisRange; float localRotationAngle = stObject.RotAngle; float radiusOffset = stObject.RadOffset; string modelUrl = stObject.ModelUrl; Vector3 orientDirection = stObject.Orientation; Vector3 radialPosition = stObject.RadPosition; if (radialPosition == Vector3.zero) { radialPosition = _currentCelestialObj.CelestialBodyComponent.transform.InverseTransformPoint( FlightGlobals.ActiveVessel.transform.position); stObject.RadPosition = radialPosition; } if (orientDirection == Vector3.zero) { orientDirection = Vector3.up; stObject.Orientation = orientDirection; } stObject.Latitude = GetLatitude(radialPosition); stObject.Longitude = GetLongitude(radialPosition); #endregion // Instantiate GameObject ktGameObject = GameDatabase.Instance.GetModel(modelUrl); // Add the reference component. var soModule = ktGameObject.AddComponent<StaticObjectModule>(); // Active the game object. ktGameObject.SetActive(true); // Set objects to layer 15 so that they collide correctly with Kerbals. SetLayerRecursively(ktGameObject, 15); // Set the parent object to the celestial component's GameObject. ktGameObject.transform.parent = celestialPQS.transform; // Obtain all active transforms in the static game object. Transform[] gameObjectList = ktGameObject.GetComponentsInChildren<Transform>(); // Create a list of renderers to be manipulated by the default PQSCity class. List<GameObject> rendererList = (from t in gameObjectList where t.gameObject.renderer != null select t.gameObject).ToList(); // Create the LOD range. _myLodRange = new PQSCity.LODRange { renderers = rendererList.ToArray(), objects = new GameObject[0], //new[] {staticGameObject}, // Todo: change to GameObject children. visibleRange = visibilityRange }; // Add the PQSCity class (extended by KerbTown). var myCity = ktGameObject.AddComponent<PQSCityEx>(); // Assign PQSCity variables. myCity.lod = new[] {_myLodRange}; myCity.frameDelta = 1; myCity.repositionToSphere = true; myCity.repositionToSphereSurface = false; myCity.repositionRadial = radialPosition; myCity.repositionRadiusOffset = radiusOffset; myCity.reorientFinalAngle = localRotationAngle; myCity.reorientToSphere = true; myCity.reorientInitialUp = orientDirection; myCity.sphere = celestialPQS; myCity.order = 100; myCity.modEnabled = true; // Assign custom variables. myCity.StaticObjectRef = stObject; // Setup and orientate the PQSCity instanced object. myCity.OnSetup(); myCity.Orientate(); // If the object was instantiated by "Create", override all renderers to active. if (freshObject) { foreach (GameObject renObj in rendererList) renObj.renderer.enabled = true; } // Add component references to the static object. stObject.PQSCityComponent = myCity; stObject.StaticGameObject = ktGameObject; //stObject.ModuleReference = soModule; // Add the static object as a reference to the StaticObjectModule soModule.StaticObjectRef = stObject; // Add remaining modules. switch (stObject.ObjectID) { case "MushroomCave": AddNativeComponent(ktGameObject, typeof (MushroomCave)); break; case "PurplePathway": AddNativeComponent(ktGameObject, typeof (PurplePathway)); break; default: AddModuleComponents(stObject); break; } // Alter the Launch Site spawn object name if necessary. // Todo: optimize if (stObject.LaunchSiteName != "") { Transform launchSiteObject = ktGameObject.transform.Cast<Transform>().FirstOrDefault(t => t.name.EndsWith("_spawn")); if (launchSiteObject != null) { launchSiteObject.name = stObject.LaunchSiteName + "_spawn"; } else { Extensions.LogWarning("Launch Site '" + ktGameObject.name + "'does not have a spawn transform."); } } }
private void InstantiateEasterEggs() { var configDict = new Dictionary<string, string> { {"Hubs/Static/KerbTown/EE01/EE01", "MushroomCave"}, {"Hubs/Static/KerbTown/EE02/EE02", "PurplePathway"} }; _eeInstancedList = new Dictionary<string, List<StaticObject>>(configDict.Count); foreach (var configItem in configDict) { ConfigNode staticUrlConfig = GameDatabase.Instance.GetConfigNode(configItem.Key); if (staticUrlConfig == null) continue; string model = staticUrlConfig.GetValue("mesh"); if (string.IsNullOrEmpty(model)) { Extensions.LogError("Missing 'mesh' parameter for " + configItem); continue; } model = model.Substring(0, model.LastIndexOf('.')); string modelUrl = configItem.Key.Substring(0, configItem.Key.SecondLastIndex('/')) + "/" + model; // TODO: Instantiate through code rather than config. foreach (ConfigNode ins in staticUrlConfig.GetNodes("Instances")) { Vector3 radPosition = ConfigNode.ParseVector3(ins.GetValue("RadialPosition")); float rotAngle = float.Parse(ins.GetValue("RotationAngle")); float radOffset = float.Parse(ins.GetValue("RadiusOffset")); Vector3 orientation = ConfigNode.ParseVector3(ins.GetValue("Orientation")); float visRange = float.Parse(ins.GetValue("VisibilityRange")); string celestialBodyName = ins.GetValue("CelestialBody"); //string scaleStr = "";//ins.GetValue("Scale"); //Vector3 scale = ConfigNode.ParseVector3(string.IsNullOrEmpty(scaleStr) ? "1,1,1" : scaleStr); //var staticObject = new StaticObject(radPosition, rotAngle, radOffset, orientation, // visRange, modelUrl, configItem.Key, celestialBodyName, scale, configItem.Value); var staticObject = new StaticObject(radPosition, rotAngle, radOffset, orientation, visRange, modelUrl, configItem.Key, celestialBodyName, configItem.Value); if (_eeInstancedList.ContainsKey(modelUrl)) _instancedList[modelUrl].Add(staticObject); else _eeInstancedList.Add(modelUrl, new List<StaticObject> {staticObject}); InstantiateStatic( (_currentCelestialObj = GetCelestialObject(staticObject.CelestialBodyName)).PQSComponent, staticObject); } } }
private void AddModuleComponents(StaticObject staticObject) { Stopwatch stopWatch = Stopwatch.StartNew(); string rootNodeUrl = staticObject.ConfigURL; ConfigNode rootNode = GameDatabase.Instance.GetConfigNode(rootNodeUrl); IEnumerator nodeEnum = rootNode.nodes.GetEnumerator(); while (nodeEnum.MoveNext()) { var currentNode = (ConfigNode) nodeEnum.Current; if (currentNode == null) continue; name = currentNode.name; if (name == null) continue; var moduleTypes = new Dictionary<string, int> {{"MODULE", 0}, {"RESOURCE", 1}, {"RIGIDBODY", 2}}; int nodeType; if (!moduleTypes.TryGetValue(name, out nodeType)) continue; switch (nodeType) { case 0: // Module AddModule(currentNode, staticObject); break; case 1: // Resource // Not used any more. break; case 2: // Rigidbody AddRigidBody(currentNode, staticObject.StaticGameObject); break; } } stopWatch.Stop(); Extensions.LogInfo("Modules loaded for " + staticObject.NameID + ". (" + stopWatch.ElapsedMilliseconds + "ms)"); }
private static void InvokeSetup(StaticObject staticObject) { if (staticObject.ModuleList == null) return; // Loop incase the content creator has decided to add multiple SOM's. foreach (KtComponent module in staticObject.ModuleList.Where (module => module.ModuleComponent.GetType() == typeof (StaticObjectModule))) { ((StaticObjectModule) module.ModuleComponent).OnFirstSetup(); } }
private static void DestroySoInstance(StaticObject staticObject) { try { staticObject.PQSCityComponent.modEnabled = false; foreach (PQSCity.LODRange lod in staticObject.PQSCityComponent.lod) { lod.SetActive(false); foreach (GameObject lodren in lod.renderers) Destroy(lodren); foreach (GameObject lodobj in lod.objects) Destroy(lodobj); } if (staticObject.ModuleList != null) { foreach (KtComponent module in staticObject.ModuleList.Where (module => module.ModuleComponent.GetType() == typeof (StaticObjectModule))) { ((StaticObjectModule) module.ModuleComponent).OnUnload(); } } staticObject.StaticGameObject.transform.parent = null; Destroy(staticObject.PQSCityComponent); DestroyImmediate(staticObject.StaticGameObject); } catch (Exception ex) { Extensions.LogError("An exception was caught while destroying a static object."); Debug.LogException(ex); } }