public bool Test(IActor actor, ISectorTaskSourceContext context, ILogicState currentState,
                         ILogicStrategyData strategyData)
        {
            if (actor is null)
            {
                throw new ArgumentNullException(nameof(actor));
            }

            if (currentState is null)
            {
                throw new ArgumentNullException(nameof(currentState));
            }

            if (strategyData is null)
            {
                throw new ArgumentNullException(nameof(strategyData));
            }

            if (!actor.Person.HasModule <IInventoryModule>() || !actor.Person.HasModule <IEquipmentModule>())
            {
                return(false);
            }

            var inventoryModule            = actor.Person.GetModule <IInventoryModule>();
            var inventoryProps             = inventoryModule.CalcActualItems();
            var currentInventoryEquipments = inventoryProps.OfType <Equipment>();

            if (!currentInventoryEquipments.Any())
            {
                strategyData.TargetEquipment          = null;
                strategyData.TargetEquipmentSlotIndex = null;
                return(false);
            }

            var equipmentModule = actor.Person.GetModule <IEquipmentModule>();

            for (var slotIndex = 0; slotIndex < equipmentModule.Slots.Length; slotIndex++)
            {
                var slotScheme = equipmentModule.Slots[slotIndex];
                var equiped    = equipmentModule[slotIndex];
                if (equiped is null)
                {
                    var availableEquipments = from equipment in currentInventoryEquipments
                                              where IsApplicableForSlot(equipment, slotScheme.Types)
                                              where EquipmentCarrierHelper.CanBeEquiped(equipmentModule, slotIndex,
                                                                                        equipment)
                                              select equipment;

                    var targetEquipmentFromInventory = availableEquipments.FirstOrDefault();
                    if (targetEquipmentFromInventory != null)
                    {
                        strategyData.TargetEquipment          = targetEquipmentFromInventory;
                        strategyData.TargetEquipmentSlotIndex = slotIndex;
                        return(true);
                    }
                }
            }

            return(false);
        }
        public IActorTask GetActorTask(ISectorTaskSourceContext context)
        {
            // Для текущего состояния проверяем каждый из переходов.
            // Если переход выстреливает, то генерируем задачу актёру.
            // Алгоритм делится на два этапа:
            // 1. Для текущей логики проверяются все триггеры по порядку. Если какой-то триггер выстреливает, то связанная
            // через переход логика фиксируется, как текущая. За одну итерацию может быть только один переход.
            // 2. Получаем задачу из текущей логики. Если текущая логика возвращает пустую задачу - значит
            // переводим её в соответствующее состояние и ждём перехода из неё с помощью триггеров (этап 1).
            // Второй пункт означает, что каждая логика обязана выдавать хотя бы пустую задачу, если она
            // не может выполниться. И выставлять себе статус выполненной. В дереве состояний нужно следить за тем, чтобы
            // все логики имели триггер на окончание с переходом на какую-либо задачу.

            // После окончания всех проверок триггеров выполняется обновление состояния триггеров. Некоторые триггеры
            // могут иметь счётчики или логику, которая выполняется при каждой итерации (считай, каждый ход).

            var transitionWasPerformed = SelectCurrentState(CurrentState, context, out var newState);

            if (transitionWasPerformed)
            {
                CurrentState = newState;
                ResetLogicStates(_stateTree);
            }

            var actorTask = CurrentState.GetTask(Actor, context, _strategyData);

            var currentTriggers = _stateTree.Transitions[CurrentState].Select(x => x.Trigger);

            UpdateCurrentTriggers(currentTriggers);

            return(actorTask);
        }
        public override IActorTask GetTask(IActor actor, ISectorTaskSourceContext context,
                                           ILogicStrategyData strategyData)
        {
            var map = context.Sector.Map;
            var staticObjectManager = context.Sector.StaticObjectManager;
            var staticObject        = FindContainer(actor, staticObjectManager, map);

            if (staticObject == null || !staticObject.GetModule <IPropContainer>().Content.CalcActualItems().Any())
            {
                Complete = true;
                return(null);
            }

            var distance = map.DistanceBetween(actor.Node, staticObject.Node);

            if (distance <= 1)
            {
                return(TakeAllFromContainerTask(actor, staticObject, context.Sector));
            }

            var storedMoveTask = _moveTask;
            var moveTask       = MoveToContainerTask(actor, staticObject.Node, storedMoveTask, context.Sector);

            _moveTask = moveTask;
            return(moveTask);
        }
