コード例 #1
0
ファイル: MouseCellSelector.cs プロジェクト: bmjoy/Osnowa
        private void AddTerrainText(Position mousePosition, StringBuilder positionText)
        {
            IOsnowaContext context = _contextManager.Current;
            byte           standingIdAtPosition = context.TileMatricesByLayer[(int)TilemapLayer.Standing].Get(mousePosition);
            byte           floorIdAtPosition    = context.TileMatricesByLayer[(int)TilemapLayer.Floor].Get(mousePosition);
            byte           soilIdAtPosition     = context.TileMatricesByLayer[(int)TilemapLayer.Soil].Get(mousePosition);

            OsnowaBaseTile[] tilesByIds = _tileByIdProvider.GetTilesByIds();

            OsnowaBaseTile standingBaseTile = tilesByIds[standingIdAtPosition];
            OsnowaBaseTile floorBaseTile    = tilesByIds[floorIdAtPosition];
            OsnowaBaseTile soilBaseTile     = tilesByIds[soilIdAtPosition];

            if (standingBaseTile != null)
            {
                positionText.Append(standingBaseTile.name + ". " + Environment.NewLine);
            }
            if (floorBaseTile != null)
            {
                positionText.Append(floorBaseTile.name + ". " + Environment.NewLine);
            }
            if (soilBaseTile != null)
            {
                positionText.Append(soilBaseTile.name + ". " + Environment.NewLine);
            }

            positionText.Append(mousePosition);
        }
コード例 #2
0
        /// <inheritdoc />
        public void SetMany(Tilemap tilemap, HashSet <Position> totalVisibleByThem, OsnowaBaseTile tilesetVisibleByOthers)
        {
            OsnowaBaseTile[] tilesByIds = _tileByIdProvider.GetTilesByIds();
            int tilesByIdsCount         = tilesByIds.Length;

            Vector3Int[]     positions = totalVisibleByThem.Select(p => p.ToVector3Int()).ToArray();
            OsnowaBaseTile[] tiles     = new OsnowaBaseTile[positions.Length];
            for (int i = 0; i < tiles.Length; i++)
            {
                tiles[i] = tilesetVisibleByOthers;
            }

            tilemap.SetTiles(positions, tiles);

            if (tilesetVisibleByOthers is OsnowaTile osnowaTile)
            {
                foreach (Position position in totalVisibleByThem)
                {
                    tilemap.SetColor(position.ToVector3Int(), osnowaTile.Color);
                }
            }
            else
            {
                foreach (Position position in totalVisibleByThem)
                {
                    tilemap.SetColor(position.ToVector3Int(), Color.white);
                }
            }

            foreach (Position position in totalVisibleByThem)
            {
                _positionFlagsResolver.SetFlagsAt(position.x, position.y, tilesByIdsCount, tilesByIds, idsOfNotFoundTiles: null);
            }
        }
コード例 #3
0
        public void ShortenHighTiles(Position playerPosition, int range)
        {
            var        bounds             = new BoundsInt(playerPosition.x - range, playerPosition.y - range, 0, range * 2 + 1, range * 2 + 1, 1);
            MatrixByte standingTileMatrix = _contextManager.Current.TileMatricesByLayer[(int)TilemapLayer.Standing];

            OsnowaBaseTile[] tilesByIds = _tileByIdProvider.GetTilesByIds();
            foreach (Vector3Int position3 in bounds.allPositionsWithin)
            {
                var position = position3.ToPosition();
                if (!standingTileMatrix.IsWithinBounds(position))
                {
                    continue;
                }
                byte standingTileAtPosition = standingTileMatrix.Get(position);
                if (standingTileAtPosition <= 0)
                {
                    continue;
                }
                OsnowaBaseTile baseTileAtPosition = tilesByIds[standingTileAtPosition];
                if (baseTileAtPosition.ShorterVariant != null)
                {
                    _positionsToReset.Add(position);
                    _sceneContext.StandingTilemap.SetTile(position3, baseTileAtPosition.ShorterVariant);
                }
            }
        }
コード例 #4
0
        public void RefreshTile(Position position, int layer)
        {
            var tileId = _tileMatricesByteByLayer[layer].Get(position);

            OsnowaBaseTile[] tilesByIds = _tileByIdProvider.GetTilesByIds();

            OsnowaBaseTile baseTile = tilesByIds[tileId];

            _sceneContext.AllTilemapsByLayers[layer].SetTile(position.ToVector3Int(), baseTile);
        }
