protected override void Execute(List <GameEntity> entities)
        {
            GameEntity playerEntity = entities.SingleEntity();

            _uiFacade.ChangeAbilityAccesibility(_gameConfig.Abilities.SpawnActors, true);

            List <GameEntity> entitiesAround = _entityDetector.DetectEntities(playerEntity.position.Position, 1).ToList();

            bool pickUpOrPutInIsPossible = false;
            bool dropIsPossible          = false;

            if (playerEntity.hasEntityHolder)
            {
                bool isHoldingSomething = playerEntity.entityHolder.EntityHeld != Guid.Empty;
                dropIsPossible          = isHoldingSomething;
                pickUpOrPutInIsPossible = isHoldingSomething && playerEntity.hasInventory &&
                                          playerEntity.inventory.EntitiesInInventory.Any(e => e == Guid.Empty);
            }

            List <GameEntity> entitiesAtPosition = _entityDetector.DetectEntities(playerEntity.position.Position)
                                                   .Where(e => e != playerEntity && !e.hasHeld).ToList();

            GameEntity anyEntityAtFeet = entitiesAtPosition.FirstOrDefault();

            _uiFacade.ShowEntityDetails(anyEntityAtFeet, atFeet: true);

            if (playerEntity.entityHolder.EntityHeld == Guid.Empty)
            {
                GameEntity carryableEntityAtFeet = entitiesAtPosition.FirstOrDefault(e => e.isCarryable);
                pickUpOrPutInIsPossible |= carryableEntityAtFeet != null;
            }

            _uiFacade.ChangeAbilityAccesibility(_gameConfig.Abilities.Drop, dropIsPossible);
            _uiFacade.ChangeAbilityAccesibility(_gameConfig.Abilities.PickUp, pickUpOrPutInIsPossible);
        }
Example #2
0
        private IGameAction ResolveForAlphaNumber(int number, GameEntity entity)
        {
            if (number == 4 && (!entity.hasEntityHolder || entity.entityHolder.EntityHeld == Guid.Empty))
            {
                GameEntity neighbourToKidnap = _entityDetector.DetectEntities(entity.position.Position, 1).
                                               FirstOrDefault(a => a != entity);
                if (neighbourToKidnap != null)
                {
                    return(_actionFactory.CreateKindapAction(neighbourToKidnap, entity));
                }
            }

            return(null);
        }
Example #3
0
        private GameEntity GetEntityAtCursor(Position mousePosition)
        {
            List <GameEntity> eligibleEntities = _entityDetector.DetectEntities(mousePosition)
                                                 .Where(e => _contextManager.Current.VisibleEntities.Contains(e.view.Controller)).ToList();

            return(eligibleEntities.FirstOrDefault());
        }
Example #4
0
        private GameEntity GetEntityAtCursor(Position mousePosition)
        {
            List <GameEntity> eligibleEntities = _entityDetector.DetectEntities(mousePosition)
                                                 .Where(e => _contextManager.Current.VisibleEntities.Contains(((EntityViewBehaviour)e.view.Controller).PositionedEntity))
                                                 .OrderByDescending(e => e.hasEnergy ? 1 : 0)
                                                 .ToList();

            return(eligibleEntities.FirstOrDefault());
        }
Example #5
0
        public void OnSendStimulus(GameEntity activeEntity, int range, StimulusDefinition stimulusDefinition)
        {
            IEnumerable <GameEntity> otherActorsAround = _entityDetector.DetectEntities(activeEntity.position.Position, range)
                                                         .Where(a => a != activeEntity);

            foreach (GameEntity receiver in otherActorsAround)
            {
//				_stimulusSender.OnSendStimulus(receiver, stimulusDefinition, activeEntity);
            }
        }
        public void UpdateTileVisibility(Vector2Int actorPosition, int cellsRangeInVision)
        {
            List <IGameEntity> entitiesHit = _entityDetector.DetectEntities(actorPosition, cellsRangeInVision).ToList();

            Vector2Int           fovCenter    = actorPosition;
            HashSet <Vector2Int> visibleTiles = _fovCalculator.CalculateFov(fovCenter, cellsRangeInVision, _gridInfoProvider.IsPassingLight);

            _tilePresenter.Illuminate(visibleTiles);
            _entityPresenter.Illuminate(visibleTiles, entitiesHit);
        }
Example #7
0
        private void ShowActivitiesOfVisibleActors(Position playerPosition, GameEntity entity)
        {
            var visibleActors =
                _entityDetector.DetectEntities(playerPosition, 25).Where(a => a != entity /*&& a.Entity.IsVisible toecs*/).ToList();

            foreach (GameEntity visibleActor in visibleActors)
            {
                //toecs PositionEffect effect = _positionEffectPresenter.ShowStablePositionEffect(visibleActor.position.Position,
                //	visibleActor.Activity?.GetFullName() ?? "-", Color.yellow);
                //_positionEffectsShown.Add(effect);
            }
        }
