/// <summary> /// Construct a new CombatManager object with the provided data. /// </summary> /// <param name="parties">All participants in combat, grouped by their Party affiliation.</param> /// <param name="standardActionGenerator">Supplier of standard actions which all Actors have access to.</param> /// <param name="winningPartyCalculator">Calculator for how CombatManager decides when combat is finished and which party won.</param> /// <param name="actorChangeCalculator">Calculator for changes within an actor's properties.</param> /// <param name="initiativeQueue">Implementation of an initiative queue for use in this combat session.</param> /// <param name="eventQueue">Implementation of an event queue for use in this combat session.</param> public CombatManager( IReadOnlyCollection <IParty> parties, ITurnController turnController, IStandardActionGenerator standardActionGenerator, IWinningPartyCalculator winningPartyCalculator, IActorChangeCalculator actorChangeCalculator, IInitiativeQueue initiativeQueue, IEventQueue eventQueue) { _turnController = turnController ?? new OneActionTurnController(); _standardActionGenerator = standardActionGenerator ?? new NullStandardActionGenerator(); _winningPartyCalculator = winningPartyCalculator ?? new AnyAliveWinningPartyCalculator(); _actorChangeCalculator = actorChangeCalculator ?? new NullActorChangeCalculator(); _initiativeQueue = initiativeQueue ?? new InitiativeQueue(100); _eventQueue = eventQueue ?? new EventQueue(); _parties.AddRange(parties); foreach (IParty party in parties) { _controllerByPartyId[party.Id] = party.Controller ?? new RandomCharacterController(); foreach (IInitiativeActor actor in party.Actors) { if (actor is ITargetableActor targetableActor) { _allTargets.Add(targetableActor); } float startingInitiative = (float)(RANDOM.NextDouble() * _initiativeQueue.InitiativeThreshold * 0.5f); _initiativeQueue.Add(actor, startingInitiative); } } _combatState = CombatState.Init; _eventQueue.EnqueueEvent(new CombatStateChangedEvent(_combatState)); }
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); } } }
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)); }