Example #1
0
        public override ActivityStep ResolveStep(GameEntity entity)
        {
            float chanceToStop = entity.isAggressive ? 0.2f : 0.07f;

            if (!_targetToKeepDistanceTo.hasPosition || _rng.Check(chanceToStop))
            {
                return(Succeed(entity));
            }
            int turnsPassed = 1;         // osnowatodo Contexts.sharedInstance.game.turMinelo.Tur;

            bool  targetPositionHasChanged = _targetToKeepDistanceTo.position.Position != _lastTargetPosition;
            float chanceToKeepPosition     = 0.8f;
            bool  shouldKeepPosition       = !targetPositionHasChanged && _rng.Check(chanceToKeepPosition);

            if (shouldKeepPosition)
            {
                return(KeepPosition(entity));
            }

            bool recalculateCooldownHasPassed = turnsPassed >= _turnsPassedToRecalculate;
            bool shouldRecalculate            = (_navigationDataToGoodPosition == null) ||
                                                (recalculateCooldownHasPassed && (targetPositionHasChanged || _rng.Check(0.2f)));

            if (shouldRecalculate)
            {
                _turnsPassedToRecalculate = turnsPassed + 3;
                _lastTargetPosition       = _targetToKeepDistanceTo.position.Position;

                IFloodArea targetFlood = _calculatedAreaAccessor.FetchWalkableFlood(_lastTargetPosition, _preferredDistance);
                _navigationDataToGoodPosition = FindNavigationDataToGoodPosition(entity, targetFlood, _preferredDistance);
                if (_navigationDataToGoodPosition == null)
                {
                    return(Fail(entity));
                }
            }

            Position         nextStep;
            NavigationResult navigationResult = _navigator.ResolveNextStep(_navigationDataToGoodPosition, entity.position.Position, out nextStep);

            if (navigationResult == NavigationResult.Finished)
            {
                return(new ActivityStep
                {
                    GameAction = _actionFactory.CreatePassAction(entity),
                    State = ActivityState.InProgress
                });
            }
            if (nextStep == PositionUtilities.Min)
            {
                return(Fail(entity));
            }

            IGameAction moveGameAction = CreateMoveAction(entity, nextStep);

            return(new ActivityStep
            {
                State = ActivityState.InProgress,
                GameAction = moveGameAction
            });
        }
Example #2
0
        public override ActivityStep ResolveStep(GameEntity entity)
        {
            if (!_targetEntity.hasPosition)
            {
                return(Succeed(entity));
            }

            if (Position.Distance(_targetEntity.position.Position, entity.position.Position) >= _giveUpDistance)
            {
                return(Fail(entity));
            }

            Position targetCurrentPosition = _targetEntity.position.Position;

            bool targetIsOneStepAway = PositionUtilities.IsOneStep(entity.position.Position - targetCurrentPosition);

            if (targetIsOneStepAway)
            {
                return(new ActivityStep
                {
                    State = ActivityState.InProgress,
                    GameAction = _actionFactory.CreateAttackAction(entity, _targetEntity),
                });
            }

            if (_rng.Check(0.03f))
            {
                return(Fail(entity, _actionFactory.CreatePassAction(entity, 3f)));
            }

            bool targetPositionHasChanged = targetCurrentPosition != _lastTargetPosition;

            if (targetPositionHasChanged)
            {
                _lastTargetPosition = targetCurrentPosition;
            }
            if (targetPositionHasChanged || _navigationData == null)
            {
                // performance: should in fact be done every couple of turns
                _navigationData = _navigator.GetNavigationData(entity.position.Position, targetCurrentPosition);
            }

            Position         nextStep;
            NavigationResult navigationResult = _navigator.ResolveNextStep(_navigationData, entity.position.Position, out nextStep);

            if (navigationResult == NavigationResult.Finished)
            {
                return(Succeed(entity));
            }

            IGameAction moveGameAction = CreateMoveAction(nextStep, entity);

            return(new ActivityStep
            {
                State = ActivityState.InProgress,
                GameAction = moveGameAction
            });
        }
