/// <summary> /// Gets an ability value. /// If the stacking rule in the mod is DoNotStack, an arbitrary matching ability will be chosen. /// If there are no values, null will be returned. /// </summary> /// <param name="name">The name of the ability.</param> /// <param name="obj">The object from which to get the value.</param> /// <param name="index">The ability value index (usually 1 or 2).</param> /// <param name="filter">A filter for the abilities. For instance, you might want to filter by the ability grouping rule's value.</param> /// <returns>The ability value.</returns> public static string GetAbilityValue(this IAbilityObject obj, string name, int index = 1, bool includeShared = true, bool includeEmpireCommon = true, Func <Ability, bool> filter = null) { if (obj == null) { return(null); } var abils = obj.Abilities(); if (includeShared) { abils = abils.Union(obj.SharedAbilities()); } if (includeEmpireCommon) { abils = abils.Union(obj.EmpireCommonAbilities()); } abils = abils.Where(a => a.Rule != null && a.Rule.Matches(name) && a.Rule.CanTarget(obj.AbilityTarget) && (filter == null || filter(a))); abils = abils.Stack(obj); if (!abils.Any()) { return(null); } return(abils.First().Values[index - 1]); }
/// <summary> /// All abilities belonging to an object, before stacking. /// </summary> /// <param name="obj"></param> /// <param name="includeShared"></param> /// <returns></returns> public static IEnumerable <Ability> UnstackedAbilities(this IAbilityObject obj, bool includeShared, Func <IAbilityObject, bool> sourceFilter = null) { if (obj == null) { return(Enumerable.Empty <Ability>()); } IEnumerable <Ability> result; if (sourceFilter == null || sourceFilter(obj)) { result = obj.IntrinsicAbilities.Concat(obj.DescendantAbilities(sourceFilter)).Concat(obj.AncestorAbilities(sourceFilter)); } else { result = obj.DescendantAbilities(sourceFilter).Concat(obj.AncestorAbilities(sourceFilter)); } if (includeShared) { result = result.Concat(obj.SharedAbilities(sourceFilter)); } return(result); }
/// <summary> /// Determines if an object has a specified ability. /// </summary> /// <param name="obj"></param> /// <param name="abilityName"></param> /// <returns></returns> public static bool HasAbility(this IAbilityObject obj, string abilityName, bool includeShared = true) { IEnumerable <Ability> abils; if (includeShared && obj is IOwnableAbilityObject) { abils = obj.UnstackedAbilities(true).Union(obj.SharedAbilities()); } else { abils = obj.UnstackedAbilities(true); } return(abils.Any(abil => abil.Rule != null && abil.Rule.Matches(abilityName))); }