예제 #1
0
            /**
             * Generates the system prefab from the configuration
             * @return System prefab object
             **/
            public PSystem Generate()
            {
                // Dictionary of bodies generated
                Dictionary <string, Body> bodies = new Dictionary <string, Body> ();

                // Retrieve the root config node
                ConfigNode rootConfig = GameDatabase.Instance.GetConfigs(rootNodeName) [0].config;

                // Stage 1 - Load all of the bodies
                foreach (ConfigNode bodyNode in rootConfig.GetNodes(bodyNodeName))
                {
                    // Load this body from the
                    Body body = Parser.CreateObjectFromConfigNode <Body> (bodyNode);
                    bodies.Add(body.name, body);

                    Debug.Log("[Kopernicus]: Configuration.Loader: Loaded Body: " + body.name);
                }

                // Stage 2 - create a new planetary system object
                GameObject gameObject = new GameObject("Kopernicus");

                gameObject.transform.parent = Utility.Deactivator;
                PSystem system = gameObject.AddComponent <PSystem> ();

                // Set the planetary system defaults (pulled from PSystemManager.Instance.systemPrefab)
                system.systemName          = "Kopernicus";
                system.systemTimeScale     = 1.0;
                system.systemScale         = 1.0;
                system.mainToolbarSelected = 2;                   // initial value in stock systemPrefab. Unknown significance.

                // Stage 3 - Glue all the orbits together in the defined pattern
                foreach (KeyValuePair <string, Body> body in bodies)
                {
                    // If this body is in orbit around another body
                    if (body.Value.referenceBody != null)
                    {
                        // Get the Body object for the reference body
                        Body parent = null;
                        if (!bodies.TryGetValue(body.Value.referenceBody, out parent))
                        {
                            throw new Exception("\"" + body.Value.referenceBody + "\" not found.");
                        }

                        // Setup the orbit of the body
                        parent.generatedBody.children.Add(body.Value.generatedBody);
                        body.Value.generatedBody.orbitDriver.referenceBody       = parent.generatedBody.celestialBody;
                        body.Value.generatedBody.orbitDriver.orbit.referenceBody = parent.generatedBody.celestialBody;
                    }

                    // Parent the generated body to the PSystem
                    body.Value.generatedBody.transform.parent = system.transform;
                }

                // Stage 4 - elect root body
                system.rootBody = bodies.First(p => p.Value.referenceBody == null).Value.generatedBody;

                // Stage 5 - sort by distance from parent (discover how this effects local bodies)
                RecursivelySortBodies(system.rootBody);
                return(system);
            }
예제 #2
0
        bool SystemTurretPlacementRequest(IArea currentArea, Player player, int turretID, ref float xPos, ref float yPos, out string resultMessage)
        {
            if (currentArea.AreaType != AreaTypes.System)
            {
                resultMessage = "Not in a system.";//Client shouldn't ever see this...
                return(false);
            }

            PSystem system = ((PSystem)(currentArea));


            if (!currentArea.CanAddStructure(player, StructureTypes.LaserTurret, xPos, yPos, out resultMessage))
            {
                return(false);
            }
            else if (player.GetActiveShip().Cargo.IsCargoInHolds(turretID) != StatefulCargoTypes.LaserTurret)
            {
                resultMessage = "Turret not found in ship cargo.";
                return(false);
            }
            else if (!system.GetValidStructurePosition(StructureStatManager.GetStats(StructureTypes.LaserTurret), ref xPos, ref yPos))
            {
                resultMessage = "Invalid structure position.";
                return(false);
            }


            resultMessage = "Success";
            return(true);
        }
예제 #3
0
 public void TakeDamage(int damage)
 {
     if (Health < 0)
     {
         return;
     }
     if (Fortified)
     {
         damage = (int)(damage * .8f);
     }
     health -= damage; // Add armour to the equation
     if (EntityBar != null)
     {
         EntityBar.GetComponent <EntityBar>().SetHealthSize(health / maxHealth);
     }
     Debug.Log(String.Format("{0} took {1} points of damage, {2} health remaining.", name, damage, Health));
     if (Destroyed())
     {
         //gameObject.SetActive(false);
         if (PSystem != null)
         {
             PSystem.Play();
         }
         Destroy(this.gameObject, 1f);
     }
 }
예제 #4
0
        // Awake() is the first function called in the lifecycle of a Unity3D MonoBehaviour.  In the case of KSP,
        // it happens to be called right before the game's PSystem is instantiated from PSystemManager.Instance.systemPrefab
        public void Awake()
        {
            // Abort, if KSP isn't compatible
            if (!CompatibilityChecker.IsCompatible())
            {
                string supported = CompatibilityChecker.version_major + "." + CompatibilityChecker.version_minor + "." + CompatibilityChecker.Revision;
                string current   = Versioning.version_major + "." + Versioning.version_minor + "." + Versioning.Revision;
                Debug.LogWarning("[Kopernicus] Detected incompatible install.\nCurrent version of KSP: " + current + ".\nSupported version of KSP: " + supported + ".\nPlease wait, until Kopernicus gets updated to match your version of KSP.");
                Debug.Log("[Kopernicus] Aborting...");

                // Abort
                Destroy(this);
                return;
            }

            // We're ALIVE
            Logger.Default.SetAsActive();
            Logger.Default.Log("Injector.Awake(): Begin");

            // Parser Config
            ParserOptions.Register("Kopernicus", new ParserOptions.Data {
                errorCallback = e => Logger.Active.LogException(e), logCallback = s => Logger.Active.Log(s)
            });

            // Yo garbage collector - we have work to do man
            DontDestroyOnLoad(this);

            // If the planetary manager does not work, well, error out
            if (PSystemManager.Instance == null)
            {
                // Log the error
                Logger.Default.Log("Injector.Awake(): If PSystemManager.Instance is null, there is nothing to do");
                return;
            }

            // Backup the old prefab
            StockSystemPrefab = PSystemManager.Instance.systemPrefab;

            // Get the current time
            DateTime start = DateTime.Now;

            // Get the configNode
            ConfigNode kopernicus = GameDatabase.Instance.GetConfigs(rootNodeName)[0].config;

            // THIS IS WHERE THE MAGIC HAPPENS - OVERWRITE THE SYSTEM PREFAB SO KSP ACCEPTS OUR CUSTOM SOLAR SYSTEM AS IF IT WERE FROM SQUAD
            PSystemManager.Instance.systemPrefab = Parser.CreateObjectFromConfigNode <Loader>(kopernicus, "Kopernicus").systemPrefab;

            // Clear space center instance so it will accept nouveau Kerbin
            SpaceCenter.Instance = null;

            // Add a handler so that we can do post spawn fixups.
            PSystemManager.Instance.OnPSystemReady.Add(PostSpawnFixups);

            // Done executing the awake function
            TimeSpan duration = (DateTime.Now - start);

            Logger.Default.Log("Injector.Awake(): Completed in: " + duration.TotalMilliseconds + " ms");
            Logger.Default.Flush();
        }
예제 #5
0
        public void TestAreCompatible()
        {
            PSystem PSystem = new PSystem(v_TestDeserializedMSystemObjects);

            var c1 = v_TestDeserializedMSystemObjects.Tiles["q1"].Connectors[0];
            var c2 = v_TestDeserializedMSystemObjects.Tiles["q1"].Connectors[1];
            var c3 = v_TestDeserializedMSystemObjects.Tiles["s1"].Connectors[1];

            Assert.IsTrue(PSystem.AreCompatible(c1, c2));
            Assert.IsFalse(PSystem.AreCompatible(c1, c3));
        }
예제 #6
0
        static void Main(string[] args)
        {
            PSystem system = new PSystem()
            {
                new FixedObject(new Vector2(5, 0), 1e+6f),
                new FixedObject(new Vector2(-5, 0), 1e+6f)
            };
            var f = PLine.ElectricFieldLine(system, new Vector2(5, 6), 6 * (int)6e3 + 1).ToArray();

            for (int i = 0; i <= 100; ++i)
            {
                Console.WriteLine(f[i * 50]);
            }
        }
        private void _handleMessageStartUpdatingSystems(object sender, NetworkMessageContainer messageData)
        {
            var data = messageData?.MessageData as MessageStartUpdatingSystems;

            // Return if this isn't the target slave
            if (data.SlaveServerID != _mySlaveID)
            {
                return;
            }

            PSystemsLoaded = false;

            if (data.ClearCurrentSystems)
            {
                _galaxyManager.ClearLocalSystems();
            }

#if DEBUG
            Stopwatch s1 = new Stopwatch();
            s1.Start();
#endif

            var loadedSystemModels = _databaseManager.GetAreasAsync(data.IDsToSimulate).Result;

            foreach (PSystemModel p in loadedSystemModels)
            {
                PSystem s = Deserializer.DeserializePSystemAsync(p, _redisServer, _locatorService, _registrationManager, _databaseManager).Result;
            }


            foreach (var a in _galaxyManager.AllAreas)
            {
                //Clear existing subscriptions to prevent doubles (for hot loading)
                _redisServer.UnSubscribe(ChannelTypes.WebToSlave, a.Value.Id, _routedMessageProcessor);

                //Subscribe
                _redisServer.Subscribe(ChannelTypes.WebToSlave, a.Value.Id, _routedMessageProcessor);
            }

#if DEBUG
            ConsoleManager.WriteLine(_galaxyManager.AllAreas.Count.ToString() + " total areas currently loaded.", ConsoleMessageType.Debug);
            s1.Stop();
            ConsoleManager.WriteLine(s1.ElapsedMilliseconds + " ms to load " + _galaxyManager.Systems.Count + " systems.", ConsoleMessageType.Debug);
#endif

            PSystemsLoaded = true;
        }
        public static PSystemBody GenerateSystemBody(PSystem system, PSystemBody parent, string templateName, string name, Orbit orbit)
        {
            // Look up the template body
            PSystemBody template = Utility.FindBody(system.rootBody, templateName);

            // Create a new celestial body as a clone of this template
            PSystemBody clone = system.AddBody(parent);

            clone.name = name;

            // Set up the celestial body of the clone (back up the orbit driver)
            Utility.CopyObjectFields <CelestialBody> (template.celestialBody, clone.celestialBody);
            clone.celestialBody.bodyName       = name;
            clone.celestialBody.orbitingBodies = null;
            clone.celestialBody.orbitDriver    = clone.orbitDriver;
            clone.flightGlobalsIndex           = 100 + template.flightGlobalsIndex;

            // Setup the orbit driver
            clone.orbitRenderer.orbitColor  = template.orbitRenderer.orbitColor;
            clone.orbitDriver.orbit         = orbit;
            clone.orbitDriver.celestialBody = clone.celestialBody;
            clone.orbitDriver.updateMode    = OrbitDriver.UpdateMode.UPDATE;

            // Setup the deactivator object
            GameObject deactivator = new GameObject("Deactivator");

            deactivator.SetActive(false);
            UnityEngine.Object.DontDestroyOnLoad(deactivator);

            // Clone the template's PQS
            clone.pqsVersion = UnityEngine.Object.Instantiate(template.pqsVersion) as PQS;
            clone.pqsVersion.transform.parent = deactivator.transform;
            clone.pqsVersion.name             = name;

            // Clone the scaled space
            clone.scaledVersion = UnityEngine.Object.Instantiate(template.scaledVersion) as GameObject;
            clone.scaledVersion.transform.parent = deactivator.transform;
            clone.scaledVersion.name             = name;

            return(clone);
        }
        // This function generates a duplicate of a PSystem
        public static PSystem DuplicateSystem(PSystem originalSystem)
        {	
            // Create a new planetary system object
            GameObject gameObject = new GameObject (originalSystem.systemName);
            UnityEngine.Object.DontDestroyOnLoad (gameObject);
            PSystem system = gameObject.AddComponent<PSystem> ();
            
            // Set the planetary system defaults (pulled from PSystemManager.Instance.systemPrefab)
            system.systemName          = originalSystem.systemName;
            system.systemTimeScale     = 1.0; 
            system.systemScale         = 1.0;
            system.mainToolbarSelected = 2;   // initial value in stock systemPrefab. Unknown significance.

            // Clone the root body of the system (we could set it up from scratch, but we do need the pqsVersion entries, which this DOES NOT copy
            GameObject rootBody = (GameObject) UnityEngine.Object.Instantiate (originalSystem.rootBody.gameObject);
            UnityEngine.Object.DontDestroyOnLoad (rootBody);
            system.rootBody = rootBody.GetComponent<PSystemBody> ();

            // Return the new system
            return system;
        }
예제 #10
0
        // This function generates a duplicate of a PSystem
        public static PSystem DuplicateSystem(PSystem originalSystem)
        {
            // Create a new planetary system object
            GameObject gameObject = new GameObject(originalSystem.systemName);

            UnityEngine.Object.DontDestroyOnLoad(gameObject);
            PSystem system = gameObject.AddComponent <PSystem> ();

            // Set the planetary system defaults (pulled from PSystemManager.Instance.systemPrefab)
            system.systemName          = originalSystem.systemName;
            system.systemTimeScale     = 1.0;
            system.systemScale         = 1.0;
            system.mainToolbarSelected = 2;               // initial value in stock systemPrefab. Unknown significance.

            // Clone the root body of the system (we could set it up from scratch, but we do need the pqsVersion entries, which this DOES NOT copy
            GameObject rootBody = (GameObject)UnityEngine.Object.Instantiate(originalSystem.rootBody.gameObject);

            UnityEngine.Object.DontDestroyOnLoad(rootBody);
            system.rootBody = rootBody.GetComponent <PSystemBody> ();

            // Return the new system
            return(system);
        }
예제 #11
0
        // This function returns a PSystem that will replace the stock systemPrefab
        // with one of the modder's design. KSP then loads the replacement planetary
        // system just as it would have loaded the stock system.
        public static PSystem GenerateSystem()
        {
            // If the planetary manager does not work, well, error out
            if (PSystemManager.Instance == null)
            {
                // Log the error
                Debug.LogError("[Kopernicus]: KopernicusSystemSource.GenerateSystem() can not be called if PSystemManager.Instance is null");
                return(null);
            }

            // Setup the template solar system object from the original game
            PSystem system = DuplicateSystem(PSystemManager.Instance.systemPrefab);

            // Create "Kopernicus"
            // Note that due to the way AddBody works, this is a function with side effects
            // rather than something that returns a planet. Perhaps it should be named differently
            // from the GenerateSystem method to emphasize this difference in usage??
            KopernicusPlanetSource.GeneratePlanet(system, "Kopernicus");
            //StockPlanetSource.GeneratePlanet(system, "Laythe", "Bob", new Orbit (0.0, 0.0, 47500000000, 0, 0, 0, 0, system.rootBody.celestialBody));

            // Return the newly created planetary system
            return(system);
        }