Example #3
0
        public virtual void Show()
        {
            _spriteRenderer.enabled = true;

            for (int i = 0; i < transform.childCount; i++)
            {
                if (transform.GetChild(i).name == "ControlArrows")
                {
                    continue;
                }
                transform.GetChild(i).gameObject.SetActive(true);
            }
            if (this is ActorBehaviour)
            {
                _swordsIndicator.InitializeActiveSwords((this as ActorBehaviour).ActorData.Swords);

                var   actorData = ((ActorBehaviour)this).ActorData;
                float chance    = actorData.ActorType == ActorType.LastMonster ? 1.0f : 0.6f;
                if (actorData.Team == Team.Neutral && _rng.Check(chance))
                {
                    string text = "";
                    if (actorData.ActorType == ActorType.Dog)
                    {
                        text = _rng.Choice(new[] { "Woof!", "Whrrrr!", "Woof! Woof!" });
                    }
                    else if (actorData.ActorType == ActorType.LastMonster)
                    {
                        text = _rng.Choice(new[] { "BACK TO YOUR WARD!!!" });
                    }
                    else if (actorData.ActorType == ActorType.BruisedRat)
                    {
                        text = _rng.Choice(new[] { "Give me your guts!", "Squeak! Squeak!", "Ghhhrrr!" });
                    }
                    else
                    {
                        text = _rng.Choice(new[]
                        {
                            "You?!", "The prisoner is loose!", "Back to your ward!", "Squeak!", "He's there!", "", "", "En garde!", "Have at you!",
                            "Comrades, help me!", "Aah!"
                        });
                    }
                    _textEffectPresenter.ShowTextEffect(EntityData.LogicalPosition, text, text == "BACK TO YOUR WARD!!!" ? Color.magenta : Color.white, text == "BACK TO YOUR WARD!!!");
                }
            }
        }
Example #4
0
        public override IEnumerable <IActionEffect> Execute()
        {
            float chanceToSucceed = ActorData.Accuracy;
            bool  success         = _rng.Check(chanceToSucceed);

            yield return(new BumpEffect(ActorData, _targetEnemy.LogicalPosition));

            if (success)
            {
                _targetEnemy.Energy -= 1.2f;
                --ActorData.Swords;

                Vector2Int direction = _targetEnemy.LogicalPosition - ActorData.LogicalPosition;

                Assert.IsTrue(Vector2IntUtilities.IsOneStep(direction));

                Vector2Int previousPosition = _targetEnemy.LogicalPosition;
                _targetEnemy.LogicalPosition += direction;
                yield return(new MoveEffect(_targetEnemy, previousPosition, _gridInfoProvider, _entityDetector, _uiConfig));
            }
        }
