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); }
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); }
private GameEntity GetEntityAtCursor(Position mousePosition) { List <GameEntity> eligibleEntities = _entityDetector.DetectEntities(mousePosition) .Where(e => _contextManager.Current.VisibleEntities.Contains(e.view.Controller)).ToList(); return(eligibleEntities.FirstOrDefault()); }
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()); }
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); }
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); } }
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)); }
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; }
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); }
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 }); } }
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); } } }
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)); }