예제 #12
0
        public static PSystemBody GenerateSystemBody(PSystem system, PSystemBody parent, String name, Orbit orbit = null)
        {
            PSystemBody Jool   = Utility.FindBody(system.rootBody, "Jool");             // Need the geosphere for scaled version
            PSystemBody Laythe = Utility.FindBody(system.rootBody, "Laythe");           // Need pqs and ocean definitions

            //Utility.DumpObject (Laythe.celestialBody, " Laythe Celestial Body ");
            //Utility.DumpObject (Laythe.pqsVersion, " Laythe PQS ");
            //Transform laytheOcean = Utility.FindInChildren (Laythe.pqsVersion.transform, "LaytheOcean");
            //Utility.DumpObject (laytheOcean.GetComponent<PQS> (), " Laythe Ocean PQS ");

            // AddBody makes the GameObject and stuff. It also attaches it to the system and parent.
            PSystemBody body = system.AddBody(parent);

            // set up the various parameters
            body.name = name;
            body.flightGlobalsIndex = 100;

            // Some parameters of the celestialBody, which represents the actual planet...
            // PSystemBody is more of a container that associates the planet with its orbit
            // and position in the planetary system, etc.
            body.celestialBody.bodyName        = name;
            body.celestialBody.bodyDescription = "Merciful Kod, this thing just APPEARED! And unlike last time, it wasn't bird droppings on the telescope.";
            body.celestialBody.Radius          = 320000;
            //body.celestialBody.Radius                 = 3380100;
            body.celestialBody.GeeASL = 0.3;
            //body.celestialBody.Mass                   = 6.4185E+23;
            body.celestialBody.Mass = 4.5154812E+21;
            body.celestialBody.timeWarpAltitudeLimits = (float[])Laythe.celestialBody.timeWarpAltitudeLimits.Clone();
            body.celestialBody.rotationPeriod         = 88642.6848;
            body.celestialBody.rotates       = true;
            body.celestialBody.BiomeMap      = GenerateCBAttributeMapSO(name);                     //Dres.celestialBody.BiomeMap;//
            body.celestialBody.scienceValues = Laythe.celestialBody.scienceValues;
            body.celestialBody.ocean         = false;

            // Presumably true of Kerbin. I do not know what the consequences are of messing with this exactly.
            // I think this just affects where the Planetarium/Tracking station starts.
            body.celestialBody.isHomeWorld = false;

            // Setup the orbit of "Kopernicus."  The "Orbit" class actually is built to support serialization straight
            // from Squad, so storing these to files (and loading them) will be pretty easy.
            body.orbitRenderer.orbitColor  = Color.magenta;
            body.orbitDriver.celestialBody = body.celestialBody;
            body.orbitDriver.updateMode    = OrbitDriver.UpdateMode.UPDATE;
            if (orbit == null)
            {
                body.orbitDriver.orbit = new Orbit(0.0, 0.0, 47500000000, 0, 0, 0, 0, system.rootBody.celestialBody);
            }
            else
            {
                body.orbitDriver.orbit = orbit;
            }


            #region PSystemBody.pqsVersion generation

            // Create the PQS controller game object for Kopernicus
            GameObject controllerRoot = new GameObject(name);
            controllerRoot.layer            = Constants.GameLayers.LocalSpace;
            controllerRoot.transform.parent = Utility.Deactivator;

            // Create the PQS object and pull all the values from Dres (has some future proofing i guess? adapts to PQS changes)
            body.pqsVersion = controllerRoot.AddComponent <PQS>();
            Utility.CopyObjectFields(Laythe.pqsVersion, body.pqsVersion);
            //body.pqsVersion.surfaceMaterial = new PQSProjectionSurfaceQuad();
            //body.pqsVersion.fallbackMaterial = new PQSProjectionFallback();
            body.pqsVersion.surfaceMaterial  = new PQSProjectionAerialQuadRelative(Laythe.pqsVersion.surfaceMaterial);            // use until we determine all the functions of the shader textures
            body.pqsVersion.fallbackMaterial = new PQSProjectionFallback(Laythe.pqsVersion.fallbackMaterial);
            body.pqsVersion.radius           = body.celestialBody.Radius;
            body.pqsVersion.mapOcean         = false;

            // Debug
            Utility.DumpObjectProperties(body.pqsVersion.surfaceMaterial, " Surface Material ");
            Utility.DumpObjectProperties(body.pqsVersion.fallbackMaterial, " Fallback Material ");

            // Detail defaults
            body.pqsVersion.maxQuadLenghtsPerFrame = 0.03f;
            body.pqsVersion.minLevel          = 1;
            body.pqsVersion.maxLevel          = 10;
            body.pqsVersion.minDetailDistance = 8;

            // Create the celestial body transform
            GameObject mod = new GameObject("_CelestialBody");
            mod.transform.parent = controllerRoot.transform;
            PQSMod_CelestialBodyTransform celestialBodyTransform = mod.AddComponent <PQSMod_CelestialBodyTransform>();
            celestialBodyTransform.sphere                        = body.pqsVersion;
            celestialBodyTransform.forceActivate                 = false;
            celestialBodyTransform.deactivateAltitude            = 115000;
            celestialBodyTransform.forceRebuildOnTargetChange    = false;
            celestialBodyTransform.planetFade                    = new PQSMod_CelestialBodyTransform.AltitudeFade();
            celestialBodyTransform.planetFade.fadeFloatName      = "_PlanetOpacity";
            celestialBodyTransform.planetFade.fadeStart          = 100000.0f;
            celestialBodyTransform.planetFade.fadeEnd            = 110000.0f;
            celestialBodyTransform.planetFade.valueStart         = 0.0f;
            celestialBodyTransform.planetFade.valueEnd           = 1.0f;
            celestialBodyTransform.planetFade.secondaryRenderers = new List <GameObject>();
            celestialBodyTransform.secondaryFades                = new PQSMod_CelestialBodyTransform.AltitudeFade[0];
            celestialBodyTransform.requirements                  = PQS.ModiferRequirements.Default;
            celestialBodyTransform.modEnabled                    = true;
            celestialBodyTransform.order = 10;

            // Create the color PQS mods
            mod = new GameObject("_Color");
            mod.transform.parent = controllerRoot.transform;
            PQSMod_VertexSimplexNoiseColor vertexSimplexNoiseColor = mod.AddComponent <PQSMod_VertexSimplexNoiseColor>();
            vertexSimplexNoiseColor.sphere       = body.pqsVersion;
            vertexSimplexNoiseColor.seed         = 45;
            vertexSimplexNoiseColor.blend        = 1.0f;
            vertexSimplexNoiseColor.colorStart   = new Color(0.768656731f, 0.6996614f, 0.653089464f, 1);
            vertexSimplexNoiseColor.colorEnd     = new Color(0.0f, 0.0f, 0.0f, 1.0f);
            vertexSimplexNoiseColor.octaves      = 12.0;
            vertexSimplexNoiseColor.persistence  = 0.5;
            vertexSimplexNoiseColor.frequency    = 2.0;
            vertexSimplexNoiseColor.requirements = PQS.ModiferRequirements.MeshColorChannel;
            vertexSimplexNoiseColor.modEnabled   = true;
            vertexSimplexNoiseColor.order        = 200;

            PQSMod_HeightColorMap heightColorMap = mod.AddComponent <PQSMod_HeightColorMap>();
            heightColorMap.sphere = body.pqsVersion;
            List <PQSMod_HeightColorMap.LandClass> landClasses = new List <PQSMod_HeightColorMap.LandClass>();

            PQSMod_HeightColorMap.LandClass landClass = new PQSMod_HeightColorMap.LandClass("AbyPl", 0.0, 0.5, new Color(0.0f, 0.0f, 0.0f, 1.0f), Color.white, double.NaN);
            landClass.lerpToNext = true;
            landClasses.Add(landClass);

            landClass            = new PQSMod_HeightColorMap.LandClass("Beach", 0.5, 0.550000011920929, new Color(0.164179087f, 0.164179087f, 0.164179087f, 1.0f), Color.white, double.NaN);
            landClass.lerpToNext = true;
            landClasses.Add(landClass);

            landClass            = new PQSMod_HeightColorMap.LandClass("Beach", 0.550000011920929, 1.0, new Color(0.373134315f, 0.373134315f, 0.373134315f, 1.0f), Color.white, double.NaN);
            landClass.lerpToNext = false;
            landClasses.Add(landClass);

            // Generate an array from the land classes list
            heightColorMap.landClasses  = landClasses.ToArray();
            heightColorMap.blend        = 0.7f;
            heightColorMap.lcCount      = 3;
            heightColorMap.requirements = PQS.ModiferRequirements.MeshColorChannel;
            heightColorMap.modEnabled   = true;
            heightColorMap.order        = 201;

            // Create the alititude alpha mods
            mod = new GameObject("_Material_ModProjection");
            mod.transform.parent = controllerRoot.transform;
            PQSMod_AltitudeAlpha altitudeAlpha = mod.AddComponent <PQSMod_AltitudeAlpha>();
            altitudeAlpha.sphere          = body.pqsVersion;
            altitudeAlpha.atmosphereDepth = 4000.0;
            altitudeAlpha.invert          = false;
            altitudeAlpha.requirements    = PQS.ModiferRequirements.Default;
            altitudeAlpha.modEnabled      = false;
            altitudeAlpha.order           = 999999999;

            // Create the aerial perspective material
            mod = new GameObject("_Material_AerialPerspective");
            mod.transform.parent = controllerRoot.transform;
            PQSMod_AerialPerspectiveMaterial aerialPerspectiveMaterial = mod.AddComponent <PQSMod_AerialPerspectiveMaterial>();
            aerialPerspectiveMaterial.sphere              = body.pqsVersion;
            aerialPerspectiveMaterial.globalDensity       = -0.00001f;
            aerialPerspectiveMaterial.heightFalloff       = 6.75f;
            aerialPerspectiveMaterial.atmosphereDepth     = 150000;
            aerialPerspectiveMaterial.DEBUG_SetEveryFrame = true;
            aerialPerspectiveMaterial.cameraAlt           = 0;
            aerialPerspectiveMaterial.cameraAtmosAlt      = 0;
            aerialPerspectiveMaterial.heightDensAtViewer  = 0;
            aerialPerspectiveMaterial.requirements        = PQS.ModiferRequirements.Default;
            aerialPerspectiveMaterial.modEnabled          = true;
            aerialPerspectiveMaterial.order = 100;

            // Create the UV planet relative position
            mod = new GameObject("_Material_SurfaceQuads");
            mod.transform.parent = controllerRoot.transform;
            PQSMod_UVPlanetRelativePosition planetRelativePosition = mod.AddComponent <PQSMod_UVPlanetRelativePosition>();
            planetRelativePosition.sphere       = body.pqsVersion;
            planetRelativePosition.requirements = PQS.ModiferRequirements.Default;
            planetRelativePosition.modEnabled   = true;
            planetRelativePosition.order        = 999999;

            // Create the height noise module
            mod = new GameObject("_HeightNoise");
            mod.transform.parent = controllerRoot.transform;
            PQSMod_VertexHeightMap vertexHeightMap = mod.gameObject.AddComponent <PQSMod_VertexHeightMap>();
            vertexHeightMap.sphere = body.pqsVersion;
            //vertexHeightMap.heightMapDeformity = 29457.0;
            vertexHeightMap.heightMapDeformity     = 10000.0;
            vertexHeightMap.heightMapOffset        = -1000.0;
            vertexHeightMap.scaleDeformityByRadius = false;
            vertexHeightMap.requirements           = PQS.ModiferRequirements.MeshCustomNormals | PQS.ModiferRequirements.VertexMapCoords;
            vertexHeightMap.modEnabled             = true;
            vertexHeightMap.order = 20;

            // Load the heightmap for this planet
            Texture2D map = new Texture2D(4, 4, TextureFormat.Alpha8, false);
            map.LoadImage(System.IO.File.ReadAllBytes(KSPUtil.ApplicationRootPath + PluginDirectory + "/Planets/" + name + "/Height.png"));
            vertexHeightMap.heightMap = ScriptableObject.CreateInstance <MapSO>();
            vertexHeightMap.heightMap.CreateMap(MapSO.MapDepth.Greyscale, map);
            UnityEngine.Object.DestroyImmediate(map);

            // Create the simplex height module
            PQSMod_VertexSimplexHeight vertexSimplexHeight = mod.AddComponent <PQSMod_VertexSimplexHeight>();
            vertexSimplexHeight.sphere       = body.pqsVersion;
            vertexSimplexHeight.seed         = 670000;
            vertexSimplexHeight.deformity    = 1700.0;
            vertexSimplexHeight.octaves      = 12.0;
            vertexSimplexHeight.persistence  = 0.5;
            vertexSimplexHeight.frequency    = 4.0;
            vertexSimplexHeight.requirements = PQS.ModiferRequirements.MeshCustomNormals;
            vertexSimplexHeight.modEnabled   = true;
            vertexSimplexHeight.order        = 21;

            // SERIOUSLY RECOMMENDED FOR NO OCEAN WORLDS
            // Create the flatten ocean module
            PQSMod_FlattenOcean flattenOcean = mod.AddComponent <PQSMod_FlattenOcean>();
            flattenOcean.sphere       = body.pqsVersion;
            flattenOcean.oceanRadius  = 1.0;
            flattenOcean.requirements = PQS.ModiferRequirements.MeshCustomNormals;
            flattenOcean.modEnabled   = true;
            flattenOcean.order        = 25;

            // Creat the vertex height noise module
            PQSMod_VertexHeightNoise vertexHeightNoise = mod.AddComponent <PQSMod_VertexHeightNoise>();
            vertexHeightNoise.sphere       = body.pqsVersion;
            vertexHeightNoise.noiseType    = PQSMod_VertexHeightNoise.NoiseType.RiggedMultifractal;
            vertexHeightNoise.deformity    = 1000.0f;
            vertexHeightNoise.seed         = 5906;
            vertexHeightNoise.frequency    = 2.0f;
            vertexHeightNoise.lacunarity   = 2.5f;
            vertexHeightNoise.persistance  = 0.5f;
            vertexHeightNoise.octaves      = 4;
            vertexHeightNoise.mode         = LibNoise.Unity.QualityMode.Low;
            vertexHeightNoise.requirements = PQS.ModiferRequirements.MeshColorChannel;
            vertexHeightNoise.modEnabled   = true;
            vertexHeightNoise.order        = 22;

            // Create the material direction
            mod = new GameObject("_Material_SunLight");
            mod.transform.parent = controllerRoot.gameObject.transform;
            PQSMod_MaterialSetDirection materialSetDirection = mod.AddComponent <PQSMod_MaterialSetDirection>();
            materialSetDirection.sphere       = body.pqsVersion;
            materialSetDirection.valueName    = "_sunLightDirection";
            materialSetDirection.requirements = PQS.ModiferRequirements.Default;
            materialSetDirection.modEnabled   = true;
            materialSetDirection.order        = 100;

            // Crete the quad mesh colliders
            mod = new GameObject("QuadMeshColliders");
            mod.transform.parent = controllerRoot.gameObject.transform;
            PQSMod_QuadMeshColliders quadMeshColliders = mod.AddComponent <PQSMod_QuadMeshColliders>();
            quadMeshColliders.sphere                             = body.pqsVersion;
            quadMeshColliders.maxLevelOffset                     = 0;
            quadMeshColliders.physicsMaterial                    = new PhysicMaterial();
            quadMeshColliders.physicsMaterial.name               = "Ground";
            quadMeshColliders.physicsMaterial.dynamicFriction    = 0.6f;
            quadMeshColliders.physicsMaterial.staticFriction     = 0.8f;
            quadMeshColliders.physicsMaterial.bounciness         = 0.0f;
            quadMeshColliders.physicsMaterial.frictionDirection2 = Vector3.zero;
            quadMeshColliders.physicsMaterial.dynamicFriction2   = 0.0f;
            quadMeshColliders.physicsMaterial.staticFriction2    = 0.0f;
            quadMeshColliders.physicsMaterial.frictionCombine    = PhysicMaterialCombine.Maximum;
            quadMeshColliders.physicsMaterial.bounceCombine      = PhysicMaterialCombine.Average;
            quadMeshColliders.requirements                       = PQS.ModiferRequirements.Default;
            quadMeshColliders.modEnabled                         = true;
            quadMeshColliders.order = 100;

            // Create the simplex height absolute
            mod = new GameObject("_FineDetail");
            mod.transform.parent = controllerRoot.gameObject.transform;
            PQSMod_VertexSimplexHeightAbsolute vertexSimplexHeightAbsolute = mod.AddComponent <PQSMod_VertexSimplexHeightAbsolute>();
            vertexSimplexHeightAbsolute.sphere       = body.pqsVersion;
            vertexSimplexHeightAbsolute.seed         = 4234;
            vertexSimplexHeightAbsolute.deformity    = 400.0;
            vertexSimplexHeightAbsolute.octaves      = 6.0;
            vertexSimplexHeightAbsolute.persistence  = 0.5;
            vertexSimplexHeightAbsolute.frequency    = 18.0;
            vertexSimplexHeightAbsolute.requirements = PQS.ModiferRequirements.Default;
            vertexSimplexHeightAbsolute.modEnabled   = true;
            vertexSimplexHeightAbsolute.order        = 30;

            // Surface color map
            mod = new GameObject("_LandClass");
            mod.transform.parent = body.pqsVersion.gameObject.transform;
            PQSMod_VertexColorMap colorMap = mod.AddComponent <PQSMod_VertexColorMap>();
            colorMap.sphere     = body.pqsVersion;
            colorMap.order      = 500;
            colorMap.modEnabled = true;

            // Decompress and load the color
            map = new Texture2D(4, 4, TextureFormat.RGB24, false);
            map.LoadImage(System.IO.File.ReadAllBytes(KSPUtil.ApplicationRootPath + PluginDirectory + "/Planets/" + name + "/Color.png"));
            colorMap.vertexColorMap = ScriptableObject.CreateInstance <MapSO>();
            colorMap.vertexColorMap.CreateMap(MapSO.MapDepth.RGB, map);
            UnityEngine.Object.DestroyImmediate(map);

            #endregion

            #region PSystemBody.scaledVersion generation

            // Create the scaled version of the planet for use in map view
            body.scaledVersion                  = new GameObject(name);
            body.scaledVersion.layer            = Constants.GameLayers.ScaledSpace;
            body.scaledVersion.transform.parent = Utility.Deactivator;

            // DEPRECATED - USE PQSMeshWrapper
            // Make sure the scaled version cooresponds to the size of the body
            // Turns out that the localScale is directly related to the planet size.
            // Jool's local scale is {1,1,1}, Kerbin's is {0.1,0.1,0.1}.  Jool's
            // radius is 6000 km, Kerbin's is 600 km.  Notice the relation?
            float scale = (float)body.celestialBody.Radius / 6000000.0f;
            body.scaledVersion.transform.localScale = new Vector3(scale, scale, scale);

            // Generate a mesh to fit the PQS we generated (it would be cool to generate this FROM the PQS)
            Mesh mesh = new Mesh();
            Utility.CopyMesh(Jool.scaledVersion.GetComponent <MeshFilter>().sharedMesh, mesh);

            // Iterate though the UVs
            // Geosphere with a radius of 1000, cooresponds to an object 6000km in radius
            Vector3[] vertices = mesh.vertices;
            for (int i = 0; i < mesh.vertexCount; i++)
            {
                // Get the height offset from the height map
                Vector2 uv           = mesh.uv[i];
                float   displacement = vertexHeightMap.heightMap.GetPixelFloat(uv.x, uv.y);

                // Since this is a geosphere, normalizing the vertex gives the vector to translate on
                Vector3 v = vertices[i];
                v.Normalize();

                // Calculate the real height displacement (in meters), normalized vector "v" scale (1 unit = 6 km)
                displacement = (float)vertexHeightMap.heightMapOffset + (displacement * (float)vertexHeightMap.heightMapDeformity);
                Vector3 offset = v * ((displacement / 6000.0f) / scale);

                // Adjust the displacement
                vertices[i] += offset;
            }
            mesh.vertices = vertices;
            mesh.RecalculateNormals();

            // Create the mesh filter
            MeshFilter meshFilter = body.scaledVersion.AddComponent <MeshFilter> ();
            meshFilter.mesh = mesh;

            // Load and compress the color texture for the custom planet
            Texture2D colorTexture = new Texture2D(4, 4, TextureFormat.RGBA32, true);
            colorTexture.LoadImage(System.IO.File.ReadAllBytes(KSPUtil.ApplicationRootPath + PluginDirectory + "/Planets/" + name + "/Color.png"));
            colorTexture.Compress(true);
            colorTexture.Apply(true, true);

            // Load and compress the color texture for the custom planet
            Texture2D normalTexture = new Texture2D(4, 4, TextureFormat.RGB24, true);
            normalTexture.LoadImage(System.IO.File.ReadAllBytes(KSPUtil.ApplicationRootPath + PluginDirectory + "/Planets/" + name + "/Normals.png"));
            //normalTexture = GameDatabase.BitmapToUnityNormalMap(normalTexture);
            normalTexture.Compress(true);
            normalTexture.Apply(true, true);

            // Create the renderer and material for the scaled version
            MeshRenderer renderer = body.scaledVersion.AddComponent <MeshRenderer>();
            //ScaledPlanetSimple material = new ScaledPlanetSimple();   // for atmosphereless planets
            ScaledPlanetRimAerial material = new ScaledPlanetRimAerial();
            material.color       = Color.white;
            material.specColor   = Color.black;
            material.mainTexture = colorTexture;
            material.bumpMap     = normalTexture;
            renderer.material    = material;

            // Create the sphere collider
            SphereCollider collider = body.scaledVersion.AddComponent <SphereCollider> ();
            collider.center = Vector3.zero;
            collider.radius = 1000.0f;

            // Create the ScaledSpaceFader to fade the orbit out where we view it (maybe?)
            ScaledSpaceFader fader = body.scaledVersion.AddComponent <ScaledSpaceFader> ();
            fader.celestialBody = body.celestialBody;
            fader.fadeStart     = 95000.0f;
            fader.fadeEnd       = 100000.0f;
            fader.floatName     = "_Opacity";

            #endregion

            #region Atmosphere
            //--------------------- PROPERTIES EXCLUSIVE TO BODIES WITH ATMOSPHERE

            // Load the atmosphere gradient (compress it, does not need to be high quality)
            Texture2D atmosphereGradient = new Texture2D(4, 4, TextureFormat.RGB24, true);
            atmosphereGradient.LoadImage(System.IO.File.ReadAllBytes(KSPUtil.ApplicationRootPath + PluginDirectory + "/Planets/" + name + "/AtmosphereGradient.png"));
            atmosphereGradient.Compress(true);
            atmosphereGradient.wrapMode   = TextureWrapMode.Clamp;
            atmosphereGradient.mipMapBias = 0.0f;
            atmosphereGradient.Apply(true, true);

            // Set the additional settings in the scaledVersion body's shader
            material.rimPower     = 2.06f;
            material.rimBlend     = 0.3f;
            material.rimColorRamp = atmosphereGradient;

            // Atmosphere specific properties (for scaled version root) (copied from duna)
            MaterialSetDirection materialLightDirection = body.scaledVersion.AddComponent <MaterialSetDirection>();
            materialLightDirection.valueName = "_localLightDirection";

            // Create the atmosphere shell itself
            GameObject scaledAtmosphere = new GameObject("atmosphere");
            scaledAtmosphere.transform.parent = body.scaledVersion.transform;
            scaledAtmosphere.layer            = Constants.GameLayers.ScaledSpaceAtmosphere;
            meshFilter            = scaledAtmosphere.AddComponent <MeshFilter>();
            meshFilter.sharedMesh = Jool.scaledVersion.GetComponent <MeshFilter>().sharedMesh;
            renderer          = scaledAtmosphere.AddComponent <MeshRenderer>();
            renderer.material = new Kopernicus.MaterialWrapper.AtmosphereFromGround();
            AtmosphereFromGround atmosphereRenderInfo = scaledAtmosphere.AddComponent <AtmosphereFromGround>();
            atmosphereRenderInfo.waveLength = new Color(0.509f, 0.588f, 0.643f, 0.000f);

            // Technical info for atmosphere
            body.celestialBody.atmosphere = true;
            body.celestialBody.atmosphereContainsOxygen        = true;
            body.celestialBody.staticPressureASL               = 1.0;      // can't find anything that references this, especially with the equation in mind - where is this used?
            body.celestialBody.altitudeMultiplier              = 1.4285f;  // ditto
            body.celestialBody.atmosphereScaleHeight           = 4.0;      // pressure (in atm) = atmosphereMultipler * e ^ -(altitude / (atmosphereScaleHeight * 1000))
            body.celestialBody.atmosphereMultiplier            = 0.8f;
            body.celestialBody.atmoshpereTemperatureMultiplier = 1.0f;     // how does this coorespond?
            body.celestialBody.maxAtmosphereAltitude           = 55000.0f; // i guess this is so the math doesn't drag out?
            body.celestialBody.useLegacyAtmosphere             = true;
            body.celestialBody.atmosphericAmbientColor         = new Color(0.306f, 0.187f, 0.235f, 1.000f);
            #endregion

            #region Ocean
            // ---------------- FOR BODIES WITH OCEANS ----------

            /*body.celestialBody.ocean = true;
             *
             * // Setup the laythe ocean info in master pqs
             * body.pqsVersion.mapOcean = true;
             * body.pqsVersion.mapOceanColor = new Color(0.117f, 0.126f, 0.157f, 1.000f);
             * body.pqsVersion.mapOceanHeight = 0.0f;
             *
             * // Generate the PQS object
             * GameObject oceanRoot       = new GameObject(name + "Ocean");
             * oceanRoot.transform.parent = body.pqsVersion.transform;
             * oceanRoot.layer            = Constants.GameLayers.LocalSpace;
             * PQS oceanPQS               = oceanRoot.AddComponent<PQS>();
             *
             * // Add this new PQS to the secondary renderers of the altitude fade controller
             * celestialBodyTransform.planetFade.secondaryRenderers.Add(oceanRoot);
             *
             * // Setup the PQS object data
             * Utility.CopyObjectFields<PQS>(laytheOcean.GetComponent<PQS>(), oceanPQS);
             * oceanPQS.radius            = body.pqsVersion.radius;
             * oceanPQS.surfaceMaterial   = new PQSOceanSurfaceQuad(laytheOcean.GetComponent<PQS>().surfaceMaterial);
             * oceanPQS.fallbackMaterial  = new PQSOceanSurfaceQuadFallback(laytheOcean.GetComponent<PQS>().fallbackMaterial);
             * Utility.DumpObjectProperties(oceanPQS.surfaceMaterial, oceanPQS.surfaceMaterial.ToString());
             * Utility.DumpObjectProperties(oceanPQS.fallbackMaterial, oceanPQS.fallbackMaterial.ToString());
             *
             * // Create the aerial perspective material
             * mod = new GameObject("_Material_AerialPerspective");
             * mod.transform.parent = oceanRoot.transform;
             * aerialPerspectiveMaterial = mod.AddComponent<PQSMod_AerialPerspectiveMaterial>();
             * aerialPerspectiveMaterial.sphere = body.pqsVersion;
             * aerialPerspectiveMaterial.globalDensity = -0.00001f;
             * aerialPerspectiveMaterial.heightFalloff = 6.75f;
             * aerialPerspectiveMaterial.atmosphereDepth = 150000;
             * aerialPerspectiveMaterial.DEBUG_SetEveryFrame = true;
             * aerialPerspectiveMaterial.cameraAlt = 0;
             * aerialPerspectiveMaterial.cameraAtmosAlt = 0;
             * aerialPerspectiveMaterial.heightDensAtViewer = 0;
             * aerialPerspectiveMaterial.requirements = PQS.ModiferRequirements.Default;
             * aerialPerspectiveMaterial.modEnabled = true;
             * aerialPerspectiveMaterial.order = 100;
             *
             * // Create the UV planet relative position
             * mod = new GameObject("_Material_SurfaceQuads");
             * mod.transform.parent = oceanRoot.transform;
             * planetRelativePosition = mod.AddComponent<PQSMod_UVPlanetRelativePosition>();
             * planetRelativePosition.sphere = body.pqsVersion;
             * planetRelativePosition.requirements = PQS.ModiferRequirements.Default;
             * planetRelativePosition.modEnabled = true;
             * planetRelativePosition.order = 100;
             *
             * // Create the quad map remover (da f**k?)
             * mod = new GameObject("QuadRemoveMap");
             * mod.transform.parent = oceanRoot.transform;
             * PQSMod_RemoveQuadMap removeQuadMap = mod.AddComponent<PQSMod_RemoveQuadMap>();
             * removeQuadMap.mapDeformity = 0.0f;
             * removeQuadMap.minHeight = 0.0f;
             * removeQuadMap.maxHeight = 0.5f;
             * removeQuadMap.requirements = PQS.ModiferRequirements.Default;
             * removeQuadMap.modEnabled = true;
             * removeQuadMap.order = 1000;
             *
             * // Load the heightmap into whatever the hell this is
             * map = new Texture2D(4, 4, TextureFormat.Alpha8, false);
             * map.LoadImage(System.IO.File.ReadAllBytes(KSPUtil.ApplicationRootPath + PluginDirectory + "/Planets/" + name + "/Height.png"));
             * removeQuadMap.map = ScriptableObject.CreateInstance<MapSO>();
             * removeQuadMap.map.CreateMap(MapSO.MapDepth.Greyscale, map);
             * UnityEngine.Object.DestroyImmediate(map);
             *
             * // Setup the ocean effects
             * mod = new GameObject("OceanFX");
             * mod.transform.parent = oceanRoot.transform;
             * PQSMod_OceanFX oceanFX = mod.AddComponent<PQSMod_OceanFX>();
             * oceanFX.watermain = Utility.RecursivelyGetComponent<PQSMod_OceanFX>(laytheOcean).watermain.Clone() as Texture2D[];
             * oceanFX.requirements = PQS.ModiferRequirements.Default;
             * oceanFX.modEnabled = true;
             * oceanFX.order = 100;*/

            #endregion

            // Return the new body
            return(body);
        }
