Пример #1
0
        private void CheckForDirtAndCleanIfPossible()
        {
            if (_currentCapacity == 0)
            {
                return;
            }

            // Check tile below me
            var realWorldPosition = transform.position;

            var vLocPos = _doodadsBackgroundTilemap.transform.InverseTransformPoint(realWorldPosition);
            var gridX   = BrushUtil.GetGridX(vLocPos, _doodadsBackgroundTilemap.CellSize);
            var gridY   = BrushUtil.GetGridY(vLocPos, _doodadsBackgroundTilemap.CellSize);


            var gridPosition = TilemapUtils.GetGridPosition(
                _doodadsBackgroundTilemap,
                new Vector2(realWorldPosition.x, realWorldPosition.y)
                );

            gridPosition = new Vector2(gridX, gridY);

            var tileData = _doodadsBackgroundTilemap.GetTileData(gridPosition);

            // Remove the tile below me!
            if (IsDirtTile(tileData))
            {
                _doodadsBackgroundTilemap.Erase(gridPosition);
                _doodadsBackgroundTilemap.UpdateMesh();
                _currentCapacity--;
            }
        }
Пример #2
0
        private Vector2?GetRandomPlaceableTilePosition()
        {
            var dirtyCount    = 0;
            var freePositions = new List <Vector2>();

            foreach (var tileVector in _dirtiableTiles)
            {
                var tileData = _doodadsBackgroundTilemap.GetTileData(tileVector);
                if (Tileset.k_TileData_Empty == tileData)
                {
                    freePositions.Add(tileVector);
                }
                else if (IsDirtTile(tileData))
                {
                    dirtyCount++;
                }
            }

            if (freePositions.Count == 0)
            {
                return(null);
            }

            var toSkip     = MathHelper.GetRandomInt(0, freePositions.Count);
            var randomTile = freePositions.Skip(toSkip).Take(1).First();

            return(randomTile);
        }
    public void GenerateBackgroundTilemap(STETilemap existingTilemap)
    {
        //Clear the current background tilemap
        thisTilemap.ClearMap();

        //If background type chosen is perlin, run the perlin background generation functionality
        if (backgroundType == BackgroundType.perlin)
        {
            //random seed for variation
            float rand = Random.Range(0f, 999999f);

            //Loop through and assign tiles based on whether their perlin value at the given tile (with the seed/scale taken into account) is above a set threshold
            //If its above the threshold, set it as a tile, if not, leave it blank
            //This leads to organic and natural looking curves of tiles and a nice looking randomised background
            for (int x = 0; x < existingTilemap.GridWidth; x++)
            {
                for (int y = 0; y < existingTilemap.GridHeight; y++)
                {
                    float xCoord = rand + (float)x / (float)existingTilemap.GridWidth * perlinScale;
                    float yCoord = rand + (float)y / (float)existingTilemap.GridHeight * perlinScale;

                    float p = Mathf.PerlinNoise(xCoord, yCoord);

                    if (p > perlinThreshold)
                    {
                        thisTilemap.SetTile(x, y, 0, brushId, eTileFlags.None);
                    }
                }
            }
        }
        //If the background mode is set from the main map, set any tile behind a foreground tile to a rubbly/destroyed tile, and the rest to regular background tiles
        else if (backgroundType == BackgroundType.fromMainMap)
        {
            for (int x = 0; x < existingTilemap.GridWidth; x++)
            {
                for (int y = 0; y < existingTilemap.GridHeight; y++)
                {
                    uint     raw       = existingTilemap.GetTileData(x, y);
                    TileData processed = new TileData(raw);

                    if (processed.tileId != 65535)
                    {
                        thisTilemap.SetTile(x, y, 0, brushId, eTileFlags.None);
                    }
                    else
                    {
                        thisTilemap.SetTile(x, y, 0, brushId, eTileFlags.None);
                    }
                }
            }
        }

        //Update the background mesh after all generation is complete
        thisTilemap.UpdateMesh();
    }
