Exemplo n.º 1
0
        private void Update()
        {
            if (!_isActive)
            {
                return;
            }
            if (grid == null || grid.Value == null)
            {
                return;
            }
            if (uiTilemap == null)
            {
                return;
            }

            // todo(chris) remove nasty hack for "is paused"
            if (Time.timeScale < float.Epsilon)
            {
                return;
            }

            var worldPoint = _camera.ScreenToWorldPoint(Input.mousePosition);
            var node       = new Grid.Grid.Node();

            if (grid.Value.TryGetNodeAtWorldPosition(worldPoint, ref node))
            {
                if (_node?.Equals(node) != true)
                {
                    _node = node;
                    OnNewNode(node);
                }
            }
        }
Exemplo n.º 2
0
        private void OnNewNode(Grid.Grid.Node node)
        {
            switch (_mode)
            {
            case MouseMode.Moving:
                highlightedUiTilemap.ClearAllTiles();

                _path = _pathfinding.CalculatePath(_player.transform.position, node.WorldPosition);

                if (_path != null && _path.Count > 0)
                {
                    foreach (var n in _path)
                    {
                        var pos = grid.Value.Position00.ToVector2Int() + n.Position;
                        highlightedUiTilemap.SetTile((Vector3Int)pos, up);
                    }
                }
                else
                {
                    var pos = grid.Value.Position00.ToVector2Int() + node.Position;
                    if (uiTilemap.HasTile((Vector3Int)pos))
                    {
                        highlightedUiTilemap.SetTile((Vector3Int)pos, attackTile);
                    }
                }

                break;

            case MouseMode.RangedWeaponMode:
                var diff = node.Position - _player.CurrentNodeIdx;

                highlightedUiTilemap.ClearAllTiles();
                if (diff.IsCardinal())
                {
                    HighlightCardinal(diff, highlightedUiTilemap);
                }
                break;

            case MouseMode.OtherWeapon:
                var effected = _item.FindAllPossibleEffectedNodes(_player.Occupant, grid.Value);
                if (effected.Contains(node))
                {
                    var pos = grid.Value.Position00.ToVector2Int() + node.Position;
                    if (uiTilemap.HasTile((Vector3Int)pos))
                    {
                        highlightedUiTilemap.SetTile((Vector3Int)pos, highlighted);
                    }
                }

                break;

            default:
                break;
            }
        }
Exemplo n.º 3
0
        private void Start()
        {
            var offsetX = .5f;
            var offsety = .5f;

            Grid.Node[,] nodes = new Grid.Node[width, height];

            StringBuilder sb = new StringBuilder();

            for (int x = 0; x < width; ++x)
            {
                for (int y = 0; y < height; ++y)
                {
                    var worldPosition = new Vector3(x + bottomLeft.x + offsetX, y + bottomLeft.y + offsety);
                    var cellPos       = impassable.WorldToCell(worldPosition);
                    var tile          = impassable.GetTile(cellPos);

                    if (tile)
                    {
                        nodes[x, y] = new Grid.Node(x, y, -1, worldPosition);

                        sb.Append(", -1");

                        continue;
                    }


                    cellPos = impassable.WorldToCell(worldPosition);

                    tile = passable.GetTile(cellPos);

                    if (tile)
                    {
                        nodes[x, y] = new Grid.Node(x, y, 1, worldPosition);
                        sb.Append(",  1");
                        continue;
                    }

                    nodes[x, y] = new Grid.Node(x, y, -2, worldPosition);
                    sb.Append(", -2");
                }

                sb.Append("\n");
            }

            //   Debug.Log("grid:\n" + sb.ToString());

            _grid = new SquareGrid(nodes, bottomLeft);

            output.Value = _grid;
            onGridGenerated.Raise();
        }
 public List <IUnitAction> CollideWith(GridOccupant other, Grid.Grid.Node otherNode)
 {
     // if I hurt things on collision then hurt them
     if (OnCollisionEffects?.CanTarget(other, _occupant.Occupant, _occupant.Grid) == true)
     {
         var diff = new Vector2Int(otherNode.X, otherNode.Y) - _occupant.CurrentNodeIdx;
         return(OnCollisionEffects.Use(_occupant.Occupant, diff, _occupant.Grid));
     }
     else
     {
         return(null);
     }
 }
Exemplo n.º 5
0
        private bool IsNodeValid(Grid.Grid.Node node)
        {
            if (_onGoing.Contains(node))
            {
                return(false);
            }

            foreach (var occupant in node.Occupants)
            {
                if (cantSpawnOn.Contains(occupant.Type))
                {
                    return(false);
                }
            }

            return(true);
        }