Exemple #4
0
        public override IActorTask GetTask(IActor actor, ISectorTaskSourceContext context,
                                           ILogicStrategyData strategyData)
        {
            if (actor is null)
            {
                throw new ArgumentNullException(nameof(actor));
            }

            if (context is null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (strategyData is null)
            {
                throw new ArgumentNullException(nameof(strategyData));
            }

            var usePropTask = CreateTask(actor, context, strategyData);

            if (usePropTask != null)
            {
                Complete = true;
                return(usePropTask);
            }

            Complete = true;
            return(null);
        }
Exemple #5
0
        public bool Test(IActor actor, ISectorTaskSourceContext context, ILogicState currentState,
                         ILogicStrategyData strategyData)
        {
            if (actor is null)
            {
                throw new ArgumentNullException(nameof(actor));
            }

            if (context is null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (currentState is null)
            {
                throw new ArgumentNullException(nameof(currentState));
            }

            if (strategyData is null)
            {
                throw new ArgumentNullException(nameof(strategyData));
            }

            var staticObjectManager = context.Sector.StaticObjectManager;
            var map = context.Sector.Map;

            var containers      = staticObjectManager.Items.Where(x => x.HasModule <IPropContainer>());
            var foundContainers = LootHelper.FindAvailableContainers(containers,
                                                                     actor.Node,
                                                                     map);

            return(foundContainers.Any());
        }
        public override IActorTask GetTask(IActor actor, ISectorTaskSourceContext context,
                                           ILogicStrategyData strategyData)
        {
            var inventory                  = actor.Person.GetModule <IInventoryModule>();
            var currentInventoryProps      = inventory.CalcActualItems();
            var currentInventoryEquipments = currentInventoryProps.OfType <Equipment>().ToArray();

            var equipmentCarrier = actor.Person.GetModule <IEquipmentModule>();

            for (var slotIndex = 0; slotIndex < equipmentCarrier.Slots.Length; slotIndex++)
            {
                var slot    = actor.Person.GetModule <IEquipmentModule>().Slots[slotIndex];
                var equiped = actor.Person.GetModule <IEquipmentModule>()[slotIndex];
                if (equiped == null)
                {
                    var availableEquipments = currentInventoryEquipments
                                              .Where(equipment => (equipment.Scheme.Equip.SlotTypes[0] & slot.Types) > 0)
                                              .Where(equipment => EquipmentCarrierHelper.CanBeEquiped(equipmentCarrier, slotIndex, equipment))
                                              .ToArray();

                    if (availableEquipments.Any())
                    {
                        var targetEquipmentFromInventory = availableEquipments.First();
                        var targetSlotIndex = slotIndex;

                        var taskContext = new ActorTaskContext(context.Sector);
                        return(new EquipTask(actor, taskContext, targetEquipmentFromInventory, targetSlotIndex));
                    }
                }
            }

            Complete = true;
            return(null);
        }
        public override IActorTask GetTask(IActor actor, ISectorTaskSourceContext context,
                                           ILogicStrategyData strategyData)
        {
            var triggerTarget = strategyData.TriggerIntuder;

            if (triggerTarget == null)
            {
                throw new InvalidOperationException(
                          $"Assign {nameof(strategyData.TriggerIntuder)} with not null valie in related trigger.");
            }

            var targetCanBeDamaged = triggerTarget.CanBeDamaged();

            if (!targetCanBeDamaged)
            {
                Complete = true;
                return(null);
            }

            var attackParams = CheckAttackAvailability(actor, triggerTarget, context.Sector.Map);

            if (attackParams.IsAvailable)
            {
                var act = attackParams.CombatAct;

                var taskContext = new ActorTaskContext(context.Sector);

                var attackTask = new AttackTask(actor, taskContext, triggerTarget, act, _actService);
                return(attackTask);
            }

            // Маршрут до цели обновляем каждые 3 хода.
            // Для оптимизации.
            // Эффект потери цели.
            if (_refreshCounter > 0 && _moveTask?.CanExecute() == true)
            {
                _refreshCounter--;
                return(_moveTask);
            }

            var map = context.Sector.Map;

            _refreshCounter = REFRESH_COUNTER_VALUE;
            var targetIsOnLine = map.TargetIsOnLine(actor.Node, triggerTarget.Node);

            if (targetIsOnLine)
            {
                var taskContext = new ActorTaskContext(context.Sector);
                var moveModule  = actor.Person.GetModule <IMovingModule>();
                var moveCost    = moveModule.CalculateCost();

                _moveTask = new MoveTask(actor, taskContext, triggerTarget.Node, map, moveCost);
                return(_moveTask);
            }

            // Цел за пределами видимости. Считается потерянной.
            return(null);
        }
Exemple #8
0
        public bool Test(IActor actor, ISectorTaskSourceContext context, ILogicState currentState,
                         ILogicStrategyData strategyData)
        {
            if (currentState is null)
            {
                throw new System.ArgumentNullException(nameof(currentState));
            }

            return(currentState.Complete);
        }
Exemple #9
0
        protected override bool TestInner(IActor actor, ISectorTaskSourceContext context, ILogicState currentState,
                                          ILogicStrategyData strategyData)
        {
            var taskContext = new ActorTaskContext(context.Sector);

            return(SurvivalHazardTriggerHelper.TestHazardAndResource(
                       actor,
                       taskContext,
                       strategyData,
                       SurvivalStatType.Satiety,
                       ConsumeCommonRuleType.Satiety));
        }
Exemple #10
0
        public bool Test(IActor actor, ISectorTaskSourceContext context, ILogicState currentState,
                         ILogicStrategyData strategyData)
        {
            foreach (var trigger in _triggers)
            {
                if (!trigger.Test(actor, context, currentState, strategyData))
                {
                    return(false);
                }
            }

            return(true);
        }
        /// <summary>
        /// Checks situation when all nodes of a map are explored (known) by the person.
        /// </summary>
        /// <returns>True if all nodes are explored. False otherside.</returns>
        public bool Test(IActor actor, ISectorTaskSourceContext context, ILogicState currentState,
                         ILogicStrategyData strategyData)
        {
            if (actor is null)
            {
                throw new ArgumentNullException(nameof(actor));
            }

            if (context is null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (currentState is null)
            {
                throw new ArgumentNullException(nameof(currentState));
            }

            if (strategyData is null)
            {
                throw new ArgumentNullException(nameof(strategyData));
            }

            var fowModule = actor.Person.GetModuleSafe <IFowData>();

            if (fowModule is null)
            {
                var notObservedNodes = context.Sector.Map.Nodes.Where(x => !strategyData.ObservedNodes.Contains(x));

                var allNodesObserved = !notObservedNodes.Any();
                return(allNodesObserved);
            }
            else
            {
                var fowData        = fowModule.GetSectorFowData(context.Sector);
                var observingNodes = fowData.GetFowNodeByState(SectorMapNodeFowState.Observing).Select(x => x.Node)
                                     .ToArray();
                var exploredNodes = fowData.GetFowNodeByState(SectorMapNodeFowState.Explored).Select(x => x.Node)
                                    .ToArray();

                var knownNodes = observingNodes.Union(exploredNodes);

                var notObservedNodes = context.Sector.Map.Nodes.Where(x => !knownNodes.Contains(x));

                var allNodesObserved = !notObservedNodes.Any();
                return(allNodesObserved);
            }
        }
        public bool Test(IActor actor, ISectorTaskSourceContext context, ILogicState currentState,
                         ILogicStrategyData strategyData)
        {
            if (actor is null)
            {
                throw new ArgumentNullException(nameof(actor));
            }

            if (currentState is null)
            {
                throw new ArgumentNullException(nameof(currentState));
            }

            if (strategyData is null)
            {
                throw new ArgumentNullException(nameof(strategyData));
            }

            //TODO Здесь лучше проверять на наличие эффекта раны
            var hpStat = actor.Person.GetModule <ISurvivalModule>().Stats
                         .SingleOrDefault(x => x.Type == SurvivalStatType.Health);
            var isLowHp = hpStat.ValueShare <= 0.5f;

            if (!isLowHp)
            {
                return(false);
            }

            //

            var props     = actor.Person.GetModule <IInventoryModule>().CalcActualItems();
            var resources = props.OfType <Resource>();

            var taskContext = new ActorTaskContext(context.Sector);

            var bestResource = ResourceFinder.FindBestConsumableResourceByRule(
                actor,
                taskContext,
                resources,
                ConsumeCommonRuleType.Health);

            if (bestResource == null)
            {
                return(false);
            }

            return(true);
        }
Exemple #13
0
        private static UsePropTask CreateTask(IActor actor, ISectorTaskSourceContext context,
                                              ILogicStrategyData strategyData)
        {
            if (strategyData.ResourceToReduceHazard is null)
            {
                throw new InvalidOperationException(
                          $"Assign {nameof(strategyData.ResourceToReduceHazard)} value in the triggers first.");
            }

            var taskContxt = new ActorTaskContext(context.Sector);
            var prop       = strategyData.ResourceToReduceHazard;

            // When prop was used it no need to store anymore.
            strategyData.ResourceToReduceHazard = null;
            return(new UsePropTask(actor, taskContxt, prop));
        }
Exemple #14
0
        public override IActorTask GetTask(IActor actor, ISectorTaskSourceContext context,
                                           ILogicStrategyData strategyData)
        {
            if (_idleTask == null)
            {
                var taskContext = new ActorTaskContext(context.Sector);
                _idleTask = new IdleTask(actor, taskContext, _decisionSource);
            }

            if (_idleTask.IsComplete)
            {
                Complete = true;
                return(null);
            }

            return(_idleTask);
        }
Exemple #15
0
        public override IActorTask GetTask(IActor actor, ISectorTaskSourceContext context,
                                           ILogicStrategyData strategyData)
        {
            if (actor is null)
            {
                throw new System.ArgumentNullException(nameof(actor));
            }

            if (context is null)
            {
                throw new System.ArgumentNullException(nameof(context));
            }

            var hpStat = actor.Person.GetModule <ISurvivalModule>().Stats
                         .SingleOrDefault(x => x.Type == SurvivalStatType.Health);

            if (hpStat == null)
            {
                Complete = true;
                return(null);
            }

            var hpStatCoeff = (float)hpStat.Value / (hpStat.Range.Max - hpStat.Range.Min);
            var isLowHp     = hpStatCoeff <= 0.5f;

            if (!isLowHp)
            {
                Complete = true;
                return(null);
            }

            var props        = actor.Person.GetModule <IInventoryModule>().CalcActualItems();
            var resources    = props.OfType <Resource>();
            var bestResource = ResourceFinder.FindBestConsumableResourceByRule(resources,
                                                                               ConsumeCommonRuleType.Health);

            if (bestResource == null)
            {
                Complete = true;
                return(null);
            }

            var taskContext = new ActorTaskContext(context.Sector);

            return(new UsePropTask(actor, taskContext, bestResource));
        }
Exemple #16
0
        public override IActorTask GetTask(IActor actor, ISectorTaskSourceContext context,
                                           ILogicStrategyData strategyData)
        {
            if (strategyData.TargetEquipment is null || strategyData.TargetEquipmentSlotIndex is null)
            {
                throw new InvalidOperationException("Assign TargetEquipment and TargetEquipmentSlot in trigger first.");
            }

            var targetEquipmentFromInventory = strategyData.TargetEquipment;
            var targetSlotIndex = strategyData.TargetEquipmentSlotIndex;

            var taskContext = new ActorTaskContext(context.Sector);

            var task = new EquipTask(actor, taskContext, targetEquipmentFromInventory, targetSlotIndex.Value);

            Complete = true;
            return(task);
        }
Exemple #17
0
        public override IActorTask GetTask(IActor actor, ISectorTaskSourceContext context,
                                           ILogicStrategyData strategyData)
        {
            if (MoveTask == null)
            {
                MoveTask = CreateBypassMoveTask(actor, strategyData, context.Sector);

                if (MoveTask != null)
                {
                    return(MoveTask);
                }

                // Это может произойти, если актёр не выбрал следующий узел.
                // Тогда переводим актёра в режим ожидания.

                var taskContext = new ActorTaskContext(context.Sector);
                IdleTask = new IdleTask(actor, taskContext, DecisionSource);
                return(IdleTask);
            }

            if (!MoveTask.IsComplete)
            {
                // Если команда на перемещение к целевой точке патруля не закончена,
                // тогда продолжаем её.
                // Предварительно проверяем, не мешает ли что-либо её продолжить выполнять.
                if (!MoveTask.CanExecute())
                {
                    MoveTask = CreateBypassMoveTask(actor, strategyData, context.Sector);
                }

                if (MoveTask != null)
                {
                    return(MoveTask);
                }

                var taskContext = new ActorTaskContext(context.Sector);
                IdleTask = new IdleTask(actor, taskContext, DecisionSource);
                return(IdleTask);
            }

            Complete = true;
            return(null);
        }
Exemple #18
0
        public override IActorTask GetTask(IActor actor, ISectorTaskSourceContext context,
                                           ILogicStrategyData strategyData)
        {
            var sector = context.Sector;
            var map    = sector.Map;

            if (!strategyData.ExitNodes.Any())
            {
                Complete = true;
                return(null);
            }

            var actorNode = actor.Node;

            if (map.Transitions.TryGetValue(actorNode, out var currentTransition))
            {
                var taskContext    = new ActorTaskContext(sector);
                var transitionTask = new SectorTransitTask(actor, taskContext);
                Complete = true;
                return(transitionTask);
            }

            if (_moveTask == null || _moveTask.IsComplete || !_moveTask.CanExecute())
            {
                var nearbyExitNode = strategyData.ExitNodes
                                     .OrderBy(x => map.DistanceBetween(actor.Node, x))
                                     .First();

                _moveTask = CreateMoveTask(actor, nearbyExitNode, sector, map);

                if (_moveTask == null)
                {
                    Complete = true;
                    return(null);
                }

                return(_moveTask);
            }

            return(_moveTask);
        }
Exemple #19
0
        public bool Test(IActor actor, ISectorTaskSourceContext context, ILogicState currentState,
                         ILogicStrategyData strategyData)
        {
            if (actor is null)
            {
                throw new System.ArgumentNullException(nameof(actor));
            }

            if (currentState is null)
            {
                throw new System.ArgumentNullException(nameof(currentState));
            }

            if (strategyData is null)
            {
                throw new System.ArgumentNullException(nameof(strategyData));
            }

            var currentInventoryEquipments =
                actor.Person.GetModule <IInventoryModule>().CalcActualItems().OfType <Equipment>();

            for (int i = 0; i < actor.Person.GetModule <IEquipmentModule>().Slots.Length; i++)
            {
                var slot    = actor.Person.GetModule <IEquipmentModule>().Slots[i];
                var equiped = actor.Person.GetModule <IEquipmentModule>()[i];
                if (equiped == null)
                {
                    var availableEquipments = currentInventoryEquipments
                                              .Where(x => (x.Scheme.Equip.SlotTypes[0] & slot.Types) > 0);

                    if (availableEquipments.Any())
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
        public bool Test(IActor actor, ISectorTaskSourceContext context, ILogicState currentState,
                         ILogicStrategyData strategyData)
        {
            if (actor is null)
            {
                throw new ArgumentNullException(nameof(actor));
            }

            if (context is null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (currentState is null)
            {
                throw new ArgumentNullException(nameof(currentState));
            }

            if (strategyData is null)
            {
                throw new ArgumentNullException(nameof(strategyData));
            }

            var map          = context.Sector.Map;
            var actorManager = context.Sector.ActorManager;

            var nearbyIntruder = IntruderDetectionHelper.GetIntruder(actor, map, actorManager);

            // Remember last intruder for logic with will handle reaction.
            strategyData.TriggerIntuder = nearbyIntruder;

            if (nearbyIntruder is null)
            {
                return(false);
            }

            return(true);
        }
        private bool SelectCurrentState(ILogicState currentState, ISectorTaskSourceContext context,
                                        out ILogicState newState)
        {
            var transitionWasPerformed = false;

            newState = null;

            var currentStateTransitions = _stateTree.Transitions[CurrentState];

            foreach (var transition in currentStateTransitions)
            {
                var trigger = transition.Trigger;

                var isFired = trigger.Test(Actor, context, currentState, _strategyData);
                if (isFired)
                {
                    newState = transition.NextState;
                    transitionWasPerformed = true;
                    break;
                }
            }

            return(transitionWasPerformed);
        }
Exemple #22
0
 protected abstract bool TestInner(
     [NotNull] IActor actor,
     [NotNull] ISectorTaskSourceContext context,
     [NotNull] ILogicState currentState,
     [NotNull] ILogicStrategyData strategyData);
Exemple #23
0
 public abstract IActorTask GetTask(IActor actor, ISectorTaskSourceContext context,
                                    ILogicStrategyData strategyData);
 protected override bool TestInner(IActor actor, ISectorTaskSourceContext context, ILogicState currentState,
                                   ILogicStrategyData strategyData)
 {
     return(SurvivalHazardTriggerHelper.TestHazardAndResource(actor, strategyData, SurvivalStatType.Hydration,
                                                              ConsumeCommonRuleType.Thirst));
 }