Пример #4
0
        public override void OnEnter()
        {
            var  go       = Fsm.GetOwnerDefaultTarget(gameObject);
            uint tileData = Tileset.k_TileData_Empty;

            if (UpdateCache(go))
            {
                STETilemap tilemap = cachedComponent as STETilemap;
                if ((ePositionType)positionType.Value == ePositionType.LocalPosition)
                {
                    tileData = tilemap.GetTileData(position.Value);
                }
                else// if ((ePositionType)positionType.Value == ePositionType.GridPosition)
                {
                    tileData = tilemap.GetTileData((int)position.Value.x, (int)position.Value.y);
                }
            }
            tileId.Value    = Tileset.GetTileIdFromTileData(tileData);
            brushId.Value   = Tileset.GetBrushIdFromTileData(tileData);
            tileFlags.Value = (int)Tileset.GetTileFlagsFromTileData(tileData);

            Finish();
        }
Пример #5
0
    private void Spread()
    {
        if (GameObject.FindWithTag("Occupied Tiles") == null)
        {
            return;
        }
        if (AwakeChildren < 3)
        {
            return;
        }
        List <Vector2> emptyTiles = new List <Vector2>();
        STETilemap     occupied   = GameObject.FindWithTag("Occupied Tiles").GetComponent <STETilemap>();
        int            rand       = Random.Range(0, 101);

        if (rand <= SpreadChance)
        {
            GetComponent <ObjectPosition>().AdjustPositions();
            Vector2 Center = GetComponent <SpriteRenderer>().bounds.center;
            for (int x = -1; x < 2; x++)
            {
                for (int y = -1; y < 2; y++)
                {
                    Vector2  pos      = new Vector2(Center.x + x, Center.y + y);
                    uint     rawData  = occupied.GetTileData(pos);
                    TileData tileData = new TileData(rawData);
                    int      tileID   = tileData.tileId;
                    if (tileID == 65535)
                    {
                        emptyTiles.Add(pos);
                    }
                }
            }
        }
        if (emptyTiles.Count < 1)
        {
            return;
        }
        rand = Random.Range(0, emptyTiles.Count);
        Vector2 newGrassPos = emptyTiles[rand];

        rand = Random.Range(0, GrassPatches.Count);
        GrassPatch newPatch = GameObject.Instantiate(GrassPatches[rand], newGrassPos, transform.rotation).GetComponent <GrassPatch>();

        newPatch.Grow();
    }
