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--; } }
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(); }
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(); }
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(); }
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; } } } } } }
protected uint GetTileData(Vector2 pTileWorldPos, STETilemap pLayer) { return(pLayer.GetTileData(pTileWorldPos)); }
private void SetFlipForTile(STETilemap tilemap, Vector2 pos) { tilemap.SetTileData(pos, tilemap.GetTileData(pos) | Tileset.k_TileFlag_FlipH); }
uint GetTileData(Vector2 pTileWorldPos) { return(OccupiedLayer.GetTileData(pTileWorldPos)); }
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(); }