Beispiel #1
0
 public void Wipe()
 {
     Noise.Wipe();
     Player.Wipe();
     PrefabSpawnerSaveData.Wipe();
     MapGenerator.Wipe();
     FlowerLibrary.Wipe();
 }
Beispiel #2
0
 //Saves things that should be saved
 private void Save()
 {
     if (_save)
     {
         StartCoroutine(SaveIconAlpha());
         Noise.Save();
         PrefabSpawnerSaveData.Save();
         Player.Save();
         Menu.Save();
         MapGenerator.Save();
         FlowerLibrary.Save();
     }
 }
Beispiel #3
0
    //Load in stuff from memory, called on startup
    private void Load()
    {
        if (_load)
        {
            ValidateSave();
            Noise.Load();
            Player.Load();
            PrefabSpawnerSaveData.Load();
            MapGenerator.Load();
            Menu.Load();
            FlowerLibrary.Load();
            AlchemyOrganizer_2.UpdateAfterLoad();
        }

        //Used to make clear circle around player on spawn
        PrefabSpawnerSaveData.ClearStartArea(_meshSettings.NumVertsPerLine / 2, _clearAreaSize);

        Ready = true;
    }
Beispiel #4
0
    private List <SpawnInfo> SpawnFromSpawnables(int detailType, int levelOfDetail, Biome biome, Spawnable[] spawnables, HeightMap heightMap, MeshData meshData, MeshSettings meshSettings, Vector2 chunkPosition, Vector2 chunkCoord, bool firstCall = false)
    {
        List <SpawnInfo> spawnInfo = new List <SpawnInfo>();

        //Spawn Water - water has detail type of highest level even if it spawns in low LOD because it has no need to check normals
        if (firstCall)
        {
            spawnInfo.Add(new SpawnInfo(biome.WaterChunk, 0, new Vector3(chunkPosition.x, biome.WaterHeight, -chunkPosition.y), Vector3.up, 0, 0, chunkCoord, Vector2.zero, false, new Vector3((meshSettings.ChunkSize - 1) * meshSettings.MeshScale, 1, (meshSettings.ChunkSize - 1) * meshSettings.MeshScale), false));
        }

        for (int i = 0; i < spawnables.Length; i++)
        {
            //First spawn the subspawners prefabs as they are harder to make room for
            if (spawnables[i].SubSpawners.Length > 0)
            {
                List <SpawnInfo> childSpawnInfo = SpawnFromSpawnables(detailType, levelOfDetail, biome, spawnables[i].SubSpawners, heightMap, meshData, meshSettings, chunkPosition, chunkCoord);
                spawnInfo.AddRange(childSpawnInfo);
            }

            //This spawnable has nothing to spawn, act only as parent
            if (!spawnables[i].ParentOnly)
            {
                //Get noise specific to this prefab
                float[,] spawnNoise = spawnables[i].GetNoise;
                //Local size occupation
                bool[,] localOccupiedGrid = new bool[_occupiedGrid.GetLength(0), _occupiedGrid.GetLength(1)];

                //+ 1 offset in loops are due to border around mesh
                for (int x = 0; x < meshSettings.ChunkSize - spawnables[i].Size; x++)
                {
                    for (int y = 0; y < meshSettings.ChunkSize - spawnables[i].Size; y++)
                    {
                        Vector2         itemIndex       = new Vector2(x, y);
                        ChunkCoordIndex chunkCoordIndex = new ChunkCoordIndex(chunkCoord, itemIndex);
                        bool            shouldSpawn     = true;
                        bool            partialSpawn    = false;

                        if (PrefabSpawnerSaveData.InsideSpawnArea(chunkCoordIndex) && !spawnables[i].OthersCanSpawnInside)
                        {
                            shouldSpawn = false;
                        }
                        //This thing is already picked up! (Size > 0 is just to check if the thing is pickable)
                        if (!spawnables[i].OthersCanSpawnInside && PrefabSpawnerSaveData.ContainsChunkCoordIndex(chunkCoordIndex))
                        {
                            StoredSaveData data = PrefabSpawnerSaveData.GetStoredSaveData(chunkCoordIndex);

                            if (data.PartialSpawn)
                            {
                                partialSpawn = true;
                            }
                            else
                            {
                                shouldSpawn = false;
                            }
                        }
                        if (shouldSpawn)
                        {
                            bool canObjectSpawnSize = CanObjectSpawnSize(x, y, spawnables[i].Size, meshSettings.ChunkSize, ref localOccupiedGrid) && (CanObjectSpawnSize(x, y, spawnables[i].Spacing, meshSettings.ChunkSize, ref _occupiedGrid) || spawnables[i].OthersCanSpawnInside);
                            bool canObjectSpawnDiff = CanObjectSpawnDiff(x, y, spawnables[i].Size, spawnables[i].OthersCanSpawnInside, heightMap.heightMap, spawnables[i].SpawnDifferencial, meshSettings.ChunkSize);

                            //No use in checking if it can spawn if that square is occopied
                            if (canObjectSpawnSize && canObjectSpawnDiff)
                            {
                                bool insideNoise   = spawnNoise[x, y] > spawnables[i].NoiseStartPoint;                                         //is it inside the noise?
                                bool gradientSpawn = spawnNoise[x, y] + spawnables[i].OffsetNoise[x, y] > spawnables[i].Thickness;             //If it is, transition?
                                bool uniformSpread = x % spawnables[i].UniformSpreadAmount == 0 && y % spawnables[i].UniformSpreadAmount == 0; //uniform spread?
                                bool noiseSpread   = spawnables[i].SpreadNoise[y, x] > spawnables[i].RandomSpread;

                                //Slope
                                Vector3 normal = Vector3.up;
                                //Only on the highest detail level, care about normal
                                if (levelOfDetail == 0)
                                {
                                    normal = meshData.GetNormal(y * (meshSettings.ChunkSize) + x);
                                }

                                float slopeAngle = Vector3.Angle(Vector3.up, normal);

                                bool minSlope = (slopeAngle <= spawnables[i].SoftMinSlope * spawnables[i].OffsetNoise[x, y]);
                                minSlope = minSlope && slopeAngle <= spawnables[i].HardMinSlope;
                                bool maxSlope = (slopeAngle >= spawnables[i].SoftMaxSlope * spawnables[i].OffsetNoise[x, y]);
                                maxSlope = maxSlope && slopeAngle >= spawnables[i].HardMaxSlope;

                                //height bools
                                bool minHeight = (heightMap.heightMap[x, y] > spawnables[i].HardMinHeight + spawnables[i].SoftMinAmount * spawnables[i].OffsetNoise[x, y]);
                                bool maxHeight = (heightMap.heightMap[x, y] <= spawnables[i].HardMaxHeight - spawnables[i].SoftMaxAmount * spawnables[i].OffsetNoise[x, y]);

                                SpawnablePrefab spawnPrefab = spawnables[i].GetPrefab(x, y);

                                bool shouldSpawnIfFixedHeight = true;
                                if (spawnables[i].SpawnFixedHeight)
                                {
                                    shouldSpawnIfFixedHeight = heightMap.heightMap[x + (int)(STANDARD_GRID_OFFSET * spawnables[i].Size) + 1, y + (int)(STANDARD_GRID_OFFSET * spawnables[i].Size) + 1] + spawnPrefab.Height <= spawnPrefab.FixedHeight + spawnPrefab.Height;
                                }

                                //Things inside the if statement only need to be determined if it should spawn
                                if (insideNoise && gradientSpawn && uniformSpread && noiseSpread && minHeight && maxHeight && minSlope && maxSlope && shouldSpawnIfFixedHeight)
                                {
                                    //Since the object can spawn, mark it's space as occopied
                                    if (!spawnables[i].OthersCanSpawnInside)
                                    {
                                        OccupyWithObject(x, y, spawnables[i].Size, meshSettings.ChunkSize, ref _occupiedGrid);
                                    }

                                    OccupyWithObject(x, y, spawnables[i].Spacing, meshSettings.ChunkSize, ref localOccupiedGrid);

                                    float   scale    = spawnPrefab.ScaleRandom * spawnables[i].OffsetNoise[x, y] + spawnPrefab.Scale;
                                    Vector3 newScale = new Vector3(scale, scale, scale);

                                    //Current local positions in x and y in chunk, used only to spawn from
                                    float xPos = x + STANDARD_GRID_OFFSET + (STANDARD_GRID_OFFSET * spawnables[i].Size) - meshSettings.ChunkSize / 2 - 1; //Due to the border around the mesh + STANDARD_GRID_OFFSET corrects it to the right grid position
                                    float zPos = y + STANDARD_GRID_OFFSET + (STANDARD_GRID_OFFSET * spawnables[i].Size) - meshSettings.ChunkSize / 2 - 1; //Due to the border around the mesh + STANDARD_GRID_OFFSET corrects it to the right grid position
                                    float yPos = heightMap.heightMap[x + (int)(STANDARD_GRID_OFFSET * spawnables[i].Size) + 1, y + (int)(STANDARD_GRID_OFFSET * spawnables[i].Size) + 1] + spawnPrefab.Height;

                                    //Used if the object should not follow the world geometry and spawn at fixed height -> spawn in water
                                    // Only allow it if the object won't spawn under the terrain!
                                    if (spawnables[i].SpawnFixedHeight)
                                    {
                                        yPos = spawnPrefab.FixedHeight + spawnPrefab.Height;
                                    }

                                    //Position from grid in world
                                    Vector3 objectPosition = new Vector3((xPos + chunkPosition.x) * meshSettings.MeshScale, yPos, -(zPos + chunkPosition.y) * meshSettings.MeshScale);
                                    //Vector to offset from grid slightly to create less uniform distribution
                                    Vector3 offsetVector = new Vector3(spawnables[i].OffsetNoise[x, y] * 2 - 1, 0.0f, spawnables[i].SpreadNoise[x, y] * 2 - 1);

                                    objectPosition += offsetVector * spawnables[i].OffsetAmount;

                                    //How much along the normal should the object point?
                                    float tiltAmount = spawnables[i].SurfaceNormalAmount + (spawnables[i].SpreadNoise[x, y] * 2 - 1) * spawnables[i].PointAlongNormalRandomness;

                                    float localRotationAmount = spawnables[i].OffsetNoise[x, y] * DEGREES_360 * spawnables[i].RotationAmount;


                                    spawnInfo.Add(new SpawnInfo(spawnPrefab.Prefab, detailType, objectPosition, normal, tiltAmount, localRotationAmount, chunkCoord, itemIndex, spawnables[i].Size != 0, newScale, partialSpawn));
                                }
                            }
                        }
                    }
                }
            }
        }

        return(spawnInfo);
    }
Beispiel #5
0
 //Call this function on pickup
 public void StoreInPrefabSpawnerSaveData()
 {
     PrefabSpawnerSaveData.AddPickup(_saveData);
 }