public IAbility GetAutoAttackAbility(IGameUnit user, IGameUnit target) { if (user.Abilities == null || !user.Abilities.Any(x => x.CanCounterAttack)) { return(null); } // Get all possible counter abilities for this user var counterAbilities = user.Abilities.Where(ability => ability.CanCounterAttack && user.CanUseAbility(ability) && AbilityRangeCalculator.CanAbilityTargetUnit(user, target, ability)).ToList(); if (!counterAbilities.Any()) { return(null); } // And pick the strongest one! var strongestAbility = counterAbilities.Select(ability => { var abilityParams = new AbilityExecuteParameters(user, ability, target, new List <IGameMapObject> { target }, target.MapPoint, _gameMap); var repeatCount = DamageCalculator.RepeatCount(ability, user, target); var results = ability.AbilityEffects.Select(x => x.PreviewResults(abilityParams)).Sum(x => x.BaseDamage * x.HitRate) * repeatCount; return(new { Ability = ability, DamageScore = results }); }).MaxBy(x => x.DamageScore).Ability; return(strongestAbility); }
public void ExecuteEffect(AbilityExecuteParameters parameters, AbilityResultContainer results) { if (results.Successful) { (parameters.Target as IGameUnit)?.ResetActionsConsumed(); } }
public AbilityResultContainer ExecuteAbilityEffect(AbilityExecuteParameters abilityExecuteParameters, IAbilityEffect effect) { // I'll have to break this up and change all this later, but for now I'm tired and just want something to work for now var effectResults = effect.CreateResults(abilityExecuteParameters); effect.ExecuteEffect(abilityExecuteParameters, effectResults); return(effectResults); }
public AbilityResultContainer PreviewResults(AbilityExecuteParameters parameters) { // This just always succeeds so mark our return container accordingly var result = new AbilityResultContainer(); result.Successful = parameters.Target is IGameUnit; return(result); }
public AbilityResultContainer CreateResults(AbilityExecuteParameters parameters) { var previewResults = PreviewResults(parameters); // TODO: Actually add RNG/accuracy previewResults.Successful = true; return(previewResults); }
public AbilityResultContainer PreviewResults(AbilityExecuteParameters parameters) { var results = new AbilityResultContainer(); results.BaseDamage = CalculateDamage(parameters); CreateDamageModifiers(parameters, results); return(results); }
public void ExecuteEffect(AbilityExecuteParameters parameters, AbilityResultContainer results) { if (!results.Successful) { return; } var targetUnit = parameters.Target as IGameUnit; targetUnit.TakeDamage(results.CalculateDamage()); }
public IEnumerable <AbilityResultContainer> ExecuteAbilityParameters(AbilityExecuteParameters abilityExecuteParameters) { // Check to see if the user of this ability can act. If they can't then we can't execute this action (ie they died during execution, or are disabled) // Also check if the target is dead. Don't attack if they're dead if (!abilityExecuteParameters.UnitExecuting.CanAct() || (abilityExecuteParameters.Target is IGameUnit && (abilityExecuteParameters.Target as IGameUnit).IsDead())) { return(Enumerable.Empty <AbilityResultContainer>()); } // Execute each ability effect and return the results containers return(abilityExecuteParameters.AbilityExecuting.AbilityEffects.Select(x => ExecuteAbilityEffect(abilityExecuteParameters, x)).ToList()); }
public int CalculateDamage(AbilityExecuteParameters parameters) { var user = parameters.UnitExecuting; var target = parameters.Target; // Set our current damage to the damage's base effect var damage = _damageParameters.BaseDamage; if (_damageParameters.DamagePairs != null && target is IGameUnit) { var targetUnit = parameters.Target as IGameUnit; foreach (var damagePair in _damageParameters.DamagePairs) { var attack = (int)(user.GetAttribute(damagePair.OffensiveAttribute) * damagePair.OffensiveAttributeMultiplier); var defense = (int)(targetUnit.GetAttribute(damagePair.DefensiveAttribute) * damagePair.DefensiveAttributeMultiplier); var pairDamage = Math.Max(attack - defense, 0); damage += pairDamage; } } return(damage); }
public void ExecutionQueueUpdate() { // Return if we don't have a queue to run if (!HasExecutionQueue()) { return; } // If we're currently running something then don't start another if (_currentAbilityExecuteParams != null) { return; } var executionParams = _currentAbilityExecuteParams = _executionQueue.Dequeue(); var executionResults = new List <AbilityResultContainer>(); // If the params doesn't have a target assigned we'll create dupes and populate the targets if (executionParams.Target == null) { var newParams = executionParams.AllTargets.Select(x => new AbilityExecuteParameters(executionParams.UnitExecuting, executionParams.AbilityExecuting, x, executionParams.AllTargets, executionParams.TargetPoint, executionParams.GameMap)); var newParamsResults = newParams.SelectMany(x => ExecuteAbilityParameters(x)).ToList(); executionResults.AddRange(newParamsResults); } // Otherwise we'll just execute the ability else { var paramsResults = ExecuteAbilityParameters(executionParams); executionResults.AddRange(paramsResults); } // DO SOME ANIMATION HERE? // ALSO IF A COUNTER HAS A COST IT ISN"T DEDUCTED EVER }
public AbilityResultContainer CreateResults(AbilityExecuteParameters parameters) { var result = PreviewResults(parameters); return(result); }
public void CreateDamageModifiers(AbilityExecuteParameters parameters, AbilityResultContainer abilityResultContainer) { var user = parameters.UnitExecuting; if (!(parameters.Target is IGameUnit)) { return; } var target = parameters.Target as IGameUnit; var sizeDifference = SizeCalculator.GetSizeDifference(user.SizeCategory, target.SizeCategory); var absSizeDifference = Math.Abs(sizeDifference); // Static size difference modifiers if (sizeDifference > 0) { var multiplier = Mathf.Pow(1.2f, absSizeDifference); abilityResultContainer.DamageModifiers.Add(new DamageModifierContainer { DamageMultiplier = multiplier, Name = "Bigger Size Bonus" }); } else if (sizeDifference < 0) { var multiplier = Mathf.Pow(0.8f, absSizeDifference); abilityResultContainer.DamageModifiers.Add(new DamageModifierContainer { DamageMultiplier = multiplier, Name = "Smaller Size Bonus" }); } // Ability-based Size Difference if (_damageParameters.SizeBiggerDamageMultiplier > 1 && sizeDifference > 0) { var multiplier = Mathf.Pow(_damageParameters.SizeBiggerDamageMultiplier, absSizeDifference); abilityResultContainer.DamageModifiers.Add(new DamageModifierContainer { DamageMultiplier = multiplier, Name = "Ability Bigger Size Bonus" }); } else if (_damageParameters.SizeBiggerDamageMultiplier < 1 && sizeDifference > 0) { var multiplier = Mathf.Pow(_damageParameters.SizeBiggerDamageMultiplier, absSizeDifference); abilityResultContainer.DamageModifiers.Add(new DamageModifierContainer { DamageMultiplier = multiplier, Name = "Ability Bigger Size Penalty" }); } if (_damageParameters.SizeSmallerDamageMultiplier > 1 && sizeDifference < 0) { var multiplier = Mathf.Pow(_damageParameters.SizeSmallerDamageMultiplier, absSizeDifference); abilityResultContainer.DamageModifiers.Add(new DamageModifierContainer { DamageMultiplier = multiplier, Name = "Ability Smaller Size Bonus" }); } else if (_damageParameters.SizeSmallerDamageMultiplier < 1 && sizeDifference < 0) { var multiplier = Mathf.Pow(_damageParameters.SizeSmallerDamageMultiplier, absSizeDifference); abilityResultContainer.DamageModifiers.Add(new DamageModifierContainer { DamageMultiplier = multiplier, Name = "Ability Smaller Size Penalty" }); } }