예제 #13
0
 public static bool CheckForCollisions(PSystem p, Planet pp)
 {
     return(CheckForCollisions(p, pp, planetDistanceApart));
 }
예제 #14
0
        public void TestConstructor()
        {
            PSystem PSystem = new PSystem(v_TestDeserializedMSystemObjects);

            // Tiles
            ReadOnlyDictionary <string, Tile> tiles = PSystem.Tiles;

            Assert.AreEqual(3, tiles.Count);
            Tile tileQ1     = tiles["q1"];
            var  connectors = tileQ1.Connectors;

            Assert.AreEqual(6, connectors.Count);
            var connectorC1 = connectors[0];

            Assert.AreEqual("c1", connectorC1.Name);
            Assert.AreEqual(Tile.SideType.undef, connectorC1.Side);
            Assert.AreEqual(v_TestDeserializedMSystemObjects.Glues["pa"], connectorC1.Glue);
            Assert.AreEqual(Angle.FromRadians(2.034443935795703), connectorC1.Angle);
            Assert.AreEqual(2, connectorC1.Positions.Count);
            Assert.AreEqual(new Point3D(0, 10, 0), connectorC1.Positions[0]);
            double posY = 10 * Math.Cos((1) * 2 * Math.PI / 5);
            double posX = 10 * Math.Sin((1) * 2 * Math.PI / 5);

            Assert.AreEqual(new Point3D(posX, posY, 0), connectorC1.Positions[1]);
            Glue surfaceGLuePx = tileQ1.SurfaceGlue;

            Assert.AreEqual("px", surfaceGLuePx.Name);
            Assert.AreEqual(4, tileQ1.Proteins.Count);
            Assert.AreEqual("p1", tileQ1.Proteins[0].Name);
            Assert.AreEqual("p1", tileQ1.Proteins[1].Name);
            Assert.AreEqual("p2", tileQ1.Proteins[2].Name);
            Assert.AreEqual("p2", tileQ1.Proteins[3].Name);
            foreach (var protein in tileQ1.Proteins)
            {
                Assert.AreEqual(Point3D.Origin, protein.Position);
            }

            Assert.AreEqual(Color.DeepSkyBlue, tileQ1.Color);
            Tile tileS1 = tiles["s1"];

            Assert.AreEqual(2, tileS1.Connectors.Count);
            Assert.AreEqual(1, tileS1.Proteins.Count);

            //Initial objects
            IReadOnlyList <Cytos_v2.Classes.SeedTile> seedTiles = PSystem.SeedTiles;

            Assert.AreEqual(3, seedTiles.Count);
            Cytos_v2.Classes.SeedTile seedTileQ1 = seedTiles[0];
            Assert.AreEqual("q1", seedTileQ1.Name);
            Assert.AreEqual(new Point3D(0, 0, 0), seedTileQ1.Position);
            Assert.AreEqual(new EulerAngles(default(Angle), default(Angle), default(Angle)), seedTileQ1.Angle);

            //Environmental objects
            var environmentalObjects = PSystem.FloatingObjects.Values.Where(obj => obj.Concentration > 0).ToList();

            Assert.AreEqual(1, environmentalObjects.Count);
            var environmentalObjectA = environmentalObjects[0];

            Assert.AreEqual("b", environmentalObjectA.Name);
            Assert.AreEqual(2, environmentalObjectA.Concentration);

            //GlueRadius
            Assert.AreEqual(0.1, PSystem.GlueRadius);

            //Mobility
            Assert.AreEqual(3, PSystem.Mobility);

            //Tolerance
            Assert.AreEqual(1E-10, PSystem.Tolerance);

            //SideDist
            Assert.AreEqual(5E-10, PSystem.SideDist);

            //GlueRelation
            GlueRelation glueTuples = PSystem.GlueRelation;

            Assert.AreEqual(3, glueTuples.Count);

            Tuple <Glue, Glue> glueTuplePaPb = glueTuples.Keys.ElementAt(0);

            Assert.AreEqual("pa", glueTuplePaPb.Item1.Name);
            Assert.AreEqual("pb", glueTuplePaPb.Item2.Name);
            Assert.AreEqual(1, glueTuples.Values.ElementAt(0).ToDictionary()["a"]);

            Tuple <Glue, Glue> glueTuplePaPa = glueTuples.Keys.ElementAt(1);

            Assert.AreEqual("pa", glueTuplePaPa.Item1.Name);
            Assert.AreEqual("pa", glueTuplePaPa.Item2.Name);
            Assert.AreEqual(1, glueTuples.Values.ElementAt(1).ToDictionary().Count);

            Tuple <Glue, Glue> glueTuplePbPb = glueTuples.Keys.ElementAt(2);

            Assert.AreEqual("pb", glueTuplePbPb.Item1.Name);
            Assert.AreEqual("pb", glueTuplePbPb.Item2.Name);
            Assert.AreEqual(0, glueTuples.Values.ElementAt(2).ToDictionary().Count);

            //MetabolicRules
            Dictionary <string, IReadOnlyList <EvoMetabolicRule> > metabolicRules = PSystem.MetabolicRules;

            Assert.AreEqual(2, metabolicRules.Count);
            Assert.IsNotNull(metabolicRules["p1"]);
            Assert.AreEqual(1, metabolicRules["p1"].Count);
            Assert.IsNotNull(metabolicRules["p2"]);
            Assert.AreEqual(0, metabolicRules["p2"].Count);

            EvoMetabolicRule metabolicRule = metabolicRules["p1"][0];

            Assert.AreEqual(0, metabolicRule.Priority);
            Assert.AreEqual(EvolutionRule.RuleType.Metabolic, metabolicRule.Type);
            Assert.AreEqual(EvoMetabolicRule.MetabolicRuleType.Symport, metabolicRule.SubType);
            Assert.AreEqual(2, metabolicRule.LeftSideObjects.Count);
            Assert.AreEqual("a", metabolicRule.LeftSideObjects[0].Name);
            Assert.AreEqual("p1", metabolicRule.LeftSideObjects[1].Name);
            Assert.AreEqual(2, metabolicRule.RightSideObjects.Count);
            Assert.AreEqual("p1", metabolicRule.RightSideObjects[0].Name);
            Assert.AreEqual("a", metabolicRule.RightSideObjects[1].Name);
            Assert.AreEqual(0, metabolicRule.MLeftInNames.Count);
            Assert.AreEqual(1, metabolicRule.MLeftOutNames.Count);
            Assert.AreEqual(1, metabolicRule.MLeftOutNames.ToDictionary()["a"]);
            Assert.AreEqual(1, metabolicRule.MRightInNames.Count);
            Assert.AreEqual(1, metabolicRule.MRightInNames.ToDictionary()["a"]);
            Assert.AreEqual(0, metabolicRule.MRightOutNames.Count);
            Assert.AreEqual("p1", metabolicRule.RProtein.Name);


            //CreationRules
            Dictionary <Glue, IReadOnlyList <EvoNonMetabolicRule> > createRules = PSystem.CreationRules;

            Assert.AreEqual(3, createRules.Count);

            Glue pa = v_TestDeserializedMSystemObjects.Glues["pa"];
            Glue pb = v_TestDeserializedMSystemObjects.Glues["pb"];
            Glue px = v_TestDeserializedMSystemObjects.Glues["px"];

            Assert.IsNotNull(createRules[pa]);
            Assert.AreEqual(1, createRules[pa].Count);
            Assert.IsNotNull(createRules[pb]);
            Assert.AreEqual(1, createRules[pb].Count);
            Assert.IsNotNull(createRules[px]);
            Assert.AreEqual(0, createRules[px].Count);

            // For different glues there is the same creation rule - this is OK.
            EvoNonMetabolicRule createRulePA = createRules[pa][0];

            Assert.AreEqual(1, createRulePA.Priority);
            Assert.AreEqual(EvolutionRule.RuleType.Create, createRulePA.Type);
            Assert.AreEqual(3, createRulePA.LeftSideObjects.Count);
            Assert.AreEqual("a", createRulePA.LeftSideObjects[0].Name);
            Assert.AreEqual("a", createRulePA.LeftSideObjects[1].Name);
            Assert.AreEqual("a", createRulePA.LeftSideObjects[2].Name);
            Assert.AreEqual(1, createRulePA.RightSideObjects.Count);
            Assert.AreEqual("q1", createRulePA.RightSideObjects[0].Name);
            Assert.AreEqual(3, createRulePA.MLeftSideFloatingNames.Count);
            Assert.AreEqual(3, createRulePA.MLeftSideFloatingNames.ToDictionary()["a"]);
            Assert.AreEqual(0, createRulePA.MRightSideFloatingNames.Count);

            // For different glues there is the same creation rule - this is OK.
            EvoNonMetabolicRule createRulePB = createRules[pb][0];

            Assert.AreEqual(1, createRulePB.Priority);
            Assert.AreEqual(EvolutionRule.RuleType.Create, createRulePB.Type);
            Assert.AreEqual(3, createRulePB.LeftSideObjects.Count);
            Assert.AreEqual("a", createRulePB.LeftSideObjects[0].Name);
            Assert.AreEqual("a", createRulePB.LeftSideObjects[1].Name);
            Assert.AreEqual("a", createRulePB.LeftSideObjects[2].Name);
            Assert.AreEqual(1, createRulePB.RightSideObjects.Count);
            Assert.AreEqual("q1", createRulePB.RightSideObjects[0].Name);
            Assert.AreEqual(3, createRulePB.MLeftSideFloatingNames.Count);
            Assert.AreEqual(3, createRulePB.MLeftSideFloatingNames.ToDictionary()["a"]);
            Assert.AreEqual(0, createRulePB.MRightSideFloatingNames.Count);

            //DestructionRules
            var destructionRules = PSystem.DestructionRules;

            Assert.AreEqual(3, destructionRules.Count);
            Assert.IsNotNull(destructionRules["q1"]);
            Assert.AreEqual(0, destructionRules["q1"].Count);
            Assert.IsNotNull(destructionRules["s1"]);
            Assert.AreEqual(1, destructionRules["s1"].Count);

            EvoNonMetabolicRule destroyRule = destructionRules["s1"][0];

            Assert.AreEqual(1, destroyRule.Priority);
            Assert.AreEqual(EvolutionRule.RuleType.Destroy, destroyRule.Type);
            Assert.AreEqual(3, destroyRule.LeftSideObjects.Count);
            Assert.AreEqual("a", destroyRule.LeftSideObjects[0].Name);
            Assert.AreEqual("a", destroyRule.LeftSideObjects[1].Name);
            Assert.AreEqual("s1", destroyRule.LeftSideObjects[2].Name);
            Assert.AreEqual(2, destroyRule.RightSideObjects.Count);
            Assert.AreEqual("c", destroyRule.RightSideObjects[0].Name);
            Assert.AreEqual("c", destroyRule.RightSideObjects[1].Name);
            Assert.AreEqual(2, destroyRule.MLeftSideFloatingNames.Count);
            Assert.AreEqual(2, destroyRule.MLeftSideFloatingNames.ToDictionary()["a"]);
            Assert.AreEqual(2, destroyRule.MRightSideFloatingNames.Count);
            Assert.AreEqual(2, destroyRule.MRightSideFloatingNames.ToDictionary()["c"]);

            //DivisionRules
            var divisionRules = PSystem.DivisionRules;

            Assert.AreEqual(1, divisionRules.Count);

            Assert.IsNotNull(divisionRules[pa]);
            Assert.AreEqual(1, divisionRules[pa].Count);

            Assert.IsNotNull(divisionRules[pa][pa]);
            Assert.AreEqual(1, divisionRules[pa][pa].Count);

            EvoNonMetabolicRule divideRule = divisionRules[pa][pa][0];

            Assert.AreEqual(1, divideRule.Priority);
            Assert.AreEqual(EvolutionRule.RuleType.Divide, divideRule.Type);
            Assert.AreEqual(4, divideRule.LeftSideObjects.Count);
            Assert.AreEqual("pa", divideRule.LeftSideObjects[0].Name);
            Assert.AreEqual("pa", divideRule.LeftSideObjects[1].Name);
            Assert.AreEqual("a", divideRule.LeftSideObjects[2].Name);
            Assert.AreEqual("a", divideRule.LeftSideObjects[3].Name);
            Assert.AreEqual(2, divideRule.RightSideObjects.Count);
            Assert.AreEqual("pa", divideRule.RightSideObjects[0].Name);
            Assert.AreEqual("pa", divideRule.RightSideObjects[1].Name);
            Assert.AreEqual(2, divideRule.MLeftSideFloatingNames.Count);
            Assert.AreEqual(2, divideRule.MLeftSideFloatingNames.ToDictionary()["a"]);
            Assert.AreEqual(0, divideRule.MRightSideFloatingNames.Count);
        }