Exemplo n.º 6
0
        private IEnumerator OnCollision(Unit.Unit unit, Grid.Grid.Node startNode, Grid.Grid.Node lastNode, float speed, bool twoWayCollisions, Transform toMove)
        {
            if (_collisionBehaviour != null)
            {
                var colliderOccupant = _collider2D.gameObject.GetComponent <GridOccupantBehaviour>();
                unit.QueueRange(_collisionBehaviour.CollideWith(colliderOccupant.Occupant, colliderOccupant.CurrentNode.Value));
            }

            if (twoWayCollisions)
            {
                var collision = _collider2D.GetComponent <OnCollisionBehaviour>();
                if (collision != null)
                {
                    unit.QueueRange(collision.CollideWith(unit.Occupant.Occupant, startNode));
                }
            }

            yield return(StartCoroutine(CoMove(unit, lastNode, speed, false, toMove)));
            // unit.QueueAction(new MoveToPointAction(unit, lastNode, toMove, false));
        }
Exemplo n.º 7
0
        public List <Grid.Grid.Node> CalculatePath(Vector2 from, Vector2 to, bool considerEndCost = true)
        {
            var startNode = new Grid.Grid.Node();
            var endNode   = new Grid.Grid.Node();

            if (grid == null)
            {
                grid = _grid.Get();
            }

            if (!grid.Value.TryGetNodeAtWorldPosition(from, ref startNode))
            {
                return(new List <Grid.Grid.Node>());
            }
            if (!grid.Value.TryGetNodeAtWorldPosition(to, ref endNode))
            {
                return(new List <Grid.Grid.Node>());
            }


            return(CalculatePath(grid.Value, startNode, endNode, considerEndCost));
        }
Exemplo n.º 8
0
        private IEnumerator CoMove(Unit.Unit unit, Grid.Grid.Node destination, float speed, bool twoWayCollisions, Transform toMove)
        {
            Vector2 endPoint = destination.WorldPosition;

            var startNode = unit.Occupant.CurrentNode;

            if (startNode == null)
            {
                yield break;
            }

            var lastNode = startNode.Value;

            var startPoint = (Vector2)toMove.position;
            var start      = Time.time;
            var distance   = (endPoint - startPoint).magnitude;
            var duration   = distance / speed;
            var end        = start + duration;

            _collider2D = null;

            onStartMove.Invoke();

            while (Time.time < end && _collider2D == null)
            {
                var t = (Time.time - start) / duration;
                var x = Tween.Lerp(startPoint.x, endPoint.x, t);
                var y = Tween.Lerp(startPoint.y, endPoint.y, t);
                toMove.position = new Vector3(x, y, toMove.position.z);

                if (moveToLastNodeOnCollision)
                {
                    var node = new Grid.Grid.Node();
                    if (!unit.Occupant.Grid.TryGetNodeAtWorldPosition(toMove.position, ref node))
                    {
                        toMove.position = lastNode.WorldPosition;
                        yield break;
                    }

                    if (!node.Equals(lastNode) && !node.Equals(destination))
                    {
                        if (Vector2.Distance(toMove.position, node.WorldPosition) < .4f)
                        {
                            lastNode = node;
                        }
                    }
                }

                yield return(null);
            }

            OnStopMove.Invoke();

            if (_collider2D == null && _myCollider != null)
            {
                var cached = _myCollider.enabled;
                _myCollider.enabled = false;
                _collider2D         = Physics2D.OverlapCircle(toMove.position, .3f, layers);

                _myCollider.enabled = cached;
            }

            if (_collider2D == null)
            {
                toMove.position = new Vector3(endPoint.x, endPoint.y, toMove.position.z);
            }
            else
            {
                yield return(StartCoroutine(OnCollision(unit, startNode.Value, lastNode, speed, twoWayCollisions, toMove)));
            }
        }
Exemplo n.º 9
0
        private IEnumerator CoMove(Unit.Unit unit, Grid.Grid.Node destination, float speed, bool twoWayCollisions, Action onComplete, Transform toMove)
        {
            yield return(StartCoroutine(CoMove(unit, destination, speed, twoWayCollisions, toMove)));

            onComplete();
        }