コード例 #5
0
 private void Construct(Position position, float buildingValue, OsnowaBaseTile buildingBaseTile)
 {
     if (buildingValue >= 0)
     {
         Values.Set(position, buildingValue);
     }
     //if(!new[]{ _tileset.Wall.Id, _tileset.DoorHorizontalClosed.Id}.Contains(_tileMatricesByte[TilemapLayers.Standing].Get(position)))
     //	_tileMatricesByte[TilemapLayers.Standing].Set(position, 0);
     _tileMatricesByte[(int)TilemapLayer.Decoration].Set(position, 0);
     _tileMatricesByte[(int)buildingBaseTile.Layer].Set(position, buildingBaseTile.Id);
 }
コード例 #6
0
ファイル: TileMatrixUpdater.cs プロジェクト: bmjoy/Osnowa
        public void Set(Position position, OsnowaBaseTile baseTileToSet)
        {
            int layerId = (int)baseTileToSet.Layer;

            _tileMatricesByteByLayer[layerId].Set(position, baseTileToSet.Id);

            OsnowaBaseTile[] tilesByIds = _tileByIdProvider.GetTilesByIds();
            int tilesByIdsCount         = tilesByIds.Length;

            _sceneContext.AllTilemapsByLayers[layerId].SetTile(position.ToVector3Int(), baseTileToSet);

            _positionFlagsResolver.SetFlagsAt(position.x, position.y, tilesByIdsCount, tilesByIds,
                                              idsOfNotFoundTiles: null);
        }
コード例 #7
0
        public OsnowaBaseTile[] GetTilesByIds()
        {
            List <OsnowaBaseTile> allTiles = AssetLoader.LoadAll <OsnowaBaseTile>();

            int maxId = allTiles.Max(t => t.Id);

            var result = new OsnowaBaseTile[maxId + 1];

            foreach (OsnowaBaseTile tile in allTiles)
            {
                result[tile.Id] = tile;
            }

            return(result);
        }
コード例 #8
0
        private Position BuildHouse(Area area)
        {
            bool ValidForBeingDoor(Position position)
            => position.y == area.Bounds.yMin && position.x > area.Bounds.xMin && position.x < area.Bounds.xMax - 1;

            Position doorPosition = RepeatedActionExecutor.Execute(() =>
            {
                var position = _rng.Choice(area.Perimeter);
                return(ValidForBeingDoor(position), position);
            });

            foreach (Position position in area.Perimeter)
            {
                if (position != doorPosition)
                {
                    Construct(position, House, _tileset.Wall);
                }
                else
                {
                    Construct(position, -1f, null);
                }
            }

            OsnowaBaseTile roofBaseTile = _tileset.Roof;

            foreach (Position housePosition in area.Positions)
            {
                Construct(housePosition, -1f, roofBaseTile);
                if (housePosition != doorPosition)
                {
                    _grid.SetWalkability(housePosition, 0f);
                    _walkability.Set(housePosition, 0f);
                }
            }

            BoundsInt boundsForRoofAdditions = area.Bounds;

            ++boundsForRoofAdditions.xMin;
            ++boundsForRoofAdditions.yMin;
            --boundsForRoofAdditions.xMax;
            --boundsForRoofAdditions.yMax;

            return(doorPosition);
        }
コード例 #9
0
ファイル: PositionFlagsResolver.cs プロジェクト: bmjoy/Osnowa
        public void SetFlagsAt(int x, int y, int tilesByIdsCount, OsnowaBaseTile[] tilesByIds, List <int> idsOfNotFoundTiles)
        {
            bool isWalkable     = true;
            bool isPassingLight = true;

            foreach (MatrixByte layerMatrix in _tileMatricesByteByLayer)
            {
                int tileId = layerMatrix.Get(x, y);
                if (tileId == 0)
                {
                    continue;
                }
                OsnowaBaseTile baseTile = null;
                if (tileId < tilesByIdsCount)
                {
                    baseTile = tilesByIds[tileId];
                }
                if (baseTile == null)
                {
                    idsOfNotFoundTiles?.Add(tileId);
                    continue;
                }

                if (baseTile.Walkability == WalkabilityModifier.ForceWalkable)
                {
                    isWalkable = true;
                }
                else if (baseTile.Walkability == WalkabilityModifier.ForceUnwalkable)
                {
                    isWalkable = false;
                }

                if (baseTile.IsPassingLight == PassingLightModifier.ForcePassing)
                {
                    isPassingLight = true;
                }
                else if (baseTile.IsPassingLight == PassingLightModifier.ForceBlocking)
                {
                    isPassingLight = false;
                }
            }

            _positionFlags.SetFlags(x, y, isWalkable, isPassingLight);
        }