예제 #15
0
        public static bool CheckForCollisions(PSystem system, Planet pp, int PlanetApartDistanceToCheck)
        {
            if (system.PlanetCount >= 1)
            {
                float planet1PosX = 0, planet1PosY = 0;
                float planet2PosX = 0, planet2PosY = 0;
                float moon2PosX, moon2PosY;
                foreach (Planet p in system.GetPlanets())
                {
                    // Planet 1 Calculation
                    GetPosition(p, out planet1PosX, out planet1PosY);

                    // Planet 2 Calculation
                    GetPosition(pp, out planet2PosX, out planet2PosY);


                    // Distance check between points
                    float Distance = Distance2D(planet1PosX, planet1PosY, planet2PosX, planet2PosY);

                    if (Distance < PlanetApartDistanceToCheck) // Collision between planets
                    {
                        return(true);
                    }
                }
                if (system.MoonCount <= 0) // Only continue if we've got moons, otherwise we're done.
                {
                    return(false);
                }
                foreach (Planet m in system.GetMoons())
                {
                    if (m.IDToOrbit == pp.Id) // If we're checking parent, skip
                    {
                        continue;
                    }

                    foreach (Planet p in system.GetPlanets())
                    {
                        if (m.IDToOrbit != p.Id) // If we're checking parent, skip
                        {
                            continue;
                        }

                        // Planet 1 Calculation
                        GetPosition(p, out planet1PosX, out planet1PosY);

                        // Moon calculation
                        GetPosition(m, planet1PosX, planet1PosY, out moon2PosX, out moon2PosY);

                        // Distance check between points
                        float Distance;
                        Distance = Distance2D(planet2PosX, planet2PosY, moon2PosX, moon2PosY);

                        if (Distance < PlanetApartDistanceToCheck) // Collision between planets and moons
                        {
                            return(true);
                        }
                    }
                }
            }
            return(false); // Return false if no collisions
        }