Пример #6
0
    protected override void ProceedUse(List <Vector2> pTiles)
    {
        NeedBase energyNeed = PlayerNeedManager.Instance.GetNeed("Energy");

        energyNeed.Change(-CurrentTool.EnergyCost * (ToolCursorManager.Instance.CursorIndex + 1));

        List <Vector2> tiles = pTiles;

        foreach (Vector2 tile in tiles)
        {
            if (CheckTileValidity(tile))
            {
                STETilemap affectedLayer = GetTileAffectedLayer(tile);

                uint     rawData  = affectedLayer.GetTileData(tile);
                TileData tileData = new TileData(rawData);
                foreach (AffectedTerrain terrain in AffectedTerrains)
                {
                    if (affectedLayer.name == terrain.LayerName)
                    {
                        tileData.brushId = terrain.BrushId;
                    }
                }
                if (affectedLayer.name == "Dirt")
                {
                    FarmPlot plot = GetPlot(tile);
                    if (plot != null)
                    {
                        Destroy(plot.gameObject);
                    }
                }

                affectedLayer.SetTileData(tile, tileData.BuildData());
                affectedLayer.UpdateMeshImmediate();

                FindObjectOfType <PlayerInventory>().RemoveFromStack(Toolbar.Instance.SelectedSlot.ReferencedItemStack, 1);
                if (Toolbar.Instance.SelectedSlot.ReferencedItemStack == null)
                {
                    return;
                }
            }
        }
    }
    /// <summary>
    /// Spawns contextual props/clutter around the map based off the surrounding tiles (i.e. stalagtites on the ceiling, grass on the floor, etc).
    /// Chances can be weighted in the inspector in order to propogate more or less of certain prop types (more ceiling, less ground props, etc).
    /// </summary>
    /// <param name="theme">The theme of the props to be spawned.</param>
    void ClutterPass(RoomDatabaseMaster.RoomTheme theme)
    {
        Debug.Log("Starting clutter pass");

        ClutterCollectionTheme currentClutterList = null;

        //Set the corresponding room clutter from the passed in theme
        if (theme == RoomDatabaseMaster.RoomTheme.Theme1)
        {
            currentClutterList = Clutter_Theme1;
        }
        else if (theme == RoomDatabaseMaster.RoomTheme.Theme2)
        {
            currentClutterList = Clutter_Theme2;
        }
        else if (theme == RoomDatabaseMaster.RoomTheme.Theme3)
        {
            currentClutterList = Clutter_Theme3;
        }

        //Loops through every tile on the tilemap and gets the tile data and the status of the other tiles surrounding it
        //When props are spawned, they are also associated or 'linked' with the tile they are spawned on (grass linked to tile belowe, stalagtites to the tile above)
        //These links are used so that when the associated tile could possibly be destroyed by the player's actions, the associated prop is destroyed too and not left floating.
        for (float x = 0; x < tileMap.GridWidth * tileMap.CellSize.x; x += tileMap.CellSize.x)
        {
            for (float y = 0; y < tileMap.GridHeight * tileMap.CellSize.y; y += tileMap.CellSize.y)
            {
                uint     tileDataRaw       = tileMap.GetTileData(new Vector2(x, y));
                TileData tileDataProcessed = new TileData(tileDataRaw);

                //If the current tile is empty space, a prop CAN be spawned there (cannot spawn props on an occupied space)
                if (tileDataProcessed.tileId == 65535)
                {
                    //Assign the surrounding tiles statuses to an array on int values (0 is free, 1 is taken, etc)
                    int[] surroundingTiles = SurroundingTileStatus(new Vector2(x, y));
                    bool  clutterSet       = false;

                    //The following statements check the values of the surrounding tiles returns, and request the type of clutter based on the results of these checks
                    //Prioritises ground clutter > ceiling > walls for aesthetic reasons

                    //Check if ground clutter can be spawned
                    if (surroundingTiles[0] == 0 && surroundingTiles[2] == 1 && !clutterSet && !DestructibleTerrainHandler.associatedClutterDictionary.ContainsKey(new Vector2(x, y - tileMap.CellSize.y)))
                    {
                        float rand = Random.Range(0f, 1f);
                        if (rand <= groundClutterChance)
                        {
                            GameObject clutterObj = Instantiate(RequestClutter(currentClutterList.groundClutter), new Vector3(x, y, 1), Quaternion.identity);
                            DestructibleTerrainHandler.associatedClutterDictionary.Add(new Vector2(x, y - tileMap.CellSize.y), clutterObj);
                            clutteredTilePositions.Add(new Vector2(x, y));
                            clutterSet = true;
                        }
                    }
                    //If not, can ceiling clutter be spawned
                    else if (surroundingTiles[0] == 1 && surroundingTiles[2] == 0 && !clutterSet && !DestructibleTerrainHandler.associatedClutterDictionary.ContainsKey(new Vector2(x, y + tileMap.CellSize.y)))
                    {
                        float rand = Random.Range(0f, 1f);
                        if (rand <= ceilingClutterChance)
                        {
                            GameObject clutterObj = Instantiate(RequestClutter(currentClutterList.ceilingClutter), new Vector3(x, y, 1), Quaternion.identity);
                            DestructibleTerrainHandler.associatedClutterDictionary.Add(new Vector2(x, y + tileMap.CellSize.y), clutterObj);
                            clutteredTilePositions.Add(new Vector2(x, y));
                            clutterSet = true;
                        }
                    }
                    //If not, left wall clutter?
                    else if (surroundingTiles[1] == 0 && surroundingTiles[3] == 1 && !clutterSet && !DestructibleTerrainHandler.associatedClutterDictionary.ContainsKey(new Vector2(x - tileMap.CellSize.x, y)))
                    {
                        float rand = Random.Range(0f, 1f);
                        if (rand <= wallClutterChance)
                        {
                            GameObject clutterObj = Instantiate(RequestClutter(currentClutterList.leftWallClutter), new Vector3(x, y, 1), Quaternion.identity);
                            DestructibleTerrainHandler.associatedClutterDictionary.Add(new Vector2(x - tileMap.CellSize.x, y), clutterObj);
                            clutteredTilePositions.Add(new Vector2(x, y));
                            clutterSet = true;
                        }
                    }
                    //If not, right wall clutter?
                    else if (surroundingTiles[3] == 0 && surroundingTiles[1] == 1 && !clutterSet && !DestructibleTerrainHandler.associatedClutterDictionary.ContainsKey(new Vector2(x + tileMap.CellSize.x, y)))
                    {
                        float rand = Random.Range(0f, 1f);
                        if (rand <= wallClutterChance)
                        {
                            GameObject clutterObj = Instantiate(RequestClutter(currentClutterList.rightWallClutter), new Vector3(x, y, 1), Quaternion.identity);
                            DestructibleTerrainHandler.associatedClutterDictionary.Add(new Vector2(x + tileMap.CellSize.x, y), clutterObj);
                            clutteredTilePositions.Add(new Vector2(x, y));
                            clutterSet = true;
                        }
                    }
                }
            }
        }
    }