Example #5
0
        public override IEnumerable <IActionEffect> Execute()
        {
            float chanceToDealAccurateBlow = ActorData.Accuracy;
            bool  accurate = _rng.Check(chanceToDealAccurateBlow);

            if (_isDaringBlow)
            {
                ActorData.Swords -= 2;
            }

            bool hit = (_isDaringBlow || _attackedActor.Swords <= 0) && accurate;

            if (hit)
            {
                int damage = Math.Max(_rng.Next(ActorData.WeaponWeld.WeaponDefinition.MaxDamage + 1), _rng.Next(ActorData.WeaponWeld.WeaponDefinition.MaxDamage + 1));
                _attackedActor.Health -= damage;
                if (_attackedActor.Health <= 0)
                {
                    _deathHandler.HandleDeath(_attackedActor);
                    ActorData.Xp += _attackedActor.XpGiven;
                }

                if (_attackedActor.ActorType == ActorType.Basher && ActorData.ActorType == ActorType.Player && _attackedActor.HealthProgress < 0.5f)
                {
                    _uiConfig.BasherMessage.gameObject.SetActive(true);
                    _uiConfig.BasherMessage.GetComponent <RectTransform>().sizeDelta = new Vector3(560, 180);
                    _uiConfig.BasherMessage.SetMessage("Ouch! Enough for me! That was a satisfactory duel. My reputation is clean now. Thank you! Now, we have to go. To south, along the road!");
                    _gameContext.BasherSteps  = 2;
                    _attackedActor.Team       = Team.Beasts;
                    ActorData.HasFinishedDuel = true;
                    ActorData.HasWonDuel      = true;
                }
                if (_attackedActor.ActorType == ActorType.Player && ActorData.ActorType == ActorType.Basher && _attackedActor.HealthProgress < 0.5f)
                {
                    _uiConfig.BasherMessage.gameObject.SetActive(true);
                    _uiConfig.BasherMessage.GetComponent <RectTransform>().sizeDelta = new Vector3(560, 180);
                    _uiConfig.BasherMessage.SetMessage("Ha! I think you've had enough. That was a good duel! My reputation is clean now. Thank you! Now, we have to go. To south, along the road!");
                    _gameContext.BasherSteps       = 2;
                    ActorData.Team                 = Team.Beasts;
                    _attackedActor.HasFinishedDuel = true;
                    _attackedActor.HasWonDuel      = false;
                }

                yield return(new LambdaEffect(() =>
                {
                    Animator blood = Resources.Load <Animator>("Prefabs/Blood");
                    Animator bloodObject = GameObject.Instantiate(blood, AttackedActor.Entity.transform.position, Quaternion.identity);
                    bloodObject.Play("Blood");
                    GameObject.Destroy(bloodObject.gameObject, .4f);
                }));
            }

            if (_attackedActor.Swords > 0 && accurate)
            {
                --_attackedActor.Swords;
            }

            if (ActorData.WeaponWeld.WeaponDefinition.IsBodyPart)
            {
                IActionEffect bumpEffect = ActionEffectFactory.CreateBumpEffect(ActorData, AttackedActor.LogicalPosition);
                yield return(bumpEffect);
            }
            else
            {
                IActionEffect strikeEffect = ActionEffectFactory.CreateStrikeEffect(ActorData, AttackedActor, !hit, _isDaringBlow);
                yield return(strikeEffect);
            }


            AttackedActor.BlockedUntil = DateTime.UtcNow + TimeSpan.FromMilliseconds(300);
            ActorData.BlockedUntil     = DateTime.UtcNow + TimeSpan.FromMilliseconds(300);
        }
Example #6
0
        public void HandleDeath(ActorData actorData)
        {
            ItemDefinition weaponToSpawn = actorData.WeaponWeld;

            _entityRemover.CleanSceneAndGameContextAfterDeath(actorData);
            //_entitySpawner.SpawnItem(_gameConfig.ItemConfig.Definitions.FirstOrDefault(i => i.ItemType == ItemType.PotionOfFriend), actorData.LogicalPosition);
            if (actorData.ActorType == ActorType.Basher)
            {
                _gameContext.BasherDead = true;
            }
            if (actorData.IsBoss && _gameContext.CurrentDungeonIndex == 0)
            {
                _entitySpawner.SpawnItem(_gameConfig.ItemConfig.Definitions.First(i => i.ItemType == ItemType.PotionOfBuddy), actorData.LogicalPosition);
            }
            else if (actorData.ActorType != ActorType.Buddy && actorData.ActorType != ActorType.Friend && _rng.Check(0.42f))
            {
                ItemDefinition[] itemPool = actorData.XpGiven < 15
                                        ? _gameConfig.ItemConfig.ItemPoolWeak
                                        : actorData.XpGiven < 26 ? _gameConfig.ItemConfig.ItemPoolMedium : _gameConfig.ItemConfig.ItemPoolStrong;
                ItemDefinition item = _rng.Choice(itemPool);

                _entitySpawner.SpawnItem(item, actorData.LogicalPosition);
            }

            if (!weaponToSpawn.WeaponDefinition.IsBodyPart && actorData.ActorType != ActorType.Buddy && actorData.ActorType != ActorType.Friend)
            {
                _entitySpawner.SpawnItem(weaponToSpawn, actorData.LogicalPosition);
            }

            if (actorData.ControlledByPlayer)
            {
                _uiConfig.RestartButton.gameObject.SetActive(true);
                var postMortem = "You died at level " + actorData.Level + " after surviving " + actorData.RoundsCount +
                                 " rounds. \r\nIf you have trouble playing, check out \"Combat help\" to the right. Restart?";
                _uiConfig.RestartButton.transform.GetComponentInChildren <Text>().text = postMortem;
            }
        }