예제 #16
0
 public static bool CheckForCollisions(PSystem p, Planet pp, Planet moon, GalaxyManager gm)
 {
     return(CheckForCollisions(p, pp, moon, planetDistanceApart, moonDistanceFromSun, moonDistanceApart, gm));
 }
        public static PSystemBody GenerateSystemBody(PSystem system, PSystemBody parent, String name, Orbit orbit = null)
        {
            PSystemBody Jool = Utility.FindBody (system.rootBody, "Jool");  // Need the geosphere for scaled version
            PSystemBody Laythe = Utility.FindBody (system.rootBody, "Laythe"); // Need pqs and ocean definitions

            //Utility.DumpObject (Laythe.celestialBody, " Laythe Celestial Body ");
            //Utility.DumpObject (Laythe.pqsVersion, " Laythe PQS ");
            //Transform laytheOcean = Utility.FindInChildren (Laythe.pqsVersion.transform, "LaytheOcean");
            //Utility.DumpObject (laytheOcean.GetComponent<PQS> (), " Laythe Ocean PQS ");

            // AddBody makes the GameObject and stuff. It also attaches it to the system and parent.
            PSystemBody body = system.AddBody (parent);

            // set up the various parameters
            body.name = name;
            body.flightGlobalsIndex = 100;

            // Some parameters of the celestialBody, which represents the actual planet...
            // PSystemBody is more of a container that associates the planet with its orbit
            // and position in the planetary system, etc.
            body.celestialBody.bodyName               = name;
            body.celestialBody.bodyDescription        = "Merciful Kod, this thing just APPEARED! And unlike last time, it wasn't bird droppings on the telescope.";
            body.celestialBody.Radius                 = 320000;
            //body.celestialBody.Radius                 = 3380100;
            body.celestialBody.GeeASL                 = 0.3;
            //body.celestialBody.Mass                   = 6.4185E+23;
            body.celestialBody.Mass                   = 4.5154812E+21;
            body.celestialBody.timeWarpAltitudeLimits = (float[])Laythe.celestialBody.timeWarpAltitudeLimits.Clone();
            body.celestialBody.rotationPeriod         = 88642.6848;
            body.celestialBody.rotates                = true;
            body.celestialBody.BiomeMap               = GenerateCBAttributeMapSO(name);//Dres.celestialBody.BiomeMap;//
            body.celestialBody.scienceValues          = Laythe.celestialBody.scienceValues;
            body.celestialBody.ocean                  = false;

            // Presumably true of Kerbin. I do not know what the consequences are of messing with this exactly.
            // I think this just affects where the Planetarium/Tracking station starts.
            body.celestialBody.isHomeWorld            = false;

            // Setup the orbit of "Kopernicus."  The "Orbit" class actually is built to support serialization straight
            // from Squad, so storing these to files (and loading them) will be pretty easy.
            body.orbitRenderer.orbitColor             = Color.magenta;
            body.orbitDriver.celestialBody            = body.celestialBody;
            body.orbitDriver.updateMode               = OrbitDriver.UpdateMode.UPDATE;
            if (orbit == null)
                body.orbitDriver.orbit = new Orbit (0.0, 0.0, 47500000000, 0, 0, 0, 0, system.rootBody.celestialBody);
            else
                body.orbitDriver.orbit = orbit;

            #region PSystemBody.pqsVersion generation

            // Create the PQS controller game object for Kopernicus
            GameObject controllerRoot       = new GameObject(name);
            controllerRoot.layer            = Constants.GameLayers.LocalSpace;
            controllerRoot.transform.parent = Utility.Deactivator;

            // Create the PQS object and pull all the values from Dres (has some future proofing i guess? adapts to PQS changes)
            body.pqsVersion = controllerRoot.AddComponent<PQS>();
            Utility.CopyObjectFields(Laythe.pqsVersion, body.pqsVersion);
            //body.pqsVersion.surfaceMaterial = new PQSProjectionSurfaceQuad();
            //body.pqsVersion.fallbackMaterial = new PQSProjectionFallback();
            body.pqsVersion.surfaceMaterial = new PQSProjectionAerialQuadRelative(Laythe.pqsVersion.surfaceMaterial); // use until we determine all the functions of the shader textures
            body.pqsVersion.fallbackMaterial = new PQSProjectionFallback(Laythe.pqsVersion.fallbackMaterial);
            body.pqsVersion.radius = body.celestialBody.Radius;
            body.pqsVersion.mapOcean = false;

            // Debug
            Utility.DumpObjectProperties(body.pqsVersion.surfaceMaterial, " Surface Material ");
            Utility.DumpObjectProperties(body.pqsVersion.fallbackMaterial, " Fallback Material ");

            // Detail defaults
            body.pqsVersion.maxQuadLenghtsPerFrame = 0.03f;
            body.pqsVersion.minLevel = 1;
            body.pqsVersion.maxLevel = 10;
            body.pqsVersion.minDetailDistance = 8;

            // Create the celestial body transform
            GameObject mod = new GameObject("_CelestialBody");
            mod.transform.parent = controllerRoot.transform;
            PQSMod_CelestialBodyTransform celestialBodyTransform = mod.AddComponent<PQSMod_CelestialBodyTransform>();
            celestialBodyTransform.sphere = body.pqsVersion;
            celestialBodyTransform.forceActivate = false;
            celestialBodyTransform.deactivateAltitude = 115000;
            celestialBodyTransform.forceRebuildOnTargetChange = false;
            celestialBodyTransform.planetFade = new PQSMod_CelestialBodyTransform.AltitudeFade();
            celestialBodyTransform.planetFade.fadeFloatName = "_PlanetOpacity";
            celestialBodyTransform.planetFade.fadeStart = 100000.0f;
            celestialBodyTransform.planetFade.fadeEnd = 110000.0f;
            celestialBodyTransform.planetFade.valueStart = 0.0f;
            celestialBodyTransform.planetFade.valueEnd = 1.0f;
            celestialBodyTransform.planetFade.secondaryRenderers = new List<GameObject>();
            celestialBodyTransform.secondaryFades = new PQSMod_CelestialBodyTransform.AltitudeFade[0];
            celestialBodyTransform.requirements = PQS.ModiferRequirements.Default;
            celestialBodyTransform.modEnabled = true;
            celestialBodyTransform.order = 10;

            // Create the color PQS mods
            mod = new GameObject("_Color");
            mod.transform.parent = controllerRoot.transform;
            PQSMod_VertexSimplexNoiseColor vertexSimplexNoiseColor = mod.AddComponent<PQSMod_VertexSimplexNoiseColor>();
            vertexSimplexNoiseColor.sphere = body.pqsVersion;
            vertexSimplexNoiseColor.seed = 45;
            vertexSimplexNoiseColor.blend = 1.0f;
            vertexSimplexNoiseColor.colorStart = new Color(0.768656731f, 0.6996614f, 0.653089464f, 1);
            vertexSimplexNoiseColor.colorEnd = new Color(0.0f, 0.0f, 0.0f, 1.0f);
            vertexSimplexNoiseColor.octaves = 12.0;
            vertexSimplexNoiseColor.persistence = 0.5;
            vertexSimplexNoiseColor.frequency = 2.0;
            vertexSimplexNoiseColor.requirements = PQS.ModiferRequirements.MeshColorChannel;
            vertexSimplexNoiseColor.modEnabled = true;
            vertexSimplexNoiseColor.order = 200;

            PQSMod_HeightColorMap heightColorMap = mod.AddComponent<PQSMod_HeightColorMap>();
            heightColorMap.sphere = body.pqsVersion;
            List<PQSMod_HeightColorMap.LandClass> landClasses = new List<PQSMod_HeightColorMap.LandClass>();

            PQSMod_HeightColorMap.LandClass landClass = new PQSMod_HeightColorMap.LandClass("AbyPl", 0.0, 0.5, new Color(0.0f, 0.0f, 0.0f, 1.0f), Color.white, double.NaN);
            landClass.lerpToNext = true;
            landClasses.Add(landClass);

            landClass = new PQSMod_HeightColorMap.LandClass("Beach", 0.5, 0.550000011920929, new Color(0.164179087f, 0.164179087f, 0.164179087f, 1.0f), Color.white, double.NaN);
            landClass.lerpToNext = true;
            landClasses.Add(landClass);

            landClass = new PQSMod_HeightColorMap.LandClass("Beach", 0.550000011920929, 1.0, new Color(0.373134315f, 0.373134315f, 0.373134315f, 1.0f), Color.white, double.NaN);
            landClass.lerpToNext = false;
            landClasses.Add(landClass);

            // Generate an array from the land classes list
            heightColorMap.landClasses = landClasses.ToArray();
            heightColorMap.blend = 0.7f;
            heightColorMap.lcCount = 3;
            heightColorMap.requirements = PQS.ModiferRequirements.MeshColorChannel;
            heightColorMap.modEnabled = true;
            heightColorMap.order = 201;

            // Create the alititude alpha mods
            mod = new GameObject("_Material_ModProjection");
            mod.transform.parent = controllerRoot.transform;
            PQSMod_AltitudeAlpha altitudeAlpha = mod.AddComponent<PQSMod_AltitudeAlpha>();
            altitudeAlpha.sphere = body.pqsVersion;
            altitudeAlpha.atmosphereDepth = 4000.0;
            altitudeAlpha.invert = false;
            altitudeAlpha.requirements = PQS.ModiferRequirements.Default;
            altitudeAlpha.modEnabled = false;
            altitudeAlpha.order = 999999999;

            // Create the aerial perspective material
            mod = new GameObject("_Material_AerialPerspective");
            mod.transform.parent = controllerRoot.transform;
            PQSMod_AerialPerspectiveMaterial aerialPerspectiveMaterial = mod.AddComponent<PQSMod_AerialPerspectiveMaterial>();
            aerialPerspectiveMaterial.sphere = body.pqsVersion;
            aerialPerspectiveMaterial.globalDensity = -0.00001f;
            aerialPerspectiveMaterial.heightFalloff = 6.75f;
            aerialPerspectiveMaterial.atmosphereDepth = 150000;
            aerialPerspectiveMaterial.DEBUG_SetEveryFrame = true;
            aerialPerspectiveMaterial.cameraAlt = 0;
            aerialPerspectiveMaterial.cameraAtmosAlt = 0;
            aerialPerspectiveMaterial.heightDensAtViewer = 0;
            aerialPerspectiveMaterial.requirements = PQS.ModiferRequirements.Default;
            aerialPerspectiveMaterial.modEnabled = true;
            aerialPerspectiveMaterial.order = 100;

            // Create the UV planet relative position
            mod = new GameObject("_Material_SurfaceQuads");
            mod.transform.parent = controllerRoot.transform;
            PQSMod_UVPlanetRelativePosition planetRelativePosition = mod.AddComponent<PQSMod_UVPlanetRelativePosition>();
            planetRelativePosition.sphere = body.pqsVersion;
            planetRelativePosition.requirements = PQS.ModiferRequirements.Default;
            planetRelativePosition.modEnabled = true;
            planetRelativePosition.order = 999999;

            // Create the height noise module
            mod = new GameObject("_HeightNoise");
            mod.transform.parent = controllerRoot.transform;
            PQSMod_VertexHeightMap vertexHeightMap = mod.gameObject.AddComponent<PQSMod_VertexHeightMap>();
            vertexHeightMap.sphere = body.pqsVersion;
            //vertexHeightMap.heightMapDeformity = 29457.0;
            vertexHeightMap.heightMapDeformity = 10000.0;
            vertexHeightMap.heightMapOffset = -1000.0;
            vertexHeightMap.scaleDeformityByRadius = false;
            vertexHeightMap.requirements = PQS.ModiferRequirements.MeshCustomNormals | PQS.ModiferRequirements.VertexMapCoords;
            vertexHeightMap.modEnabled = true;
            vertexHeightMap.order = 20;

            // Load the heightmap for this planet
            Texture2D map = new Texture2D(4, 4, TextureFormat.Alpha8, false);
            map.LoadImage(System.IO.File.ReadAllBytes(KSPUtil.ApplicationRootPath + PluginDirectory + "/Planets/" + name + "/Height.png"));
            vertexHeightMap.heightMap = ScriptableObject.CreateInstance<MapSO>();
            vertexHeightMap.heightMap.CreateMap(MapSO.MapDepth.Greyscale, map);
            UnityEngine.Object.DestroyImmediate(map);

            // Create the simplex height module
            PQSMod_VertexSimplexHeight vertexSimplexHeight = mod.AddComponent<PQSMod_VertexSimplexHeight>();
            vertexSimplexHeight.sphere = body.pqsVersion;
            vertexSimplexHeight.seed = 670000;
            vertexSimplexHeight.deformity = 1700.0;
            vertexSimplexHeight.octaves = 12.0;
            vertexSimplexHeight.persistence = 0.5;
            vertexSimplexHeight.frequency = 4.0;
            vertexSimplexHeight.requirements = PQS.ModiferRequirements.MeshCustomNormals;
            vertexSimplexHeight.modEnabled = true;
            vertexSimplexHeight.order = 21;

            // SERIOUSLY RECOMMENDED FOR NO OCEAN WORLDS
            // Create the flatten ocean module
            PQSMod_FlattenOcean flattenOcean = mod.AddComponent<PQSMod_FlattenOcean>();
            flattenOcean.sphere = body.pqsVersion;
            flattenOcean.oceanRadius = 1.0;
            flattenOcean.requirements = PQS.ModiferRequirements.MeshCustomNormals;
            flattenOcean.modEnabled = true;
            flattenOcean.order = 25;

            // Creat the vertex height noise module
            PQSMod_VertexHeightNoise vertexHeightNoise = mod.AddComponent<PQSMod_VertexHeightNoise>();
            vertexHeightNoise.sphere = body.pqsVersion;
            vertexHeightNoise.noiseType = PQSMod_VertexHeightNoise.NoiseType.RiggedMultifractal;
            vertexHeightNoise.deformity = 1000.0f;
            vertexHeightNoise.seed = 5906;
            vertexHeightNoise.frequency = 2.0f;
            vertexHeightNoise.lacunarity = 2.5f;
            vertexHeightNoise.persistance = 0.5f;
            vertexHeightNoise.octaves = 4;
            vertexHeightNoise.mode = LibNoise.Unity.QualityMode.Low;
            vertexHeightNoise.requirements = PQS.ModiferRequirements.MeshColorChannel;
            vertexHeightNoise.modEnabled = true;
            vertexHeightNoise.order = 22;

            // Create the material direction
            mod = new GameObject("_Material_SunLight");
            mod.transform.parent = controllerRoot.gameObject.transform;
            PQSMod_MaterialSetDirection materialSetDirection = mod.AddComponent<PQSMod_MaterialSetDirection>();
            materialSetDirection.sphere = body.pqsVersion;
            materialSetDirection.valueName = "_sunLightDirection";
            materialSetDirection.requirements = PQS.ModiferRequirements.Default;
            materialSetDirection.modEnabled = true;
            materialSetDirection.order = 100;

            // Crete the quad mesh colliders
            mod = new GameObject("QuadMeshColliders");
            mod.transform.parent = controllerRoot.gameObject.transform;
            PQSMod_QuadMeshColliders quadMeshColliders = mod.AddComponent<PQSMod_QuadMeshColliders>();
            quadMeshColliders.sphere = body.pqsVersion;
            quadMeshColliders.maxLevelOffset = 0;
            quadMeshColliders.physicsMaterial = new PhysicMaterial();
            quadMeshColliders.physicsMaterial.name = "Ground";
            quadMeshColliders.physicsMaterial.dynamicFriction = 0.6f;
            quadMeshColliders.physicsMaterial.staticFriction = 0.8f;
            quadMeshColliders.physicsMaterial.bounciness = 0.0f;
            quadMeshColliders.physicsMaterial.frictionDirection2 = Vector3.zero;
            quadMeshColliders.physicsMaterial.dynamicFriction2 = 0.0f;
            quadMeshColliders.physicsMaterial.staticFriction2 = 0.0f;
            quadMeshColliders.physicsMaterial.frictionCombine = PhysicMaterialCombine.Maximum;
            quadMeshColliders.physicsMaterial.bounceCombine = PhysicMaterialCombine.Average;
            quadMeshColliders.requirements = PQS.ModiferRequirements.Default;
            quadMeshColliders.modEnabled = true;
            quadMeshColliders.order = 100;

            // Create the simplex height absolute
            mod = new GameObject("_FineDetail");
            mod.transform.parent = controllerRoot.gameObject.transform;
            PQSMod_VertexSimplexHeightAbsolute vertexSimplexHeightAbsolute = mod.AddComponent<PQSMod_VertexSimplexHeightAbsolute>();
            vertexSimplexHeightAbsolute.sphere = body.pqsVersion;
            vertexSimplexHeightAbsolute.seed = 4234;
            vertexSimplexHeightAbsolute.deformity = 400.0;
            vertexSimplexHeightAbsolute.octaves = 6.0;
            vertexSimplexHeightAbsolute.persistence = 0.5;
            vertexSimplexHeightAbsolute.frequency = 18.0;
            vertexSimplexHeightAbsolute.requirements = PQS.ModiferRequirements.Default;
            vertexSimplexHeightAbsolute.modEnabled = true;
            vertexSimplexHeightAbsolute.order = 30;

            // Surface color map
            mod = new GameObject("_LandClass");
            mod.transform.parent = body.pqsVersion.gameObject.transform;
            PQSMod_VertexColorMap colorMap = mod.AddComponent<PQSMod_VertexColorMap>();
            colorMap.sphere = body.pqsVersion;
            colorMap.order = 500;
            colorMap.modEnabled = true;

            // Decompress and load the color
            map = new Texture2D(4, 4, TextureFormat.RGB24, false);
            map.LoadImage(System.IO.File.ReadAllBytes(KSPUtil.ApplicationRootPath + PluginDirectory + "/Planets/" + name + "/Color.png"));
            colorMap.vertexColorMap = ScriptableObject.CreateInstance<MapSO>();
            colorMap.vertexColorMap.CreateMap(MapSO.MapDepth.RGB, map);
            UnityEngine.Object.DestroyImmediate(map);

            #endregion

            #region PSystemBody.scaledVersion generation

            // Create the scaled version of the planet for use in map view
            body.scaledVersion = new GameObject(name);
            body.scaledVersion.layer = Constants.GameLayers.ScaledSpace;
            body.scaledVersion.transform.parent = Utility.Deactivator;

            // DEPRECATED - USE PQSMeshWrapper
            // Make sure the scaled version cooresponds to the size of the body
            // Turns out that the localScale is directly related to the planet size.
            // Jool's local scale is {1,1,1}, Kerbin's is {0.1,0.1,0.1}.  Jool's
            // radius is 6000 km, Kerbin's is 600 km.  Notice the relation?
            float scale = (float) body.celestialBody.Radius / 6000000.0f;
            body.scaledVersion.transform.localScale = new Vector3(scale, scale, scale);

            // Generate a mesh to fit the PQS we generated (it would be cool to generate this FROM the PQS)
            Mesh mesh = new Mesh();
            Utility.CopyMesh(Jool.scaledVersion.GetComponent<MeshFilter>().sharedMesh, mesh);

            // Iterate though the UVs
            // Geosphere with a radius of 1000, cooresponds to an object 6000km in radius
            Vector3[] vertices = mesh.vertices;
            for(int i = 0; i < mesh.vertexCount; i++)
            {
                // Get the height offset from the height map
                Vector2 uv = mesh.uv[i];
                float displacement = vertexHeightMap.heightMap.GetPixelFloat(uv.x, uv.y);

                // Since this is a geosphere, normalizing the vertex gives the vector to translate on
                Vector3 v = vertices[i];
                v.Normalize();

                // Calculate the real height displacement (in meters), normalized vector "v" scale (1 unit = 6 km)
                displacement = (float) vertexHeightMap.heightMapOffset + (displacement * (float) vertexHeightMap.heightMapDeformity);
                Vector3 offset = v * ((displacement / 6000.0f) / scale);

                // Adjust the displacement
                vertices[i] += offset;
            }
            mesh.vertices = vertices;
            mesh.RecalculateNormals();

            // Create the mesh filter
            MeshFilter meshFilter = body.scaledVersion.AddComponent<MeshFilter> ();
            meshFilter.mesh = mesh;

            // Load and compress the color texture for the custom planet
            Texture2D colorTexture = new Texture2D(4, 4, TextureFormat.RGBA32, true);
            colorTexture.LoadImage(System.IO.File.ReadAllBytes(KSPUtil.ApplicationRootPath + PluginDirectory + "/Planets/" + name + "/Color.png"));
            colorTexture.Compress(true);
            colorTexture.Apply(true, true);

            // Load and compress the color texture for the custom planet
            Texture2D normalTexture = new Texture2D(4, 4, TextureFormat.RGB24, true);
            normalTexture.LoadImage(System.IO.File.ReadAllBytes(KSPUtil.ApplicationRootPath + PluginDirectory + "/Planets/" + name + "/Normals.png"));
            //normalTexture = GameDatabase.BitmapToUnityNormalMap(normalTexture);
            normalTexture.Compress(true);
            normalTexture.Apply(true, true);

            // Create the renderer and material for the scaled version
            MeshRenderer renderer = body.scaledVersion.AddComponent<MeshRenderer>();
            //ScaledPlanetSimple material = new ScaledPlanetSimple();   // for atmosphereless planets
            ScaledPlanetRimAerial material = new ScaledPlanetRimAerial();
            material.color       = Color.white;
            material.specColor   = Color.black;
            material.mainTexture = colorTexture;
            material.bumpMap     = normalTexture;
            renderer.material    = material;

            // Create the sphere collider
            SphereCollider collider = body.scaledVersion.AddComponent<SphereCollider> ();
            collider.center         = Vector3.zero;
            collider.radius         = 1000.0f;

            // Create the ScaledSpaceFader to fade the orbit out where we view it (maybe?)
            ScaledSpaceFader fader = body.scaledVersion.AddComponent<ScaledSpaceFader> ();
            fader.celestialBody    = body.celestialBody;
            fader.fadeStart        = 95000.0f;
            fader.fadeEnd          = 100000.0f;
            fader.floatName        = "_Opacity";

            #endregion

            #region Atmosphere
            //--------------------- PROPERTIES EXCLUSIVE TO BODIES WITH ATMOSPHERE

            // Load the atmosphere gradient (compress it, does not need to be high quality)
            Texture2D atmosphereGradient = new Texture2D(4, 4, TextureFormat.RGB24, true);
            atmosphereGradient.LoadImage(System.IO.File.ReadAllBytes(KSPUtil.ApplicationRootPath + PluginDirectory + "/Planets/" + name + "/AtmosphereGradient.png"));
            atmosphereGradient.Compress(true);
            atmosphereGradient.wrapMode = TextureWrapMode.Clamp;
            atmosphereGradient.mipMapBias = 0.0f;
            atmosphereGradient.Apply(true, true);

            // Set the additional settings in the scaledVersion body's shader
            material.rimPower = 2.06f;
            material.rimBlend = 0.3f;
            material.rimColorRamp = atmosphereGradient;

            // Atmosphere specific properties (for scaled version root) (copied from duna)
            MaterialSetDirection materialLightDirection = body.scaledVersion.AddComponent<MaterialSetDirection>();
            materialLightDirection.valueName            = "_localLightDirection";

            // Create the atmosphere shell itself
            GameObject scaledAtmosphere               = new GameObject("atmosphere");
            scaledAtmosphere.transform.parent         = body.scaledVersion.transform;
            scaledAtmosphere.layer                    = Constants.GameLayers.ScaledSpaceAtmosphere;
            meshFilter                                = scaledAtmosphere.AddComponent<MeshFilter>();
            meshFilter.sharedMesh                     = Jool.scaledVersion.GetComponent<MeshFilter>().sharedMesh;
            renderer                                  = scaledAtmosphere.AddComponent<MeshRenderer>();
            renderer.material                         = new Kopernicus.MaterialWrapper.AtmosphereFromGround();
            AtmosphereFromGround atmosphereRenderInfo = scaledAtmosphere.AddComponent<AtmosphereFromGround>();
            atmosphereRenderInfo.waveLength           = new Color(0.509f, 0.588f, 0.643f, 0.000f);

            // Technical info for atmosphere
            body.celestialBody.atmosphere = true;
            body.celestialBody.atmosphereContainsOxygen = true;
            body.celestialBody.staticPressureASL = 1.0; // can't find anything that references this, especially with the equation in mind - where is this used?
            body.celestialBody.altitudeMultiplier = 1.4285f; // ditto
            body.celestialBody.atmosphereScaleHeight = 4.0;   // pressure (in atm) = atmosphereMultipler * e ^ -(altitude / (atmosphereScaleHeight * 1000))
            body.celestialBody.atmosphereMultiplier = 0.8f;
            body.celestialBody.atmoshpereTemperatureMultiplier = 1.0f; // how does this coorespond?
            body.celestialBody.maxAtmosphereAltitude = 55000.0f;  // i guess this is so the math doesn't drag out?
            body.celestialBody.useLegacyAtmosphere = true;
            body.celestialBody.atmosphericAmbientColor = new Color(0.306f, 0.187f, 0.235f, 1.000f);
            #endregion

            #region Ocean
            // ---------------- FOR BODIES WITH OCEANS ----------
            /*body.celestialBody.ocean = true;

            // Setup the laythe ocean info in master pqs
            body.pqsVersion.mapOcean = true;
            body.pqsVersion.mapOceanColor = new Color(0.117f, 0.126f, 0.157f, 1.000f);
            body.pqsVersion.mapOceanHeight = 0.0f;

            // Generate the PQS object
            GameObject oceanRoot       = new GameObject(name + "Ocean");
            oceanRoot.transform.parent = body.pqsVersion.transform;
            oceanRoot.layer            = Constants.GameLayers.LocalSpace;
            PQS oceanPQS               = oceanRoot.AddComponent<PQS>();

            // Add this new PQS to the secondary renderers of the altitude fade controller
            celestialBodyTransform.planetFade.secondaryRenderers.Add(oceanRoot);

            // Setup the PQS object data
            Utility.CopyObjectFields<PQS>(laytheOcean.GetComponent<PQS>(), oceanPQS);
            oceanPQS.radius            = body.pqsVersion.radius;
            oceanPQS.surfaceMaterial   = new PQSOceanSurfaceQuad(laytheOcean.GetComponent<PQS>().surfaceMaterial);
            oceanPQS.fallbackMaterial  = new PQSOceanSurfaceQuadFallback(laytheOcean.GetComponent<PQS>().fallbackMaterial);
            Utility.DumpObjectProperties(oceanPQS.surfaceMaterial, oceanPQS.surfaceMaterial.ToString());
            Utility.DumpObjectProperties(oceanPQS.fallbackMaterial, oceanPQS.fallbackMaterial.ToString());

            // Create the aerial perspective material
            mod = new GameObject("_Material_AerialPerspective");
            mod.transform.parent = oceanRoot.transform;
            aerialPerspectiveMaterial = mod.AddComponent<PQSMod_AerialPerspectiveMaterial>();
            aerialPerspectiveMaterial.sphere = body.pqsVersion;
            aerialPerspectiveMaterial.globalDensity = -0.00001f;
            aerialPerspectiveMaterial.heightFalloff = 6.75f;
            aerialPerspectiveMaterial.atmosphereDepth = 150000;
            aerialPerspectiveMaterial.DEBUG_SetEveryFrame = true;
            aerialPerspectiveMaterial.cameraAlt = 0;
            aerialPerspectiveMaterial.cameraAtmosAlt = 0;
            aerialPerspectiveMaterial.heightDensAtViewer = 0;
            aerialPerspectiveMaterial.requirements = PQS.ModiferRequirements.Default;
            aerialPerspectiveMaterial.modEnabled = true;
            aerialPerspectiveMaterial.order = 100;

            // Create the UV planet relative position
            mod = new GameObject("_Material_SurfaceQuads");
            mod.transform.parent = oceanRoot.transform;
            planetRelativePosition = mod.AddComponent<PQSMod_UVPlanetRelativePosition>();
            planetRelativePosition.sphere = body.pqsVersion;
            planetRelativePosition.requirements = PQS.ModiferRequirements.Default;
            planetRelativePosition.modEnabled = true;
            planetRelativePosition.order = 100;

            // Create the quad map remover (da f**k?)
            mod = new GameObject("QuadRemoveMap");
            mod.transform.parent = oceanRoot.transform;
            PQSMod_RemoveQuadMap removeQuadMap = mod.AddComponent<PQSMod_RemoveQuadMap>();
            removeQuadMap.mapDeformity = 0.0f;
            removeQuadMap.minHeight = 0.0f;
            removeQuadMap.maxHeight = 0.5f;
            removeQuadMap.requirements = PQS.ModiferRequirements.Default;
            removeQuadMap.modEnabled = true;
            removeQuadMap.order = 1000;

            // Load the heightmap into whatever the hell this is
            map = new Texture2D(4, 4, TextureFormat.Alpha8, false);
            map.LoadImage(System.IO.File.ReadAllBytes(KSPUtil.ApplicationRootPath + PluginDirectory + "/Planets/" + name + "/Height.png"));
            removeQuadMap.map = ScriptableObject.CreateInstance<MapSO>();
            removeQuadMap.map.CreateMap(MapSO.MapDepth.Greyscale, map);
            UnityEngine.Object.DestroyImmediate(map);

            // Setup the ocean effects
            mod = new GameObject("OceanFX");
            mod.transform.parent = oceanRoot.transform;
            PQSMod_OceanFX oceanFX = mod.AddComponent<PQSMod_OceanFX>();
            oceanFX.watermain = Utility.RecursivelyGetComponent<PQSMod_OceanFX>(laytheOcean).watermain.Clone() as Texture2D[];
            oceanFX.requirements = PQS.ModiferRequirements.Default;
            oceanFX.modEnabled = true;
            oceanFX.order = 100;*/

            #endregion

            // Return the new body
            return body;
        }