Пример #8
0
 protected uint GetTileData(Vector2 pTileWorldPos, STETilemap pLayer)
 {
     return(pLayer.GetTileData(pTileWorldPos));
 }
Пример #9
0
 private void SetFlipForTile(STETilemap tilemap, Vector2 pos)
 {
     tilemap.SetTileData(pos, tilemap.GetTileData(pos) | Tileset.k_TileFlag_FlipH);
 }
Пример #10
0
 uint GetTileData(Vector2 pTileWorldPos)
 {
     return(OccupiedLayer.GetTileData(pTileWorldPos));
 }
Пример #11
0
    public void ExportRoom(bool conflict)
    {
        roomDataList = new List <TileDataCustom>();

        //Create a directory path based on the selected theme and room type, and append any identifiers to the filename
        directory = GetPath() + roomTheme.ToString() + "/" + roomType.ToString();
        Directory.CreateDirectory(directory);
        directory += "/" + filename + "_" + roomTheme.ToString() + "_" + roomType.ToString() + "_" + roomIdentifier;

        //Conflict handling - if automatically handled (shouldn't have got to this point otherwise, but best to be safe), add an index to the filename that is free/unique.
        if (!conflict)
        {
            directory += ".csv";
        }
        else if (conflict && autoNameConflictResolution)
        {
            bool indexFree = false;
            int  counter   = 1;

            while (!indexFree)
            {
                if (!CheckForExistingRooms(directory + "_" + counter.ToString() + ".csv"))
                {
                    Debug.Log("Room name (" + directory + ") already taken, appending index to distinguish between room identities.");

                    directory += "_" + counter.ToString() + ".csv";
                    indexFree  = true;
                }
                else
                {
                    counter++;
                }
            }
        }

        //If the file already exists, delete it and overwrite it.
        if (File.Exists(directory))
        {
            System.IO.File.Delete(directory);
            Debug.Log("Deleting existing room file to overwrite");
        }

        //Create and configure the CSV/text writers
        textWriter = File.CreateText(directory);
        csvWriter  = new CsvWriter(textWriter);
        csvWriter.Configuration.RegisterClassMap <RoomTileDataMap>();
        csvWriter.WriteHeader <RoomData>();
        csvWriter.NextRecord();

        //For every tile on the tilemap, loop through and create a TileDataCustom object based on all of its data and parameters
        for (int x = tileMap.MinGridX; x < tileMap.GridWidth; x++)
        {
            for (int y = tileMap.MinGridY; y < tileMap.GridHeight; y++)
            {
                uint     tileDataRaw = tileMap.GetTileData(x, y);
                Tile     tile        = tileMap.GetTile(x, y);
                TileData tileData    = new TileData(tileDataRaw);

                bool isMutateable    = false;
                bool isChunkTemplate = false;
                if (tile != null)
                {
                    isMutateable    = tile.paramContainer.GetBoolParam("mutateable");
                    isChunkTemplate = tile.paramContainer.GetBoolParam("isChunkTemplate");
                    if (isChunkTemplate)
                    {
                        Debug.Log(new Vector2(x, y));
                    }
                }
                data = new TileDataCustom(tileData.tileId, new Vector2(x, y), isMutateable, isChunkTemplate);
                roomDataList.Add(data);
            }
        }

        //Pass data to writing function that actually handles the file writing
        WriteDataToCSV();
    }