// Usage. public void UseAbility(IAttackAbilityPresentation abilityPresentation, UnitPresentation target) { if (attacks.TryGetValue(abilityPresentation, out IAttackAbility ability)) { ability.Use(target); } }
// Acting. private protected override void OnAct(out GoalStatus goalStatus) { var owner = Owner; var context = Context; if (owner is null || context is null) { goalStatus = GoalStatus.Active; return; } // Check if target is down. if (Goal.Target.Durability.Fallen) { goalStatus = GoalStatus.Achieved; return; } // Check if already attacking. if (owner.Condition is IAttackConditionPresentation currentAttack && currentAttack.Target == Goal.Target) { goalStatus = GoalStatus.Active; return; } // Choose attack ability. IAttackAbilityPresentation chosenAttack = null; foreach (var attackAbility in owner.AbilityCollection.Attacks) { if (chosenAttack == null || attackAbility.DamagePerSecond.DamageValue > chosenAttack.DamagePerSecond.DamageValue) { chosenAttack = attackAbility; } } if (chosenAttack == null) { goalStatus = GoalStatus.Failed; return; } // Check if target is reached. var currentPosition = owner.Body.Position; var targetPosition = Goal.Target.Body.Position; if ((currentPosition - targetPosition).magnitude <= chosenAttack.AttackRange) { var abilityUsage = new AttackUsageAction(chosenAttack, Goal.Target); owner.PlanAction(abilityUsage); goalStatus = GoalStatus.Active; return; } // Reach target. if (relocation == null) { var goal = new RelocationGoal(targetPosition); relocation = new RelocationBehaviour(goal, this); } relocation.Act(out GoalStatus relocationStatus); if (relocationStatus == GoalStatus.Failed) { goalStatus = GoalStatus.Failed; return; } if (relocationStatus == GoalStatus.Achieved) { relocation = null; } goalStatus = GoalStatus.Active; }