Example #8
0
        private Position GetHerdCenterOf(IEntityDetector detector, GameEntity entity, IFriendshipResolver friendshipResolver)
        {
            List <GameEntity> meAndFriendsAround = detector.DetectEntities(entity.position.Position, entity.vision.PerceptionRange)
                                                   .Where(e => friendshipResolver.AreFriends(entity, e))
                                                   .Union(new[] { entity })
                                                   .ToList();
            int averageX = meAndFriendsAround.Sum(f => f.position.Position.x) / meAndFriendsAround.Count;
            int averageY = meAndFriendsAround.Sum(f => f.position.Position.y) / meAndFriendsAround.Count;

            //Debug.Log($"me and friends: {meAndFriendsAround.Count}");

            return(new Position(averageX, averageY));
        }
Example #9
0
        public virtual void Process()
        {
            Position position = _entity.position.Position;
            bool     visibleActorsAreClose = _entity.isPlayerControlled &&
                                             _entityDetector.DetectEntities(position, 4)
                                             .Any(e => e != _entity && e.hasEnergy && e.hasView && e.view.Controller.IsVisible);

            if (visibleActorsAreClose)
            {
                DateTime potentialBlockedUntil = DateTime.UtcNow + TimeSpan.FromMilliseconds(150);
                if (_entity.hasBlockedUntil)
                {
                    if (potentialBlockedUntil > _entity.blockedUntil.BlockedUntil)
                    {
                        _entity.ReplaceBlockedUntil(potentialBlockedUntil);
                    }
                }
                else
                {
                    _entity.AddBlockedUntil(potentialBlockedUntil);
                }
            }

            IViewController view           = _entity.view.Controller;
            IEntityAnimator entityAnimator = view.Animator;

            if (view.IsVisible)
            {
                bool playerActorIsNear = _entityDetector.DetectEntities(position, 5).Any(a => a.isPlayerControlled);
                if (playerActorIsNear)
                {
                    entityAnimator.MoveTo(PreviousPosition, position);
                }
            }
            Vector3 animationTargetPosition = _unityGridInfoProvider.GetCellCenterWorld(position);

            view.Transform.position = animationTargetPosition;
        }
Example #10
0
        public Position?FindForItem(Position source)
        {
            List <GameEntity> allAtSource = _entityDetector.DetectEntities(source).ToList();
            bool sourceIsEligible         = _grid.IsWalkable(source) && allAtSource.All(e => e.hasHeld || e.isBlockingPosition);

            if (sourceIsEligible)
            {
                return(source);
            }
            ;
            IList <Position> neighboursShuffled = _rng.Shuffle(PositionUtilities.Neighbours8(source));

            foreach (Position neighbour in neighboursShuffled)
            {
                bool neighbourIsEligible = _grid.IsWalkable(neighbour) && !_entityDetector.DetectEntities(neighbour).Any();
                if (neighbourIsEligible)
                {
                    return(neighbour);
                }
            }

            return(null);
        }
Example #11
0
        private void PostTurnEntity(GameEntity entity)
        {
            entity.isPreTurnExecuted = false;

            if (entity.hasStimuli)
            {
                entity.RemoveStimuli();
            }
            if (!entity.hasVision)
            {
                return;
            }
            List <GameEntity> entitiesInVicinity = _entityDetector.DetectEntities(entity.position.Position, entity.vision.VisionRange)
                                                   .Where(e => e != entity)
                                                   .ToList();

            if (entity.isPlayerControlled)
            {
                return;
            }

            HashSet <GameEntity> entitiesToUnnotice = new HashSet <GameEntity>();

            foreach (GameEntity entityInVicinity in entitiesInVicinity)
            {
                ProcessEntityInVicinity(entity, entityInVicinity, entitiesToUnnotice);
            }
            foreach (GameEntity entityToUnnotice in entitiesToUnnotice)
            {
                entity.vision.EntitiesNoticed.Remove(entityToUnnotice.id.Id);
                _stimulusHandler.Unnotice(entity, new Stimulus
                {
                    Type           = StimulusType.IUnnotice,
                    ObjectEntityId = entityToUnnotice.id.Id
                });
            }
        }
Example #12
0
        private void PostHeartbeatEntity(GameEntity entity)
        {
            if (!entity.hasVision)
            {
                return;
            }
            List <GameEntity> entitiesInVicinity = _entityDetector.DetectEntities(entity.position.Position, entity.vision.VisionRange).ToList();

            if (!entity.isPlayerControlled)
            {
                HashSet <GameEntity> seenActorsToVerifyIfStillInRange = entity.vision.EntitiesRecentlySeen.ToHashSet();

                /* służy do rozstrzygnięcia, czy wysyłać NoticeEnemy
                 *
                 * foreach (GameEntity entityInVicinity in entitiesInVicinity)
                 * {
                 *      ProcessEntityInVicinity(entity, entityInVicinity, entity.hasAware, seenActorsToVerifyIfStillInRange);
                 * }*/
                foreach (GameEntity actorThatGotOutOfRange in seenActorsToVerifyIfStillInRange)
                {
                    _stimulusReceiver.Unnotice(entity, actorThatGotOutOfRange);
                }
            }
        }
Example #13
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));
        }