예제 #18
0
        public static bool CheckForCollisions(PSystem system, Planet pp, Planet moon, int planetDistanceApart,
                                              int moonDistanceFromSun, int moonDistanceApart, GalaxyManager galaxyManager)
        {
            // Generate locations of: Other planet, basePlanetPos+MoonPos, OtherMoonParentPos+MoonPos
            if (system.PlanetCount >= 1)
            {
                float moon1PosX = 0, moon1PosY = 0; // Outside because used twice
                float Distance;
                foreach (Planet p in system.GetPlanets())
                {
                    if (moon.IDToOrbit == p.Id)
                    {
                        continue;
                    }

                    // Planet 1 Calculation
                    float planet1PosX, planet1PosY;
                    GetPosition(p, out planet1PosX, out planet1PosY);


                    // Planet 2 Calculation
                    float planet2PosX, planet2PosY;
                    GetPosition(pp, out planet2PosX, out planet2PosY);


                    // Moon 1 Calculation
                    GetPosition(moon, planet2PosX, planet2PosY, out moon1PosX, out moon1PosY);


                    // Distance check between points
                    Distance = Distance2D(planet1PosX, planet1PosY, moon1PosX, moon1PosY);

                    if (Distance < planetDistanceApart) // We don't want moons too close to other planets!
                    {
                        return(true);
                    }

                    // Distance check between points
                    Distance = Distance2D(0, 0, moon1PosX, moon1PosY); // Assuming sun is 0,0

                    if (Distance < moonDistanceFromSun)                // We don't want moons too close to the sun!
                    {
                        return(true);
                    }
                }

                // This is in a second forloop because otherwise we do waaaay extra calculations
                foreach (Planet m in system.GetMoons())
                {
                    // We need to get the parent planet to get the location
                    // Planet 1 Calculation
                    float planetParentPosX, planetParentPosY;
                    GetPosition((Planet)galaxyManager.GetArea(m.IDToOrbit), out planetParentPosX, out planetParentPosY);

                    // Moon 2 Calculation
                    float moon2PosX, moon2PosY;
                    GetPosition(m, planetParentPosX, planetParentPosY, out moon2PosX, out moon2PosY);

                    // Distance check between points
                    Distance = Distance2D(moon1PosX, moon1PosY, moon2PosX, moon2PosY);

                    if (Distance < moonDistanceApart) // We don't want moons too close to other moons!
                    {
                        return(true);
                    }
                }
            }
            return(false); // Return false if no collisions
        }