Exemplo n.º 10
0
 public void Move(Unit.Unit unit, Grid.Grid.Node destination, Action onComplete, bool twoWayCollisions = false, Transform toMove = null)
 {
     StartCoroutine(CoMove(unit, destination, speed, twoWayCollisions, onComplete, toMove ?? transform));
 }
        private IEnumerator BuildRoom()
        {
            LevelDefinition level          = new LevelDefinition();
            var             adjustedHeight = height + 4;
            var             adjustedWidth  = width + 4;

            char[,] roomChars = new char[adjustedWidth, adjustedHeight];
            char playerEntrance = 'b';

            bool levelParsed = false;

            while (!levelParsed)
            {
                try
                {
                    level = PickRoom(out playerEntrance, out var flipX, out var flipY);
                    var roomString = level.Level;
                    // var roomString = room.Template;

                    roomChars = StringToCharTable(width, height, roomString);

                    roomChars = ExpandChunks(roomChars);

                    roomChars = AddBorder(roomChars);

                    if (flipX)
                    {
                        roomChars = FlipX(roomChars, adjustedWidth, adjustedHeight);
                    }

                    if (flipY)
                    {
                        roomChars = FlipY(roomChars, adjustedWidth, adjustedHeight);
                    }


                    levelParsed = true;
                }
                catch (Exception e)
                {
                    Debug.LogException(e);
                    // without this we have no game, pick a a new room and try again
                }
            }

            var grid = new Grid.Node[adjustedWidth, adjustedHeight];

            int        tileIdx       = 0;
            Vector3Int pos           = Vector3Int.zero;
            Vector2    worldPos      = Vector2.zero;
            bool       playerSpawned = false;

            var enemySpawnPoints       = new List <Vector3Int>();
            var terrainSpawnPoints     = new List <Vector3Int>();
            var lootSpawnPoints        = new List <Vector3Int>();
            var specialLootSpawnPoints = new List <Vector3Int>();

            for (int y = 0; y < adjustedHeight; ++y)
            {
                pos.y      = y;
                worldPos.y = y + .5f;

                for (int x = 0; x < adjustedWidth; ++x)
                {
                    pos.x      = x;
                    worldPos.x = x + .5f;


                    switch (roomChars[x, y])
                    {
                    case 'c':
                    {
                        chasm.SetTile(pos, tiles.ChasmTiles.RandomElement());
                        var go = Instantiate(tiles.Chasm, worldPos, Quaternion.identity);
                        go.transform.parent = chasmParent;
                        grid[x, y]          = new Grid.Node(x, y, -2, worldPos);
                        break;
                    }

                    case 'u':
                    {
                        var go = Instantiate(tiles.UnbreakableWall, worldPos, Quaternion.identity);
                        go.transform.parent = unbreakableParent;
                        grid[x, y]          = new Grid.Node(x, y, -2, worldPos);
                        break;
                    }

                    case 'w':
                    {
                        walls.SetTile(pos, tiles.Wall);
                        floor.SetTile(pos, tiles.FloorTiles.RandomElement());
                        grid[x, y] = new Grid.Node(x, y, 1, worldPos);
                        break;
                    }

                    case 'b':     // entry/exit
                    {
                        playerSpawned = SpawnEntrance(
                            'b',
                            playerEntrance,
                            playerSpawned,
                            worldPos,
                            Vector2.down,
                            tiles.BottomExit
                            );

                        floor.SetTile(pos, tiles.FloorTiles.RandomElement());
                        grid[x, y] = new Grid.Node(x, y, 1, worldPos);
                        break;
                    }

                    case 'l':     // entry/exit
                    {
                        playerSpawned = SpawnEntrance(
                            'l',
                            playerEntrance,
                            playerSpawned,
                            worldPos,
                            Vector2.left,
                            tiles.LeftExit
                            );

                        floor.SetTile(pos, tiles.FloorTiles.RandomElement());
                        grid[x, y] = new Grid.Node(x, y, 1, worldPos);
                        break;
                    }

                    case 't':     // entry/exit
                    {
                        playerSpawned = SpawnEntrance(
                            't',
                            playerEntrance,
                            playerSpawned,
                            worldPos,
                            Vector2.up,
                            tiles.TopExit
                            );

                        floor.SetTile(pos, tiles.FloorTiles.RandomElement());
                        grid[x, y] = new Grid.Node(x, y, 1, worldPos);
                        break;
                    }

                    case 'r':     // entry/exit
                    {
                        playerSpawned = SpawnEntrance(
                            'r',
                            playerEntrance,
                            playerSpawned,
                            worldPos,
                            Vector2.right,
                            tiles.RightExit
                            );

                        floor.SetTile(pos, tiles.FloorTiles.RandomElement());
                        grid[x, y] = new Grid.Node(x, y, 1, worldPos);
                        break;
                    }

                    case 'n':     // entry/exit
                    {
                        floor.SetTile(pos, tiles.FloorTiles.RandomElement());
                        grid[x, y] = new Grid.Node(x, y, 1, worldPos);
                        break;
                    }

                    case 'h':     // high value item
                    {
                        specialLootSpawnPoints.Add(pos);
                        floor.SetTile(pos, tiles.FloorTiles.RandomElement());
                        grid[x, y] = new Grid.Node(x, y, 1, worldPos);
                        break;
                    }

                    default:     // must be floor so can spawns ememies and loot here
                    {
                        enemySpawnPoints.Add(pos);
                        terrainSpawnPoints.Add(pos);
                        lootSpawnPoints.Add(pos);

                        floor.SetTile(pos, tiles.FloorTiles.RandomElement());
                        grid[x, y] = new Grid.Node(x, y, 1, worldPos);
                        break;
                    }
                    }

                    if (timelapse > 0)
                    {
                        yield return(new WaitForSeconds(timelapse));
                    }
                }
            }

            var enemiesAmount = UnityEngine.Random.Range(level.MinEnemies, level.MaxEnemies + 1);
            var terrainAmount = UnityEngine.Random.Range(level.MinTerrain, level.MaxTerrain + 1);
            var itemsAmount   = UnityEngine.Random.Range(level.MinItems, level.MaxItems + 1);

            while (enemySpawnPoints.Count > 0 && enemiesAmount > 0)
            {
                var point = enemySpawnPoints.RandomElement();
                worldPos = new Vector2(point.x + .5f, point.y + .5f);

                var spawned = false;
                foreach (var enemy in tiles.Enemies)
                {
                    if (UnityEngine.Random.Range(1, enemy.Second) == 1)
                    {
                        var go = Instantiate(enemy.First, worldPos, Quaternion.identity);
                        go.transform.parent = enemiesParent;
                        spawned             = true;
                        break;
                    }
                }

                if (spawned)
                {
                    --enemiesAmount;
                    enemySpawnPoints.Remove(point);
                }
            }


            while (terrainSpawnPoints.Count > 0 && terrainAmount > 0)
            {
                var point = terrainSpawnPoints.RandomElement();
                worldPos = new Vector2(point.x + .5f, point.y + .5f);

                var spawned = false;
                foreach (var terrain in tiles.Terrain)
                {
                    if (UnityEngine.Random.Range(1, terrain.Second) == 1)
                    {
                        var go = Instantiate(terrain.First, worldPos, Quaternion.identity);
                        go.transform.parent = terrainParent;
                        spawned             = true;
                        break;
                    }
                }

                if (spawned)
                {
                    --terrainAmount;
                    terrainSpawnPoints.Remove(point);
                }
            }

            while (lootSpawnPoints.Count > 0 && itemsAmount > 0)
            {
                var point = lootSpawnPoints.RandomElement();
                worldPos = new Vector2(point.x + .5f, point.y + .5f);

                var spawned = false;
                foreach (var item in tiles.Items)
                {
                    if (UnityEngine.Random.Range(1, item.Second) == 1)
                    {
                        var go = Instantiate(tiles.Pickup, worldPos, Quaternion.identity);
                        // go.transform.parent = enemiesParent;
                        go.GetComponent <PickUpBehaviour>().SetItem(item.First);

                        spawned = true;
                        break;
                    }
                }

                if (spawned)
                {
                    --itemsAmount;
                    lootSpawnPoints.Remove(point);
                }
            }



            output.Value = new SquareGrid(grid, Vector2.zero);
            yield return(null);

            onGridBuilt.Raise();
            yield break;
        }
