private void SetupMap(int hirelings)
        {
            TurnFSM.SetTrigger(GameStateTransitions.Deselect);
            UI.InitializeUI();
            savedHirelings     = 0;
            remainingHirelings = hirelings;

            foreach (var unit in AllUnits)
            {
                Destroy(unit.gameObject);
            }
            AllUnits.Clear();

            foreach (var summoningCircle in summoningCircles)
            {
                Destroy(summoningCircle.gameObject);
            }
            summoningCircles.Clear();

            foreach (var dangerzone in AllDangerzones)
            {
                Destroy(dangerzone);
            }
            AllDangerzones.Clear();

            ClearOverlays();

            //spawn heros
            //TODO: sort of hard coded to be 3
            for (int i = 0; i < encounterData.Heros.Length; i++)
            {
                var hero = encounterData.Heros[i];
                SpawnUnit(roomInfo.HeroStartLocations[i] + Vector3Int.FloorToInt(roomInfo.transform.position), hero.LoadoutName, UnitController.SideEnum.Player, hero);
            }

            foreach (var startingBadGuy in roomInfo.InitialEnemies)
            {
                var location = FindEmptySpawnableLocation();
                SpawnUnit(location, startingBadGuy.LoadoutName, UnitController.SideEnum.BadGuy, startingBadGuy);
            }

            badGuyLoadouts = roomInfo.SpawnableBadGuys;
            turnCounter    = 0;
            StartCoroutine(NewTurn());
        }
        public IEnumerator ResolveEndTurnAndStartNext()
        {
            TriggerTransition(GameStateTransitions.Deselect);

            //apply Dangerzones
            foreach (var dangerzoneObject in AllDangerzones)
            {
                var unit       = AllUnits.Find(u => u.transform.position == dangerzoneObject.transform.position);
                var dangerzone = dangerzoneObject.GetComponent <DangerzoneController>();
                yield return(dangerzone.ApplyEndOfTurnEffects(this, unit));

                if (dangerzone.TriggerOnceThenDestroy)
                {
                    dangerzoneToDestroy.Add(dangerzoneObject);
                }
            }

            foreach (var dangerzoneObject in dangerzoneToDestroy)
            {
                AllDangerzones.Remove(dangerzoneObject);
                Destroy(dangerzoneObject);
            }
            dangerzoneToDestroy.Clear();

            //bad guys do stuff
            foreach (var badGuy in AllUnits.FindAll(u => u.Side == UnitController.SideEnum.BadGuy))
            {
                yield return(AbilityCoroutine(badGuy, badGuy.MyLoadout.Abilities[0], badGuy.TargetedTile));

                badGuy.ClearTargetOverlays();
            }

            //spawn more bad guys
            List <GameObject> circlesToDestroy = new List <GameObject>();

            foreach (var summoningCircle in summoningCircles)
            {
                var unitOnCircle = AllUnits.Find(u => u.transform.position == summoningCircle.transform.position);
                var dangerzone   = summoningCircle.GetComponent <DangerzoneController>();
                yield return(dangerzone.ApplyEndOfTurnEffects(this, unitOnCircle));

                if (dangerzone.TriggerOnceThenDestroy)
                {
                    circlesToDestroy.Add(summoningCircle);
                }
            }
            for (int i = 0; i < circlesToDestroy.Count; i++)
            {
                summoningCircles.Remove(circlesToDestroy[i]);
                Destroy(circlesToDestroy[i]);
            }

            //move hirlings
            foreach (var hireling in AllUnits.FindAll(u => u.Side == UnitController.SideEnum.Hireling))
            {
                while (hireling.CurrentMovement > 0)
                {
                    Vector3Int startingPos = Vector3Int.FloorToInt(hireling.transform.position);
                    var        tile        = Dungeon.GetTile <DungeonTile>(startingPos);
                    if (tile.Name == "Road")
                    {
                        var nextPosition = startingPos + GameManager.CardinalDirections[dungeonInfo.GetPositionProperty(startingPos, "RoadDirection", -1)];
                        var nextTile     = Dungeon.GetTile <DungeonTile>(nextPosition);
                        if (nextTile.Name == "Level Exit")
                        {
                            Kill(hireling);
                            savedHirelings++;
                            CheckVictoryConditions();
                            break;
                            //TODO: register as having made it
                        }

                        if (Passable(nextPosition, true))
                        {
                            List <Vector3Int> path = new List <Vector3Int>()
                            {
                                Vector3Int.FloorToInt(hireling.transform.position),
                                nextPosition
                            };
                            yield return(MoveUnit(hireling, path, true));
                        }
                        else
                        {
                            break;
                        }
                    }
                    else
                    {
                        //got knocke off path, stand still and panic
                        break;
                    }
                }
            }


            yield return(NewTurn());
        }
        void Update()
        {
            //sort out mouseover stuff
            MouseoverPoint = Dungeon.WorldToCell(Camera.main.ScreenToWorldPoint(Input.mousePosition));
            if (MouseoverPoint != PreviousMouseoverPoint)
            {
                MouseoverChangedEvent.Invoke(MouseoverPoint);
                PreviousMouseoverPoint = MouseoverPoint;
                foreach (var unit in AllUnits)
                {
                    unit.DisableUI();
                }
                var unitUnderMouse        = AllUnits.Find(u => u.transform.position == MouseoverPoint);
                var dungeonTileUnderMouse = (DungeonTile)Dungeon.GetTile(MouseoverPoint);
                if (unitUnderMouse != null)
                {
                    unitUnderMouse.EnableUI();
                }

                var dangerzoneUnderMouse = AllDangerzones.Where(d => d.transform.position == MouseoverPoint)
                                           .Select(d => d.GetComponent <DangerzoneController>()).ToList();
                dangerzoneUnderMouse.AddRange(
                    summoningCircles.Where(s => s.transform.position == MouseoverPoint).
                    Select(s => s.GetComponent <DangerzoneController>()));
                UI.ShowMouseOverInfo(dungeonTileUnderMouse, unitUnderMouse, dangerzoneUnderMouse);
            }

            if (!blockInputs)
            {
                //hot keyboard shortcuts
                if (Input.GetKeyDown(KeyCode.Escape))
                {
                    TurnFSM.SetTrigger(GameStateTransitions.Deselect);
                }
                else if (Input.GetKeyDown(KeyCode.Alpha1))
                {
                    if (UnitClicked != null && UnitClicked.MyLoadout.Abilities.Length > 0)
                    {
                        AbilityButtonClick(0);
                    }
                }
                else if (Input.GetKeyDown(KeyCode.Alpha2))
                {
                    if (UnitClicked != null && UnitClicked.MyLoadout.Abilities.Length > 1)
                    {
                        AbilityButtonClick(1);
                    }
                }
                else if (Input.GetKeyDown(KeyCode.Alpha3))
                {
                    if (UnitClicked != null && UnitClicked.MyLoadout.Abilities.Length > 2)
                    {
                        AbilityButtonClick(2);
                    }
                }

                if (Input.GetMouseButtonDown(1) || Input.GetKeyDown(KeyCode.Escape))
                {
                    TriggerTransition(GameStateTransitions.Deselect);
                }
                if (Input.GetMouseButtonDown(0))
                {
                    RaycastHit2D[] hits = Physics2D.RaycastAll(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);
                    foreach (var hit in hits)
                    {
                        if (hit.collider != null)
                        {
                            if (hit.collider.CompareTag("Unit"))
                            {
                                UnitClickedEvent.Invoke(hit.collider.GetComponent <UnitController>());
                            }
                            else if (hit.collider.CompareTag("UIHighlights"))
                            {
                                var destination = Dungeon.WorldToCell(hit.point);
                                //TODO: don't hardcode to first ability
                                UIHighlightClickedEvent.Invoke(destination);
                            }
                        }
                    }
                }
            }
        }