コード例 #10
0
        public void Set(Tilemap tilemap, Position position, OsnowaBaseTile baseTileToSet)
        {
            OsnowaBaseTile[] tilesByIds = _tileByIdProvider.GetTilesByIds();
            int tilesByIdsCount         = tilesByIds.Length;

            tilemap.SetTile(position.ToVector3Int(), baseTileToSet);

            if (baseTileToSet is OsnowaTile osnowaTile)
            {
                tilemap.SetColor(position.ToVector3Int(), osnowaTile.Color);
            }
            else
            {
                tilemap.SetColor(position.ToVector3Int(), Color.white);
            }

            _positionFlagsResolver.SetFlagsAt(position.x, position.y, tilesByIdsCount, tilesByIds,
                                              idsOfNotFoundTiles: null);
        }
コード例 #11
0
        public OsnowaBaseTile[] GetTilesByIds()
        {
            if (_allTiles == null)
            {
                Debug.Log("FETCHING ALL TILES - this should happen only once!");
                _allTiles = AssetLoader.LoadAll <OsnowaBaseTile>();
            }

            int maxId = _allTiles.Max(t => t.Id);

            var result = new OsnowaBaseTile[maxId + 1];

            foreach (OsnowaBaseTile tile in _allTiles)
            {
                result[tile.Id] = tile;
            }

            return(result);
        }
コード例 #12
0
        public override IEnumerator Recalculating()
        {
            OsnowaBaseTile dirtBaseTile   = _worldGeneratorConfig.Tileset.DryDirt;
            MatrixByte     dirtMatrixByte = GameContext.TileMatricesByLayer[(int)dirtBaseTile.Layer];
            float          seaLevel       = GameContext.SeaLevel;

            foreach (Position position in Values.AllCellMiddles())
            {
                float value  = _initialShapeValues.Get(position);
                bool  isLand = value > seaLevel;
                value = isLand ? float.MaxValue : float.MinValue;
                Values.Set(position, value);
                if (isLand)
                {
                    dirtMatrixByte.Set(position, dirtBaseTile.Id);
                }
            }

            yield return(new WaitForSeconds(0.1f));
        }
コード例 #13
0
        /// <inheritdoc />
        public void ClearForTile(OsnowaBaseTile tileToCleanItsLayer)
        {
            int layerId = (int)tileToCleanItsLayer.Layer;

            _sceneContext.AllTilemapsByLayers[layerId].ClearAllTiles();
        }