Exemplo n.º 12
0
        private List <Grid.Grid.Node> CalculatePath(Grid.Grid grid, Grid.Grid.Node start, Grid.Grid.Node end, bool considerEndCost)
        {
            var path = new List <Grid.Grid.Node>();

            var frontier  = new PriorityQueue <Grid.Grid.Node, int>();
            var cameFrom  = new Dictionary <Grid.Grid.Node, Grid.Grid.Node>();
            var costSoFar = new Dictionary <Grid.Grid.Node, int>();

            frontier.Enqueue(start, 0);
            cameFrom[start]  = start;
            costSoFar[start] = 0;

            while (frontier.Count > 0)
            {
                var current = frontier.Dequeue();

                if (current.Equals(end))
                {
                    var n = end;

                    while (!n.Equals(start))
                    {
                        path.Add(n);
                        n = cameFrom[n];
                    }

                    path.Reverse();
                    return(path);
                }

                var costToCurrent = costSoFar[current];
                foreach (var next in grid.GetNeighbours(current))
                {
                    var cost = costToCurrent;
                    if (next.Equals(end) && !considerEndCost)
                    {
                        cost += 1;
                    }
                    else if (next.Cost < 0)
                    {
                        continue;
                    }
                    else
                    {
                        cost += next.Cost;
                    }

                    if (costSoFar.ContainsKey(next) && cost >= costSoFar[next])
                    {
                        continue;
                    }

                    costSoFar[next] = cost;
                    int priority = cost + Heuristic(next, end);
                    frontier.Enqueue(next, priority);
                    cameFrom[next] = current;
                }
            }

            return(path);
        }
Exemplo n.º 13
0
 private int Heuristic(Grid.Grid.Node node, Grid.Grid.Node end)
 {
     return(Math.Abs(node.X - end.X) + Math.Abs(node.Y - end.Y));
 }