예제 #19
0
        /// <summary>
        /// Generates n moons for a single planet, where n is divined from some mystical voodoo black magic related to planet.Scale
        /// </summary>
        /// <param name="system"></param>
        /// <param name="planet"></param>
        /// <param name="galaxyManager"></param>
        /// <param name="idManager"></param>
        /// <param name="rm"></param>
        /// <param name="pl"></param>
        /// <param name="al"></param>
        /// <param name="sl"></param>
        /// <param name="tl"></param>
        /// <param name="mem"></param>
        static void _generateMoons(PSystem system, Planet planet, GalaxyManager galaxyManager, LocalIDManager idManager, GalaxyRegistrationManager rm, LocatorService ls)
        {
            // If any moons, add them
            if (planet.HasMoons)
            {
                int parentID = planet.Id;

                int numMoons = 0;

                // Creates moon based on scale of size
                switch (planet.Scale)
                {
                case 0:
                case 1:
                case 2:
                case 3:
                case 4:
                case 5:
                    planet.PlanetType = (PlanetTypes)r.Next(0, (int)PlanetTypes.OceanicSmall + 1);
                    planet.Scale     += 3; // Makes the small sprites scale better
                    break;

                case 6:
                case 7:
                    planet.PlanetType = (PlanetTypes)r.Next(0, (int)PlanetTypes.OceanicSmall + 1);
                    if (planet.PlanetType >= PlanetTypes.Crystalline &&
                        planet.PlanetType < PlanetTypes.Port)
                    {
                        planet.Scale += 3;     // Makes the small sprites scale better
                    }
                    numMoons = r.Next(3) + 2;
                    break;

                case 8:
                case 9:
                    numMoons = r.Next(2) + 3;
                    break;

                case 10:
                case 11:
                case 12:
                    numMoons = r.Next(3) + 3;
                    break;
                }

                for (int m = 0; m < numMoons; m++)
                {
                    Planet moon;

                    moon = new Planet(planet, idManager.PopFreeID(), ls);
                    InitializeMoon(moon, m, moonMinimumDistance, moonIncrementOfOrbit * m, moonVariationOfOrbit, planet, planet.Id,
                                   r.Next());


                    if (moon.PlanetType >= PlanetTypes.Crystalline &&
                        moon.PlanetType < PlanetTypes.Port)
                    {
                        moon.Scale += 3; // Makes the small sprites scale better
                    }
                    // #Yolo
                    moon.AreaName = planet.AreaName + "abcdefghijklmnopqrstuvwxyz"[m];

                    bool SatisfiedWithResults = false;
                    int  maxAttempts          = 200;
                    int  numAttempts          = 0;

                    while (!SatisfiedWithResults)// While we're not content with the generation
                    {
                        // Add moons
                        moon = new Planet(planet, moon.Id, ls);
                        InitializeMoon(moon, m, moonMinimumDistance, moonIncrementOfOrbit * m, moonVariationOfOrbit, planet, planet.Id,
                                       r.Next());
                        // Add another while here to check for maxDistance, as well as an If for if the system should follow that path of generation

                        SatisfiedWithResults = !CheckForCollisions(system, planet, moon, galaxyManager); // True if we find any collisions.
                        numAttempts++;

                        if (numAttempts >= maxAttempts)
                        {
                            break; // Breaks out of infinite pass if it ever occurs
                        }
                    }

                    if (!SatisfiedWithResults) // Don't add a colliding planet!
                    {
                        //Logger.log(Log_Type.ERROR, "Skipped adding a moon due to MaxAttempts being too much");
                        idManager.PushFreeID(moon.Id);

                        continue;
                    }


                    moon.IsMoon = true;
                    rm.RegisterObject(moon);
                    system.AddMoon(moon);
                    moon.ParentAreaID = system.Id;
                }
            }
        }
예제 #20
0
        public List <PSystem> generateAndFillGalaxy(int numPlanetsPerSystem, int solID, int numSystems, IEnumerable <PlanetLayout> layouts, GalaxyManager galaxyManager, LocalIDManager IDManager, GalaxyRegistrationManager rm, LocatorService ls)
        {
            float warpXPos = 0;
            float warpYPos = 0;
            int   amount   = 0;

            List <PSystem> generatedSystems = new List <PSystem>();

            PSystem sol = GenerateStarsystem(numPlanetsPerSystem, solID, galaxyManager, IDManager, rm, ls);

            sol.AreaName = "Sol";
            amount      += sol.PlanetCount;
            generatedSystems.Add(sol);

            for (int i = 0; i < numSystems - 1; i++)
            {
                tempsys = GenerateStarsystem(numPlanetsPerSystem, IDManager.PopFreeID(), galaxyManager, IDManager, rm, ls);

                amount += tempsys.PlanetCount;
                generatedSystems.Add(tempsys);

                //GalaxyManager.idToSystem.TryAdd(tempsys.ID, tempsys);
            }


            //ConsoleManager.WriteToFreeLine("Average of " + amount / numSystems + " planets per system");

            //Randomly link the systems
            //Take each system, iterate through the systems list and randomly connect them, or don't
            for (int i = 0; i < generatedSystems.Count; i++)
            {
                for (int j = i + 1; j < generatedSystems.Count; j++)
                {
                    if (r.Next(0, 100) <= 30) //30% probability of having the systems link
                    {
                        warpXPos = r.Next(-(generatedSystems[i].AreaSize - 200),
                                          (generatedSystems[i].AreaSize - 200));
                        warpYPos = -(int)Math.Sqrt(Math.Pow((generatedSystems[i].AreaSize - 200f), 2) - Math.Pow(warpXPos, 2));



                        tempWarp = new Warphole(warpXPos / 100, warpYPos / 100, generatedSystems[i].Id, generatedSystems[j].Id,
                                                (byte)generatedSystems[i].Warpholes.Count);
                        tempWarp.DestinationAreaID = generatedSystems[j].Id;
                        generatedSystems[i].Warpholes.Add(tempWarp);

                        //Normalizing the vector
                        warpXPos = warpXPos / (generatedSystems[i].AreaSize - 200f);
                        warpYPos = warpYPos / (generatedSystems[i].AreaSize - 200f);

                        //Converting it to the length for the other system, flipping to other side of system
                        warpXPos = -warpXPos * (generatedSystems[j].AreaSize - 200f);
                        warpYPos = -warpYPos * (generatedSystems[j].AreaSize - 200f);
                        tempWarp = new Warphole(warpXPos / 100, warpYPos / 100, generatedSystems[j].Id, generatedSystems[i].Id,
                                                (byte)generatedSystems[j].Warpholes.Count);
                        tempWarp.DestinationAreaID = generatedSystems[i].Id;
                        generatedSystems[j].Warpholes.Add(tempWarp);
                    }
                }
            }

            AssignPlanetLayouts(layouts, generatedSystems);

            return(generatedSystems);
        }