Example #7
0
        private IGameAction ResolveActionForAggresion(ActorData actorData)
        {
            if (_rng.Check(0.04f))
            {
                if (_gameContext.PlayerActor.ActorData.Health <= 0)
                {
                    if (_rng.Check(0.07f))
                    {
                        string text = _rng.Choice(new[] { "Ha, ha!", "I got him!", "I know my strength!", "Got what he deserved!",
                                                          "Guess what we'll cook for dinner..." });
                        _textEffectPresenter.ShowTextEffect(actorData.LogicalPosition, text);
                    }
                }
                else if (actorData.ActorType == ActorType.Dog && actorData.Team != Team.Beasts)
                {
                    string text = _rng.Choice(new[] { "Woof", "Wrrrr!" });
                    _textEffectPresenter.ShowTextEffect(actorData.LogicalPosition, text);
                }
                else if (actorData.ActorType == ActorType.LastMonster)
                {
                    var potential = new[] { "Whshsh!", "Rrrruv!" }.ToList();
                    if (!actorData.Entity.IsVisible)
                    {
                        potential.AddRange(new[] { "[THUD!]", "[THUD!]", "[THUD!]" });
                    }
                    string text = _rng.Choice(potential);
                    _textEffectPresenter.ShowTextEffect(actorData.LogicalPosition, text, text == "[THUD!]" ? Color.white
                                                : Color.magenta, true);
                }
                else if (actorData.ActorType == ActorType.Friend || actorData.ActorType == ActorType.Buddy)
                {
                    string text = _rng.Choice(new[] { "Ma-uluh, ruv!", "Suku bgeve lir...", "Alir tak rettenekopast!" });
                    _textEffectPresenter.ShowTextEffect(actorData.LogicalPosition, text, new Color(0.7f, 0.8f, 1f));
                }
                else if (actorData.ActorType != ActorType.Basher && actorData.ActorType != ActorType.LastMonster)
                {
                    string text = _rng.Choice(new[] { "Back to your ward!", "Squeak!", "You're mine!", "Comrades, help me!", "Aah!" });
                    _textEffectPresenter.ShowTextEffect(actorData.LogicalPosition, text);
                }
            }

            List <ActorData> enemiesClose = _entityDetector.DetectActors(actorData.LogicalPosition, actorData.VisionRayLength)
                                            .Where(a => a.Team != actorData.Team && a.Entity.IsVisible)
                                            .ToList();

            enemiesClose.Sort((first, second) =>
                              Vector2IntUtilities.WalkDistance(first.LogicalPosition, actorData.LogicalPosition)
                              .CompareTo(Vector2IntUtilities.WalkDistance(second.LogicalPosition, actorData.LogicalPosition))
                              );
            ActorData closestEnemy = enemiesClose.FirstOrDefault();

            if (closestEnemy != null)
            {
                Vector2Int toEnemy = closestEnemy.LogicalPosition - actorData.LogicalPosition;

                // mam nadzieje, ze zadziala
                if (Vector2IntUtilities.WalkDistance(closestEnemy.LogicalPosition, actorData.LogicalPosition) == 2)
                {                 // move towards player if possible and desired
                    bool possible = false;

                    Vector2Int?legalMove        = null;
                    Vector2Int directionToEnemy = Vector2IntUtilities.Normalized(toEnemy);
                    IEnumerable <Vector2Int> candidateMovesToEnemy = Vector2IntUtilities.GetCone(directionToEnemy)
                                                                     .Select(coneVector => coneVector - directionToEnemy)
                                                                     .Where(fixedConeVector => fixedConeVector != actorData.LogicalPosition);

                    IList <Vector2Int> candidateMovesShuffled = _rng.Shuffle(candidateMovesToEnemy);
                    foreach (var cand in candidateMovesShuffled)
                    {
                        if (!_entityDetector.DetectActors(actorData.LogicalPosition + cand).Any() &&
                            _gridInfoProvider.IsWalkable(actorData.LogicalPosition + cand))
                        {
                            legalMove = cand;
                            break;
                        }
                    }
                    if (legalMove.HasValue)
                    {
                        int closeCombatAdvantage = actorData.WeaponWeld.WeaponDefinition.CloseCombatModifier -
                                                   closestEnemy.WeaponWeld.WeaponDefinition.CloseCombatModifier;
                        if (closeCombatAdvantage < 0)
                        {
                            closeCombatAdvantage = 0;
                        }
                        float chanceToMove = .1f + 0.2f * closeCombatAdvantage;
                        if (_rng.Check(chanceToMove))
                        {
                            return(_actionFactory.CreateMoveAction(actorData, legalMove.Value));
                        }
                    }
                }

                if (Vector2IntUtilities.IsOneStep(toEnemy) ||
                    (actorData.WeaponWeld.WeaponDefinition.AllowsFarCombat && Vector2IntUtilities.IsOneOrTwoSteps(toEnemy) &&
                     _clearWayBetweenTwoPointsDetector.ClearWayExists(actorData.LogicalPosition, closestEnemy.LogicalPosition)))
                {
                    IGameAction actionToPerform;

                    bool pushingIsPossible = actorData.AiTraits.Contains(AiTrait.Pusher) && Vector2IntUtilities.IsOneStep(toEnemy) &&
                                             _gridInfoProvider.IsWalkable(closestEnemy.LogicalPosition + toEnemy);
                    bool pushingIsDesired = false;
                    if (pushingIsPossible)
                    {
                        float pushingChanceScore = 0.08f;
                        if (actorData.WeaponWeld.WeaponDefinition.CloseCombatModifier < closestEnemy.WeaponWeld.WeaponDefinition.CloseCombatModifier)
                        {
                            pushingChanceScore += .25f;
                        }
                        if (!_gridInfoProvider.IsWalkable(closestEnemy.LogicalPosition + toEnemy + toEnemy))
                        {
                            pushingChanceScore += .2f;
                        }

                        if (_rng.Check(pushingChanceScore))
                        {
                            pushingIsDesired = true;
                        }
                    }

                    if (pushingIsPossible && pushingIsDesired)
                    {
                        actionToPerform = _actionFactory.CreatePushAction(actorData, closestEnemy);
                    }
                    else
                    {
                        bool isInGoodPosition = Vector2IntUtilities.IsOneStep(toEnemy) && actorData.WeaponWeld.WeaponDefinition.CloseCombatModifier
                                                > closestEnemy.WeaponWeld.WeaponDefinition.CloseCombatModifier;
                        if (Vector2IntUtilities.IsOneOrTwoSteps(toEnemy) && !isInGoodPosition)                        // && actorData.AiTraits.Contains(AiTrait.Careful)))
                        {
                            float chanceToStepBack = 0f;
                            float healthFactor     = (1 - actorData.HealthProgress) * .15f;
                            float swordsFactor     = (closestEnemy.Swords - actorData.Swords) * .15f;
                            chanceToStepBack = healthFactor + swordsFactor;
                            if (_rng.Check(chanceToStepBack))
                            {
                                Vector2Int directionFromEnemy = Vector2IntUtilities.Normalized(toEnemy) * -1;
                                IEnumerable <Vector2Int> positionsToStepBack = Vector2IntUtilities.GetCone(directionFromEnemy)
                                                                               .Select(coneVector => actorData.LogicalPosition + coneVector - directionFromEnemy)
                                                                               .Where(position => position != actorData.LogicalPosition);
                                foreach (var conePosition in positionsToStepBack)
                                {
                                    if (!_gridInfoProvider.IsWalkable(conePosition) ||
                                        _entityDetector.DetectEntities(conePosition).Any())
                                    {
                                        continue;
                                    }
                                    Vector2Int stepBackMoveVector = conePosition - actorData.LogicalPosition;
                                    return(_actionFactory.CreateMoveAction(actorData, stepBackMoveVector));
                                }
                            }
                        }

                        bool isDaringBlow = false;
                        if (actorData.Traits.Contains(Trait.DaringBlow) && actorData.Swords >= 2)
                        {
                            float daringBlowChance = actorData.AiTraits.Contains(AiTrait.Aggressive) ? .5f : .2f;
                            if (actorData.ActorType == ActorType.Basher)
                            {
                                daringBlowChance += .2f;
                            }
                            if (_rng.Check(daringBlowChance))
                            {
                                isDaringBlow = true;
                            }
                        }
                        actionToPerform = _actionFactory.CreateAttackAction(actorData, closestEnemy, isDaringBlow);
                    }
                    if (DateTime.UtcNow < closestEnemy.BlockedUntil)
                    {
                        actorData.StoredAction = actionToPerform;
                        actorData.BlockedUntil = closestEnemy.BlockedUntil;
                        return(null);
                    }
                    return(actionToPerform);
                }
                int        moveX      = toEnemy.x.CompareTo(0);
                int        moveY      = toEnemy.y.CompareTo(0);
                Vector2Int moveVector = new Vector2Int(moveX, moveY);

                Func <Vector2Int, bool> isWalkableAndFree = position =>
                                                            _gridInfoProvider.IsWalkable(position) &&
                                                            !_entityDetector.DetectActors(position).Any();

                if (!isWalkableAndFree(actorData.LogicalPosition + moveVector))
                {
                    Vector2Int?finalMoveVector = null;
                    Vector2Int alternativeMoveVector1;
                    Vector2Int alternativeMoveVector2;

                    // trying to find best alternative vectors to move
                    if (moveVector.x == 0)
                    {
                        alternativeMoveVector1 = new Vector2Int(+1, moveVector.y);
                        alternativeMoveVector2 = new Vector2Int(-1, moveVector.y);
                    }
                    else if (moveVector.y == 0)
                    {
                        alternativeMoveVector1 = new Vector2Int(moveVector.x, -1);
                        alternativeMoveVector2 = new Vector2Int(moveVector.x, +1);
                    }
                    else
                    {
                        alternativeMoveVector1 = new Vector2Int(moveVector.x, 0);
                        alternativeMoveVector2 = new Vector2Int(0, moveVector.y);
                    }

                    if (isWalkableAndFree(actorData.LogicalPosition + alternativeMoveVector1))
                    {
                        finalMoveVector = alternativeMoveVector1;
                    }
                    else if (isWalkableAndFree(actorData.LogicalPosition + alternativeMoveVector2))
                    {
                        finalMoveVector = alternativeMoveVector2;
                    }
                    if (finalMoveVector.HasValue)
                    {
                        return(_actionFactory.CreateMoveAction(actorData, finalMoveVector.Value));
                    }
                    return(_actionFactory.CreatePassAction(actorData));
                }
                return(_actionFactory.CreateMoveAction(actorData, moveVector));
            }
            else if (actorData.Team == Team.Beasts)
            {
                ActorData playerClose = _entityDetector.DetectActors(actorData.LogicalPosition, actorData.VisionRayLength).FirstOrDefault(
                    f => f != actorData && f.ActorType == ActorType.Player);
                if (playerClose != null)
                {
                    Vector2Int toFriend          = playerClose.LogicalPosition - actorData.LogicalPosition;
                    Vector2Int directionToFriend = Vector2IntUtilities.Normalized(toFriend);
                    Vector2Int legalMove         = new Vector2Int();

                    IEnumerable <Vector2Int> candidateMovesToFriend = Vector2IntUtilities.GetCone(directionToFriend)
                                                                      .Select(coneVector => coneVector - directionToFriend)
                                                                      .Where(fixedConeVector => fixedConeVector != actorData.LogicalPosition);

                    IList <Vector2Int> candidateMovesShuffled = _rng.Shuffle(candidateMovesToFriend);
                    foreach (var cand in candidateMovesShuffled)
                    {
                        if (!_entityDetector.DetectActors(actorData.LogicalPosition + cand).Any() &&
                            _gridInfoProvider.IsWalkable(actorData.LogicalPosition + cand))
                        {
                            legalMove = cand;
                            break;
                        }
                    }

                    Vector2Int moveVector = legalMove;
                    if (!_entityDetector.DetectActors(actorData.LogicalPosition + moveVector).Any())
                    {
                        return(_actionFactory.CreateMoveAction(actorData, moveVector));
                    }
                }
                return(_actionFactory.CreatePassAction(actorData));
            }
            if (Vector2IntUtilities.WalkDistance(actorData.LogicalPosition, _gameContext.PlayerActor.ActorData.LogicalPosition) < 15 &&
                _gameContext.PlayerActor.ActorData.Health > 0 && actorData.ActorType != ActorType.Basher)
            {
                Vector2Int?farReachablePoint = GetFarReachablePoint(actorData);
                if (farReachablePoint.HasValue)
                {
                    Vector2Int moveVector = Vector2IntUtilities.Normalized(farReachablePoint.Value - actorData.LogicalPosition);
                    return(_actionFactory.CreateMoveAction(actorData, moveVector));
                }
            }
            return(_actionFactory.CreatePassAction(actorData));
        }