コード例 #14
0
ファイル: TilemapGenerator.cs プロジェクト: bmjoy/Osnowa
    public void Generate()
    {
        var            stopwatch = Stopwatch.StartNew();
        IOsnowaContext context   = _contextManager.Current;
        int            xSize     = context.PositionFlags.XSize;
        int            ySize     = context.PositionFlags.YSize;

        _allTilemaps = _sceneContext.AllTilemapsByLayers.ToArray();

        foreach (Tilemap tilemap in _sceneContext.AllPresentableTilemaps)
        {
            tilemap.ClearAllTiles();
        }

        int totalMapArea = xSize * ySize;

        List <Vector3Int>[] batchPositionsLayers;
        List <TileBase>[]   batchTilesLayers;
        CreateBatchPositionsAndTilesLayers(totalMapArea, out batchPositionsLayers, out batchTilesLayers);

        OsnowaBaseTile[] tilesByIds = _tileByIdFromFolderProvider.GetTilesByIds();

        for (int x = 0; x < xSize; x++)
        {
            for (int y = 0; y < ySize; y++)
            {
                for (int matrixLayer = 0; matrixLayer < context.TileMatricesByLayer.Length; matrixLayer++)
                {
//						if (matrixLayer == TilemapLayers.Roof || matrixLayer == TilemapLayers.OnRoof)
//							continue;
                    MatrixByte tileMatrixByte = context.TileMatricesByLayer[matrixLayer];
                    byte       tileId         = tileMatrixByte.Get(x, y);
                    if (tileId == 0)
                    {
                        continue;
                    }

                    OsnowaBaseTile baseTile = tilesByIds[tileId];
                    if (baseTile == null)
                    {
                        throw new System.Exception($"Tile with ID {tileId} not found in tileset, but placed on map.");
                    }
                    PrepareTileToSet(x, y, batchPositionsLayers, batchTilesLayers, (TilemapLayer)matrixLayer, baseTile);
                }
            }
        }

        var stopwatchBatch = Stopwatch.StartNew();

        for (int tilemapIndex = 0; tilemapIndex < _allTilemaps.Length; tilemapIndex++)
        {
            Tilemap tilemap = _allTilemaps[tilemapIndex];
            tilemap.SetTiles(batchPositionsLayers[tilemapIndex].ToArray(), batchTilesLayers[tilemapIndex].ToArray());
            UnityEngine.Debug.Log(tilemap.name + " tilemap: " + stopwatchBatch.ElapsedMilliseconds + " milliseconds.");
            stopwatchBatch.Restart();
        }

        BoundsInt fogOfWarBounds = _sceneContext.TilemapDefiningOuterBounds.cellBounds;

        OsnowaBaseTile[] fogOfWarToSet = Enumerable.Repeat(_tileset.FogOfWar, fogOfWarBounds.size.x * fogOfWarBounds.size.y).ToArray();
        _sceneContext.FogOfWarTilemap.SetTilesBlock(fogOfWarBounds, fogOfWarToSet);

        BoundsInt maskBounds = _sceneContext.TilemapDefiningOuterBounds.cellBounds;

        OsnowaBaseTile[] unseenMaskToSet = Enumerable.Repeat(_tileset.UnseenMask, maskBounds.size.x * maskBounds.size.y).ToArray();
        _sceneContext.UnseenMaskTilemap.SetTilesBlock(maskBounds, unseenMaskToSet);

        UnityEngine.Debug.Log("Tile generation time for " + xSize * ySize + " positions: " + stopwatch.ElapsedMilliseconds);
        UnityEngine.Debug.Log("Total tiles: " + batchPositionsLayers.Sum(l => l.Count));
    }
コード例 #15
0
ファイル: TilemapGenerator.cs プロジェクト: bmjoy/Osnowa
 private void PrepareTileToSet(int x, int y, List <Vector3Int>[] batchPositionsLayers, List <TileBase>[] batchTilesLayers, TilemapLayer matrixLayer, OsnowaBaseTile baseTile)
 {
     if (matrixLayer != baseTile.Layer)
     {
         // todo: detect all occurences of situation below, but log once
         //Debug.LogWarning($"Layer mismatch on {x}, {y}: {tile.name} placed on layer {matrixLayer}, but tile layer is {tile.Layer}");
     }
     batchPositionsLayers[(int)matrixLayer].Add(new Vector3Int(x, y, 0));
     batchTilesLayers[(int)matrixLayer].Add(baseTile);
 }
