Example #1
0
        private static IEnumerable <ICombatEventData> ApplyActionEffect(IAction selectedAction, IActorChangeCalculator actorChangeCalculator)
        {
            // Pre-apply copies
            IInitiativeActor sourceBeforeEffect = selectedAction.Source.Copy();
            IReadOnlyList <IInitiativeActor> targetsBeforeEffect = selectedAction.Targets.Select(t => t.Copy()).ToArray();

            // Apply
            selectedAction.Effect.Apply(selectedAction.Source, selectedAction.Targets);

            // Post-apply comparison
            foreach (ICombatEventData eventData in actorChangeCalculator.GetChangeEvents(sourceBeforeEffect, selectedAction.Source))
            {
                yield return(eventData);
            }

            foreach (var beforeAfterPair in targetsBeforeEffect.ToDictionary(
                         x => x,
                         x => selectedAction.Targets.First(y => y.Id == x.Id)))
            {
                foreach (ICombatEventData combatEventData in actorChangeCalculator.GetChangeEvents(beforeAfterPair.Key, beforeAfterPair.Value))
                {
                    yield return(combatEventData);
                }
            }
        }
Example #2
0
        private IAction SendActionsAndWaitForResponse(
            IInitiativeActor activeEntity,
            ICharacterController activeController,
            IReadOnlyDictionary <uint, IAction> availableActions)
        {
            IAction selectedAction;

            do
            {
                // Send Actions to Controller
                _pendingSelectedActionId = null;
                activeController.SelectAction(activeEntity, availableActions, OnActionSelected);

                // Wait for Controller response
                do
                {
                    Thread.Sleep(ACTION_REQUEST_SLEEP_TIME);
                } while (!_pendingSelectedActionId.HasValue);

                // Validate response
                availableActions.TryGetValue(_pendingSelectedActionId.Value, out selectedAction);

                _pendingSelectedActionId = null;
            } while (selectedAction == null || !selectedAction.Available);

            return(selectedAction);
        }
Example #3
0
        public void SelectAction(IInitiativeActor activeEntity, IReadOnlyDictionary <uint, IAction> availableActions, Action <uint> selectAction)
        {
            ActiveCharacter       = activeEntity as IPlayerCharacterActor;
            AvailableActions      = availableActions;
            _selectActionCallback = selectAction;

            ActiveCharacterChanged?.Invoke();
        }
Example #4
0
 public IEnumerable <IAction> TakeTurn(
     IInitiativeActor activeActor,
     ICharacterController actorController,
     IReadOnlyCollection <ITargetableActor> allTargets,
     IStandardActionGenerator standardActionGenerator)
 {
     yield break;
 }
Example #5
0
        /// <summary>
        /// Prompt the controller to select an Action from the provided collection randomly.
        /// </summary>
        /// <param name="activeEntity">Currently active Actor in the combat sequence.</param>
        /// <param name="availableActions">All available Actions for the Actor.</param>
        /// <param name="selectAction">Action to invoke once the Action has been selected, providing the Action's Id.</param>
        public void SelectAction(IInitiativeActor activeEntity, IReadOnlyDictionary <uint, IAction> availableActions, Action <uint> selectAction)
        {
            uint[] actionIds = availableActions
                               .Where(x => x.Value.Available)
                               .Select(x => x.Key)
                               .ToArray();
            uint actionId = actionIds[RANDOM.Next(actionIds.Length)];

            selectAction(actionId);
        }
Example #6
0
        private static IEnumerable <ICombatEventData> ApplyActionCost(IAction selectedAction, IActorChangeCalculator actorChangeCalculator)
        {
            // Pre-apply copy
            IInitiativeActor sourceBeforeCost = selectedAction.Source.Copy();

            // Apply
            selectedAction.Cost.Pay(selectedAction.Source, selectedAction.ActionSource);

            // Post-apply comparison
            return(actorChangeCalculator.GetChangeEvents(sourceBeforeCost, selectedAction.Source));
        }