Example #8
0
        private void PlaceTilesBasingOnDungeon(BoundsInt gridBounds, Dungeon generator)
        {
            bool stairsGenerated = false;

            foreach (Vector3Int position in gridBounds.allPositionsWithin)
            {
                Vector2Int position2D = position.ToVector2Int();
                GenTile    genTile    = generator.GetCellType(position2D.x, position2D.y);
                switch (genTile)
                {
                case GenTile.DirtFloor:
                {
                    _gameContext.DirtTilemap.SetTile(position, Dirt);
                    if (_rng.Check(0.03f))
                    {
                        _gameContext.EnvironmentTilemap.SetTile(position, _rng.Choice(FloorEnvironmetals));
                    }
                    if (_rng.Check(0.06f))
                    {
                        if (Vector2IntUtilities.Neighbours8(position2D).All(n => generator.GetCellType(n.x, n.y) == GenTile.DirtFloor))
                        {
                            _gameContext.ObjectsTilemap.SetTile(position, _rng.Choice(WallEnvironmetals));
                        }
                    }
                    break;
                }

                case GenTile.Corridor:
                {
                    _gameContext.DirtTilemap.SetTile(position, Dirt);
                    break;
                }

                case GenTile.StoneWall:
                case GenTile.DirtWall:
                {
                    _gameContext.WallsTilemap.SetTile(position, Wall);
                    if (_rng.Check(0.04f))
                    {
                        _gameContext.EnvironmentTilemap.SetTile(position, _rng.Choice(WallAttachmentEnvironmetals));
                    }
                    break;
                }

                case GenTile.Upstairs:
                {
                    _gameContext.DirtTilemap.SetTile(position, Dirt);
                    _gameContext.EnvironmentTilemap.SetTile(position, StairsUp);
                    _gameContext.WallsTilemap.SetTile(position, null);
                    stairsGenerated = true;
                    break;
                }

                case GenTile.Downstairs:
                {
                    _gameContext.DirtTilemap.SetTile(position, Dirt);
                    break;
                }

                case GenTile.Door:
                {
                    _gameContext.DirtTilemap.SetTile(position, Dirt);
                    GenTile tileToRight      = generator.GetCellType(position.x + 1, position.y);
                    bool    isHorizontalDoor = tileToRight == GenTile.Corridor || tileToRight == GenTile.DirtFloor;
                    bool    doorsAreOpen     = _rng.Check(0.3f);
                    if (doorsAreOpen)
                    {
                        _gameContext.EnvironmentTilemap.SetTile(position, isHorizontalDoor ? DoorsHorizontalOpen : DoorsVerticalOpen);
                    }
                    else
                    {
                        _gameContext.WallsTilemap.SetTile(position, isHorizontalDoor ? DoorsHorizontalClosed : DoorsVerticalClosed);
                    }
                    break;
                }

                default:
                {
                    break;
                }
                }
            }
            if (!stairsGenerated)
            {
                BoundsInt  randomRoom = _rng.Choice(generator.Rooms);
                Vector3Int center     = BoundsIntUtilities.Center(randomRoom).ToVector3Int();
                _gameContext.DirtTilemap.SetTile(center, Dirt);
                _gameContext.EnvironmentTilemap.SetTile(center, StairsUp);
                _gameContext.WallsTilemap.SetTile(center, null);
                Debug.Log("Missing stairs in dungeon! Generating in random room on position: " + center);
            }
        }