コード例 #16
0
        public override void OnInspectorGUI()
        {
            int idFromEditor = EditorGUILayout.IntField("Unique ID", EditedTile.Id);

            if (idFromEditor != EditedTile.Id)
            {
                EditedTile.Id = (byte)idFromEditor;
                SaveTile();
            }

            TilemapLayer layerFromEditor = (TilemapLayer)EditorGUILayout.EnumPopup("Layer", EditedTile.Layer);

            if (layerFromEditor != EditedTile.Layer)
            {
                EditedTile.Layer = layerFromEditor;
                SaveTile();
            }

            WalkabilityModifier walkabilityFromEditor = (WalkabilityModifier)EditorGUILayout.EnumPopup("Walkability", EditedTile.Walkability);

            if (walkabilityFromEditor != EditedTile.Walkability)
            {
                EditedTile.Walkability = walkabilityFromEditor;
                SaveTile();
            }

            PassingLightModifier passingLightFromEditor = (PassingLightModifier)EditorGUILayout.EnumPopup("Passing light", EditedTile.IsPassingLight);

            if (passingLightFromEditor != EditedTile.IsPassingLight)
            {
                EditedTile.IsPassingLight = passingLightFromEditor;
                SaveTile();
            }

            EditorGUILayout.LabelField("Consistency class : when more than 0, the tile is treated by other OsnowaTiles as \"Neighbor.This\" for all other tiles with same consistency class.",
                                       new GUIStyle {
                wordWrap = true
            });
            int consistencyClassFromEditor = EditorGUILayout.IntField("Consistency class", EditedTile.ConsistencyClass);

            if (consistencyClassFromEditor != EditedTile.ConsistencyClass)
            {
                EditedTile.ConsistencyClass = consistencyClassFromEditor;
                SaveTile();
            }

            EditorGUILayout.LabelField("Drag another tile below if you want to use it as a shorter variant to display eg. when player is close to the tile:", new GUIStyle {
                wordWrap = true
            });
            OsnowaBaseTile shorterVariantTileFromEditor =
                EditorGUILayout.ObjectField("Shorter variant", EditedTile.ShorterVariant, typeof(OsnowaBaseTile), false) as OsnowaBaseTile;

            if (shorterVariantTileFromEditor != EditedTile.ShorterVariant)
            {
                EditedTile.ShorterVariant = shorterVariantTileFromEditor;
                SaveTile();
            }

            EditorGUILayout.Space();
            EditorGUILayout.LabelField("Rule generation. \r\n" +
                                       "1. Drag in a prepared multi-sprite, \r\n" +
                                       "2. generate the rules (<b>in order to see them you need to change Inspector focus to something else and back to this tile</b>),\r\n" +
                                       "3. <b>remember to save (ctrl+s) afterwards</b>.", new GUIStyle {
                wordWrap = true
            });
            EditedTile.GenerateFrom = (Sprite)EditorGUILayout.ObjectField("Multi-sprite source:", EditedTile.GenerateFrom, typeof(Sprite), false);

            if (GUILayout.Button("Remove all rules"))
            {
                EditedTile.m_TilingRules = null;
                SaveTile();
            }


            if (EditedTile.GenerateFrom != null && GUILayout.Button("Generate rules (box-like neighbourhood)"))
            {
                int[] sides =
                {
                    236,      41236,   412,  2,
                    89632, 78946123, 87412, 82,
                    896,      47896,   478,  8,
                    6,           46,     4,  5,
                };

                GenerateRules(sides, 5);
            }

            if (EditedTile.GenerateFrom != null && GUILayout.Button("Generate rules (8-sided neighbourhood)"))
            {
                // Performance tip if filling the tilemap is to slow:
                // Get occurence statistics of different rules (for sparsely- and densely appearing tiles)
                // and adjust the order of rule creation for them. That would help because refreshing of single tile
                // sequentially goes through all the rules untill it meets the satisfying one.
                int[] sides =
                {
                    236,        41236,   412,    2,      0,     42,   426,     26,
                    89632,   78946123, 87412,   82, 478263,    826,  4826,    842,
                    896,        47896,   478,    8, 896412,     86,   486,     48,
                    6,             46,     4,    5, 489632, 478962,  4236, 841236,
                    6987412,  4789632,  2146, 4782,   6982,  84269, 86247, 874126,

                    8741236,  8963214,  8632, 8964,   8746,   8214, 86214, 84236
                };

                GenerateRules(sides, 8);
            }

/* Doesn't work :( ctrl+s is needed anyway.
 *                      if (GUILayout.Button("Force save"))
 *                      {
 *                              SaveTile();
 *                      }*/

            Sprite defaultSpriteFromEditor = EditorGUILayout.ObjectField("Default Sprite", EditedTile.m_DefaultSprite, typeof(Sprite), false) as Sprite;

            if (defaultSpriteFromEditor != EditedTile.m_DefaultSprite)
            {
                EditedTile.m_DefaultSprite = defaultSpriteFromEditor;
                SaveTile();
            }

            var defaultColliderTypeFromEditor = (Tile.ColliderType)EditorGUILayout.EnumPopup("Default Collider", EditedTile.m_DefaultColliderType);

            if (defaultColliderTypeFromEditor != EditedTile.m_DefaultColliderType)
            {
                EditedTile.m_DefaultColliderType = defaultColliderTypeFromEditor;
                SaveTile();
            }

            EditorGUILayout.Space();

            if (m_ReorderableList != null && EditedTile.m_TilingRules != null)
            {
                m_ReorderableList.DoLayoutList();
            }
        }