Example #7
0
        /// <summary>
        /// Calculate all possible targeting permutations.
        /// </summary>
        /// <param name="sourceActor">Actor doing the targeting.</param>
        /// <param name="possibleTargets">All possible targetable Actors.</param>
        /// <returns>Collection containing all possible targeting group combinations.</returns>
        public IReadOnlyCollection <IReadOnlyCollection <ITargetableActor> > GetTargetOptions(
            IInitiativeActor sourceActor,
            IReadOnlyCollection <ITargetableActor> possibleTargets)
        {
            List <IReadOnlyCollection <ITargetableActor> > targetOptions = new List <IReadOnlyCollection <ITargetableActor> >(possibleTargets.Count);

            if (sourceActor is ITargetableActor targetableSource)
            {
                targetOptions.Add(new[] { targetableSource });
            }

            return(targetOptions);
        }
Example #8
0
        /// <summary>
        /// Calculate all possible targeting permutations.
        /// </summary>
        /// <param name="sourceActor">Actor doing the targeting.</param>
        /// <param name="possibleTargets">All possible targetable Actors.</param>
        /// <returns>Collection containing all possible targeting group combinations.</returns>
        public IReadOnlyCollection <IReadOnlyCollection <ITargetableActor> > GetTargetOptions(
            IInitiativeActor sourceActor,
            IReadOnlyCollection <ITargetableActor> possibleTargets)
        {
            List <ITargetableActor> allTargets = new List <ITargetableActor>(possibleTargets.Count);

            foreach (ITargetableActor possibleTarget in possibleTargets)
            {
                if (CanTarget(sourceActor, possibleTarget))
                {
                    allTargets.Add(possibleTarget);
                }
            }

            return(new[] { allTargets });
        }
Example #9
0
        private uint LoopUntilCombatComplete()
        {
            uint winningParty;

            while (!_winningPartyCalculator.GetWinningPartyId(_parties, out winningParty))
            {
                // Get Active Entity
                IInitiativeActor activeEntity = _initiativeQueue.GetNext();
                _eventQueue.EnqueueEvent(new ActiveActorChangedEvent(activeEntity.Id));

                // Prompt Action
                if (!activeEntity.IsAlive())
                {
                    // Move dead/inactive actor to end of queue
                    _initiativeQueue.Update(activeEntity.Id, _initiativeQueue.InitiativeThreshold);
                }
                else
                {
                    IEnumerable <IAction> actorSelectedActions = _turnController.TakeTurn(
                        activeEntity,
                        _controllerByPartyId[activeEntity.Party],
                        _allTargets,
                        _standardActionGenerator);
                    foreach (IAction selectedAction in actorSelectedActions)
                    {
                        // Update active entity's initiative value
                        _initiativeQueue.Update(activeEntity.Id, selectedAction.Speed);

                        // Inform event queue we're applying an action
                        _eventQueue.EnqueueEvent(new ActorActionTakenEvent(activeEntity.Id, selectedAction));

                        // Pay cost(s) for Action
                        _eventQueue.EnqueueEvents(ApplyActionCost(selectedAction, _actorChangeCalculator));

                        // Apply effect(s) for Action
                        _eventQueue.EnqueueEvents(ApplyActionEffect(selectedAction, _actorChangeCalculator));
                    }
                }

                // Rest for a bit
                Thread.Sleep(ACTOR_CHANGE_SLEEP_TIME);
            }

            return(winningParty);
        }
Example #10
0
        public IEnumerable <IAction> TakeTurn(
            IInitiativeActor activeActor,
            ICharacterController actorController,
            IReadOnlyCollection <ITargetableActor> allTargets,
            IStandardActionGenerator standardActionGenerator)
        {
            // Get active actor's action options
            Dictionary <uint, IAction> actionsForEntity = activeActor
                                                          .GetAllActions(allTargets)
                                                          .Concat(standardActionGenerator.GetActions(activeActor))
                                                          .ToDictionary(x => x.Id);

            // Send options and wait for valid response
            yield return(SendActionsAndWaitForResponse(
                             activeActor,
                             actorController,
                             actionsForEntity));
        }