예제 #21
0
        public static PSystem GenerateStarsystem(int numberOfPlanets, int ID, GalaxyManager galaxyManager, LocalIDManager idManager, GalaxyRegistrationManager rm, LocatorService ls)
        {
            bool hasPort = false;

            // Add sun

            float size         = r.Next(100, 255) / 100f;
            float mass         = r.Next(50, 255) / 10f;
            float innerGravity = mass / 1875f;
            float outerGravity = innerGravity / 6f;

            var s    = (SunTypes[])Enum.GetValues(typeof(SunTypes));
            int type = r.Next(0, s.Length);

            var star = new Star(size, mass, innerGravity, outerGravity, s[type]);

            var system = new PSystem(star, ID, ls);

            system.AreaSize = baseBorder + r.Next(0, borderVariation);


            // Add Name
            system.AreaName = NameProvider.GetRandomName();


            rm.RegisterObject(system);


            for (int i = 0; i < numberOfPlanets; i++)
            {
                Planet planet;
                bool   SatisfiedWithResults = false;
                int    numAttempts          = MaxAttempts;
                system.IsCluster = false;
                int clusterType = 0;



                planet = new Planet(system, 0, ls);

                planet.AreaName = system.AreaName + " " + ToRoman(i + 1);

                if (r.Next(0, 101) > (100 - chanceOfCluster)) // Chance for planets to cluster
                {
                    system.IsCluster = true;
                    clusterType      = r.Next(0, clusterRadii.Count()); // Get which type of cluster
                }

                planet.Init(i, moonChance, minDistance, incrementOfOrbit, variationOfOrbit, 0,
                            r.Next());
                SatisfiedWithResults = !CheckForCollisions(system, planet); // True if we find any collisions.



                while (!SatisfiedWithResults)// While we're not content with the generation
                {
                    planet.Init(i, moonChance, minDistance, incrementOfOrbit, variationOfOrbit, 0,
                                r.Next());

                    SatisfiedWithResults = !CheckForCollisions(system, planet); // True if we find any collisions.

                    if (SatisfiedWithResults && system.IsCluster && i > 0)
                    {
                        SatisfiedWithResults = CheckForCollisions(system, planet, clusterRadii[clusterType]); // Cluster planets
                    }

                    numAttempts++;

                    if (numAttempts >= MaxAttempts && !system.IsCluster)
                    {
                        break; // Breaks out of infinite pass if it ever occurs
                    }
                    else if (numAttempts >= MaxAttempts && system.IsCluster)
                    {
                        i = 0; // Reset the whole operation because there's a bad system being generated.
                        foreach (Planet pll in system.GetPlanets())
                        {
                            system.RemovePlanet(pll);
                            rm.DeRegisterObject(pll);
                        }
                        break;
                    }
                }

                if (SatisfiedWithResults == false) // Don't add a colliding planet!
                {
                    //Logger.log(Log_Type.WARNING, "Skipped adding a planet due to MaxAttempts being too much");
                    continue;
                }
                planet.Id = idManager.PopFreeID();
                system.AddPlanet(planet);
                planet.ParentAreaID = system.Id;
                rm.RegisterObject(planet);

                if (system.AreaSize < planet.Distance - baseBorder) // If we're skinny, throw in a little extra space
                {
                    system.AreaSize = planet.Distance + baseBorder + r.Next(0, borderVariation);
                }
            }


            foreach (Planet p in system.GetPlanets())
            {
                _generateMoons(system, p, galaxyManager, idManager, rm, ls);
            }

            foreach (Planet m in system.GetMoons())
            {
                if (system.AreaSize < ls.AreaLocator.GetArea(m.IDToOrbit).Distance + m.Distance + baseBorder)
                {
                    // If we're skinny, throw in a little extra space
                    system.AreaSize = ls.AreaLocator.GetArea(m.IDToOrbit).Distance + m.Distance + baseBorder + r.Next(0, borderVariation);
                }
            }

            // Port Generation
            if (r.Next(0, 100) > 100 - portChance && !hasPort)
            {
                if (system.MoonCount > 0)
                {
                    for (int i = 0; i < system.MoonCount; i++)
                    {
                    }
                    int cr          = r.Next(0, system.MoonCount + 1); // Finds moon to turn into port.
                    int currentMoon = 0;                               // Used to get the moon

                    foreach (Planet m in system.GetMoons())
                    {
                        if (currentMoon == cr)
                        {
                            Planet moonToPort = m;
                            moonToPort.ParentAreaID = system.Id;
                            system.RemoveMoon(m);
                            rm.DeRegisterObject(m);

                            Port por = new Port(idManager.PopFreeID(), moonToPort, system.AreaName, ShipStatManager.StatShipList.ToList <ShipStats>(), ls); // Converts a moon into a port.
                            system.AddPort(por);
                            rm.RegisterObject(por);

                            hasPort = true;
                            break;
                        }
                        currentMoon++;
                    }
                }
            }


            return(system);
        }
        public static PSystemBody GenerateSystemBody(PSystem system, PSystemBody parent, string templateName, string name, Orbit orbit)
        {
            // Look up the template body
            PSystemBody template = Utility.FindBody (system.rootBody, templateName);

            // Create a new celestial body as a clone of this template
            PSystemBody clone = system.AddBody (parent);
            clone.name = name;

            // Set up the celestial body of the clone (back up the orbit driver)
            Utility.CopyObjectFields<CelestialBody> (template.celestialBody, clone.celestialBody);
            clone.celestialBody.bodyName = name;
            clone.celestialBody.orbitingBodies = null;
            clone.celestialBody.orbitDriver = clone.orbitDriver;
            clone.flightGlobalsIndex = 100 + template.flightGlobalsIndex;

            // Setup the orbit driver
            clone.orbitRenderer.orbitColor = template.orbitRenderer.orbitColor;
            clone.orbitDriver.orbit = orbit;
            clone.orbitDriver.celestialBody = clone.celestialBody;
            clone.orbitDriver.updateMode = OrbitDriver.UpdateMode.UPDATE;

            // Setup the deactivator object
            GameObject deactivator = new GameObject ("Deactivator");
            deactivator.SetActive (false);
            UnityEngine.Object.DontDestroyOnLoad (deactivator);

            // Clone the template's PQS
            clone.pqsVersion = UnityEngine.Object.Instantiate (template.pqsVersion) as PQS;
            clone.pqsVersion.transform.parent = deactivator.transform;
            clone.pqsVersion.name = name;

            // Clone the scaled space
            clone.scaledVersion = UnityEngine.Object.Instantiate (template.scaledVersion) as GameObject;
            clone.scaledVersion.transform.parent = deactivator.transform;
            clone.scaledVersion.name = name;

            return clone;
        }
 public static PSystemBody GeneratePlanet(PSystem system, string templateName, string name, Orbit orbit)
 {
     return GenerateSystemBody (system, system.rootBody, templateName, name, orbit);
 }
예제 #24
0
 public static PSystemBody GeneratePlanet(PSystem system, string templateName, string name, Orbit orbit)
 {
     return(GenerateSystemBody(system, system.rootBody, templateName, name, orbit));
 }
예제 #25
0
        // Awake() is the first function called in the lifecycle of a Unity3D MonoBehaviour.  In the case of KSP,
        // it happens to be called right before the game's PSystem is instantiated from PSystemManager.Instance.systemPrefab
        public void Awake()
        {
            // Abort, if KSP isn't compatible
            if (!CompatibilityChecker.IsCompatible())
            {
                string supported = CompatibilityChecker.version_major + "." + CompatibilityChecker.version_minor + "." + CompatibilityChecker.Revision;
                string current = Versioning.version_major + "." + Versioning.version_minor + "." + Versioning.Revision;
                Debug.LogWarning("[Kopernicus] Detected incompatible install.\nCurrent version of KSP: " + current + ".\nSupported version of KSP: " + supported + ".\nPlease wait, until Kopernicus gets updated to match your version of KSP.");
                Debug.Log("[Kopernicus] Aborting...");

                // Abort
                Destroy(this);
                return;
            }

            // We're ALIVE
            Logger.Default.SetAsActive();
            Logger.Default.Log("Injector.Awake(): Begin");

            // Yo garbage collector - we have work to do man
            DontDestroyOnLoad(this);

            // If the planetary manager does not work, well, error out
            if (PSystemManager.Instance == null)
            {
                // Log the error
                Logger.Default.Log("Injector.Awake(): If PSystemManager.Instance is null, there is nothing to do");
                return;
            }

            // Backup the old prefab
            StockSystemPrefab = PSystemManager.Instance.systemPrefab;

            // Get the current time
            DateTime start = DateTime.Now;

            // Get the configNode
            ConfigNode kopernicus = GameDatabase.Instance.GetConfigs(rootNodeName)[0].config;

            // THIS IS WHERE THE MAGIC HAPPENS - OVERWRITE THE SYSTEM PREFAB SO KSP ACCEPTS OUR CUSTOM SOLAR SYSTEM AS IF IT WERE FROM SQUAD
            PSystemManager.Instance.systemPrefab = Parser.CreateObjectFromConfigNode<Loader>(kopernicus).systemPrefab;

            // SEARCH FOR THE ARCHIVES CONTROLLER PREFAB AND OVERWRITE IT WITH THE CUSTOM SYSTEM
            RDArchivesController archivesController = AssetBase.RnDTechTree.GetRDScreenPrefab ().GetComponentsInChildren<RDArchivesController> (true).First ();
            archivesController.systemPrefab = PSystemManager.Instance.systemPrefab;

            // Clear space center instance so it will accept nouveau Kerbin
            SpaceCenter.Instance = null;

            // Add a handler so that we can do post spawn fixups.
            PSystemManager.Instance.OnPSystemReady.Add(PostSpawnFixups);

            // Done executing the awake function
            TimeSpan duration = (DateTime.Now - start);
            Logger.Default.Log("Injector.Awake(): Completed in: " + duration.TotalMilliseconds + " ms");
            Logger.Default.Flush ();
        }
예제 #26
0
        /// <summary>
        /// Instantiates and registers all objects associated with a PSystem (planets, players, ships, etc)
        /// </summary>
        public static async Task <PSystem> DeserializePSystemAsync(PSystemModel system, RedisServer redisServer, LocatorService ls, IGalaxyRegistrationManager rm, IDatabaseManager dbm)
        {
            PSystem           retSys            = new PSystem(system, ls);
            List <IShip>      deserializedShips = new List <IShip>();
            List <IStructure> loadedStructures  = new List <IStructure>();
            List <Player>     loadedPlayers     = new List <Player>();

            //For now we just run the whole lambda synchronously in its own thread. Marking it async makes this method return complete before the task is complete, need to investigate...
            await Task.Factory.StartNew(() =>
            {
                HashSet <int> colonyIDsToLoad = new HashSet <int>();
                HashSet <int> shipIDsToLoad   = new HashSet <int>();
                HashSet <int> areaIDsToLoad   = new HashSet <int>();
                List <int> structureIDsToLoad = new List <int>();
                HashSet <int> layoutIDsToLoad = new HashSet <int>();

                foreach (int id in system.ShipIDs)
                {
                    if (shipIDsToLoad.Contains(id))
                    {
                        throw new CorruptStateException("Multiple areas contain the same shipID.");
                    }
                    shipIDsToLoad.Add(id);
                }
                foreach (var id in retSys.MoonIDs)
                {
                    areaIDsToLoad.Add(id);
                }

                foreach (var id in retSys.PlanetIDs)
                {
                    areaIDsToLoad.Add(id);
                }

                foreach (var id in retSys.PortIDs)
                {
                    areaIDsToLoad.Add(id);
                }

                IEnumerable <AreaModel> loadedAreaModels = dbm.GetAreasAsync(areaIDsToLoad).Result;

                foreach (var am in loadedAreaModels)
                {
                    switch (am.AreaType)
                    {
                    case AreaTypes.Planet:
                        layoutIDsToLoad.Add(((PlanetModel)am).LayoutId);
                        break;
                    }
                }


                IEnumerable <PlanetLayout> loadedLayouts = dbm.GetLayoutsAsync(layoutIDsToLoad).Result.Select(s => (PlanetLayout)s);
                Dictionary <int, PlanetLayout> layouts   = new Dictionary <int, PlanetLayout>();
                foreach (var l in loadedLayouts)
                {
                    layouts.Add(l.Id, l);
                }


                var loadedAreas = new List <IArea>();
                // Instantiate all areas
                foreach (AreaModel am in loadedAreaModels)
                {
                    IArea loadedArea = null;
                    structureIDsToLoad.AddRange(am.StructureIDs);

                    // Planets
                    if (am.AreaType == AreaTypes.Planet)
                    {
                        loadedArea = new Planet((PlanetModel)am, layouts[((PlanetModel)am).LayoutId], ls);
                        var p      = loadedArea as Planet;
                        //rm.RegisterObject(p);
                        if (p.ColonyID != null)
                        {
                            colonyIDsToLoad.Add((int)p.ColonyID);
                        }
                    }

                    // Ports
                    else if (am.AreaType == AreaTypes.Port)
                    {
                        loadedArea = new Port((PortModel)am, ls);
                    }
                    else
                    {
                        throw new Exception("Error: Loaded area not handled in DeserializePSystem()");
                    }



                    foreach (var id in am.ShipIDs)
                    {
                        if (shipIDsToLoad.Contains(id))
                        {
                            throw new CorruptStateException("Multiple areas contain the same shipID.");
                        }
                        shipIDsToLoad.Add(id);
                    }
                    loadedAreas.Add(loadedArea);
                    rm.RegisterObject(loadedArea);
                }

                // Colonies
                IEnumerable <AreaModel> LoadedColonies = dbm.GetAreasAsync(colonyIDsToLoad).Result;
                List <Colony> deserializedColonies     = new List <Colony>();
                foreach (AreaModel am in LoadedColonies)
                {
                    if (am.AreaType == AreaTypes.Colony)
                    {
                        Colony c         = new Colony((ColonyModel)am, ls);
                        c.DisableUpdates = true;
                        rm.RegisterObject(c);
                        deserializedColonies.Add(c);
                    }
                    else
                    {
                        throw new Exception("AreaID query resulted in an AreaModel which was not a ColonyModel in DeserializePSystem()");
                    }
                    foreach (var id in am.ShipIDs)
                    {
                        if (shipIDsToLoad.Contains(id))
                        {
                            throw new CorruptStateException("Multiple areas contain the same shipID.");
                        }
                        shipIDsToLoad.Add(id);
                    }
                }

                // Structures
                loadedStructures.AddRange(LoadStructures(retSys, dbm, rm, ls.PlayerLocator).Result);

                foreach (IArea loadedArea in loadedAreas)
                {
                    if (loadedArea is IHasStructures)
                    {
                        loadedStructures.AddRange(LoadStructures((IHasStructures)loadedArea, dbm, rm, ls.PlayerLocator).Result);
                    }
                }


                // Ships
                IEnumerable <ShipModel> loadedShipModels = dbm.GetShipsAsync(shipIDsToLoad).Result;
                HashSet <int> playerIDsToLoad            = new HashSet <int>();
                foreach (var s in loadedShipModels)
                {
                    var loadedShip = DeserializeShip(s, ls, rm);
                    deserializedShips.Add(loadedShip);
                    if (loadedShip.PlayerID != null)
                    {
                        playerIDsToLoad.Add((int)s.PlayerID);
                    }
                }


                // Players
                IEnumerable <PlayerModel> loadedPlayerModels = dbm.GetPlayersAsync(playerIDsToLoad).Result;

                HashSet <int> accountIDsToLoad = new HashSet <int>();
                foreach (var p in loadedPlayerModels)
                {
                    if (p.PlayerType == PlayerTypes.Human)
                    {
                        HumanPlayer hp = new HumanPlayer(p, ls);
                        rm.RegisterObject(hp);
                        loadedPlayers.Add(hp);
                    }
                    else
                    {
                        NPCPlayer np      = new NPCPlayer(p, ls);
                        np.MessageService = new RedisOutgoingMessageService(redisServer, np);
                        rm.RegisterObject(np);
                        loadedPlayers.Add(np);
                    }
                    if (p.AccountID != null)
                    {
                        accountIDsToLoad.Add((int)p.AccountID);
                    }
                }


                //Accounts
                IEnumerable <AccountModel> loadedAccounts = dbm.GetAccountsAsync(accountIDsToLoad).Result;

                foreach (var a in loadedAccounts)
                {
                    rm.RegisterObject(new Account(a));
                }

                foreach (var c in deserializedColonies)
                {
                    c.DisableUpdates = false;
                }
            }
                                        );

            rm.RegisterObject(retSys);

            foreach (Player p in loadedPlayers)
            {
                if (p.PlayerType == PlayerTypes.NPC)
                {
                    p.GetArea().MovePlayerHere(p, false);
                }
            }

            foreach (var s in deserializedShips)
            {
                IArea a = s.GetArea();

                if (a == null)//Corrupt state, the ship's CurrentAreaId doesn't match the list is for an area which hasn't been loaded yet. Abort the ship read.
                {
                    //I'm not sure that there's a way to gracefully handle this without a major rewrite and a bunch of overhead, so it'll be an exception for now.
                    throw new CorruptStateException("Ship's CurrentAreaId does not match the area from which it was loaded. Expect exceptions.");
                }
                else
                {
                    a.AddShip(s, true);
                }
            }


            return(retSys);
        }