Example #11
0
        public void max_init_never_exceeds_threshold_by_much()
        {
            IInitiativeQueue queue = new InitiativeQueue(
                100,
                new[]
            {
                new TestInitActor()
                {
                    Init = 10
                },
                new TestInitActor()
                {
                    Init = 10
                },
                new TestInitActor()
                {
                    Init = 10
                },
                new TestInitActor()
                {
                    Init = 10
                },
                new TestInitActor()
                {
                    Init = 10
                }
            });

            float initLimit = 115;

            for (int i = 0; i < 1000; i++)
            {
                foreach ((uint _, float initiative) in queue.GetCurrentQueue())
                {
                    Assert.Less(initiative, initLimit);
                }

                IInitiativeActor nextActor = queue.GetNext();
                queue.Update(nextActor.Id, 100);
            }
        }
Example #12
0
 /// <summary>
 /// Does the provided Actor meet this Requirement.
 /// </summary>
 /// <param name="actor">Actor which will take the Action.</param>
 /// <returns><c>True</c> if the Requirement is met, otherwise <c>False</c>.</returns>
 public bool MeetsRequirement(IInitiativeActor actor)
 {
     return(true);
 }
Example #13
0
 /// <summary>
 /// Apply this Effect to the target Actors provided.
 /// </summary>
 /// <param name="sourceEntity">Actor which originates this Effect.</param>
 /// <param name="targetActors">Actors which receive this Effect.</param>
 public void Apply(IInitiativeActor sourceEntity, IReadOnlyCollection <ITargetableActor> targetActors)
 {
     // Intentionally left blank
 }
Example #14
0
 /// <summary>
 /// Can the provided Actor currently afford the Cost.
 /// </summary>
 /// <param name="entity">Actor to determine Cost for.</param>
 /// <param name="actionSource">Source object which provides the Action.</param>
 /// <returns><c>True</c> if the Cost can be paid, otherwise <c>False</c>.</returns>
 public bool CanAfford(IInitiativeActor entity, IIdTracked actionSource)
 {
     return(true);
 }
Example #15
0
 /// <summary>
 /// Pay this Cost with the provided Actor.
 /// </summary>
 /// <param name="entity">Actor to pay the Cost with.</param>
 /// <param name="actionSource">Source object which provided the Action.</param>
 public void Pay(IInitiativeActor entity, IIdTracked actionSource)
 {
     // Intentionally left blank
 }
Example #16
0
 public IEnumerable <ICombatEventData> GetChangeEvents(IInitiativeActor before, IInitiativeActor after)
 {
     yield break;
 }
Example #17
0
 public InitPair(IInitiativeActor actor, float initiative)
 {
     Actor      = actor;
     Initiative = initiative;
 }
Example #18
0
 /// <summary>
 /// Get a collection of standard Actions for the supplied Actor.
 /// </summary>
 /// <param name="actor">Actor to create standard Actions for.</param>
 /// <returns>Collection of standard Actions.</returns>
 public IEnumerable <IAction> GetActions(IInitiativeActor actor)
 {
     yield break;
 }
Example #19
0
 /// <summary>
 /// Determines if the given Actor is targetable or not.
 /// </summary>
 /// <param name="sourceActor">Actor doing the targeting.</param>
 /// <param name="targetActor">Actor being targeted.</param>
 /// <returns><c>True</c> if the Actor can be targeted, otherwise <c>False</c>.</returns>
 public bool CanTarget(IInitiativeActor sourceActor, ITargetableActor targetActor)
 {
     return(sourceActor.Id == targetActor.Id);
 }
Example #20
0
 /// <summary>
 /// Determines if the given Actor is targetable or not.
 /// </summary>
 /// <param name="sourceActor">Actor doing the targeting.</param>
 /// <param name="targetActor">Actor being targeted.</param>
 /// <returns><c>True</c> if the Actor can be targeted, otherwise <c>False</c>.</returns>
 public bool CanTarget(IInitiativeActor sourceActor, ITargetableActor targetActor)
 {
     return(sourceActor.Party != targetActor.Party &&
            targetActor.IsAlive());
 }