/// <summary> /// Gets abilities that have been shared to an object. /// </summary> /// <param name="obj"></param> /// <returns></returns> public static IEnumerable <Ability> SharedAbilities(this ICommonAbilityObject obj, Empire empire, Func <IAbilityObject, bool> sourceFilter = null) { if (obj == null) { yield break; } if (empire == null) { yield break; } foreach (var clause in empire.ReceivedTreatyClauses.Flatten().OfType <ShareAbilityClause>()) { var rule = clause.AbilityRule; if (clause.AbilityRule.CanTarget(obj.AbilityTarget)) { if (rule.CanTarget(AbilityTargets.Sector) && obj is ILocated) { var sector = ((ILocated)obj).Sector; foreach (var emp in Galaxy.Current.Empires.Where(emp => emp != null)) { foreach (var abil in sector.EmpireAbilities(emp, sourceFilter)) { if (clause.AbilityRule == abil.Rule) { yield return(abil); } } } } else if (rule.CanTarget(AbilityTargets.StarSystem) && (obj is StarSystem || obj is ILocated)) { var sys = ((ILocated)obj).StarSystem; foreach (var emp in Galaxy.Current.Empires.Where(emp => emp != null)) { foreach (var abil in sys.EmpireAbilities(emp, sourceFilter)) { if (clause.AbilityRule == abil.Rule) { yield return(abil); } } } } else if (rule.CanTarget(AbilityTargets.Galaxy)) { foreach (var emp in Galaxy.Current.Empires.Where(emp => emp != null)) { foreach (var abil in Galaxy.Current.EmpireAbilities(emp, sourceFilter)) { if (clause.AbilityRule == abil.Rule) { yield return(abil); } } } } } } }
public static IEnumerable <Ability> EmpireAbilities(this ICommonAbilityObject obj, Empire emp, Func <IAbilityObject, bool> sourceFilter = null) { if (obj == null) { return(Enumerable.Empty <Ability>()); } if (sourceFilter == null) { var subobjs = obj.GetContainedAbilityObjects(emp); Func <IEnumerable <Ability> > getabils = () => subobjs.SelectMany(o => o.Abilities()).Where(a => a.Rule.CanTarget(obj.AbilityTarget)); if (Galaxy.Current.IsAbilityCacheEnabled) { var tuple = Tuple.Create(obj, emp); if (Galaxy.Current.CommonAbilityCache[tuple] == null) { Galaxy.Current.CommonAbilityCache[tuple] = getabils(); } return(Galaxy.Current.CommonAbilityCache[tuple]); } else { return(getabils()); } } else { return(obj.GetContainedAbilityObjects(emp).Where(o => sourceFilter(o)).SelectMany(o => o.Abilities()).Where(a => a.Rule.CanTarget(obj.AbilityTarget))); } }
/// <summary> /// Aggregates abilities for an empire's space objects. /// </summary> /// <param name="emp"></param> /// <param name="name"></param> /// <param name="index"></param> /// <param name="filter"></param> /// <returns></returns> public static string GetEmpireAbilityValue(this ICommonAbilityObject obj, Empire emp, string name, int index = 1, Func <Ability, bool> filter = null) { if (obj == null) { return(null); } if (filter == null && Galaxy.Current.IsAbilityCacheEnabled) { // use the cache var cached = Galaxy.Current.CommonAbilityCache[Tuple.Create(obj, emp)]; if (cached != null) { if (cached.Any()) { return(cached.Where(x => x.Rule.Matches(name)).Stack(obj).FirstOrDefault()?.Values[index - 1]); } else { return(null); } } } IEnumerable <Ability> abils; var subabils = obj.GetContainedAbilityObjects(emp).SelectMany(o => o.UnstackedAbilities(true).Where(a => a.Rule.Name == name)); if (obj is IAbilityObject) { abils = ((IAbilityObject)obj).Abilities().Where(a => a.Rule != null && a.Rule.Name == name).Concat(subabils).Stack(obj); } else { abils = subabils; } abils = abils.Where(a => a.Rule != null && a.Rule.Matches(name) && a.Rule.CanTarget(obj.AbilityTarget) && (filter == null || filter(a))); string result; if (!abils.Any()) { result = null; } else { result = abils.First().Values[index - 1]; } // cache abilities if we can if (filter == null && Galaxy.Current.IsAbilityCacheEnabled) { Galaxy.Current.CommonAbilityCache[Tuple.Create(obj, emp)] = abils.ToArray(); } return(result); }
/// <summary> /// Determines if a common ability object has a specified ability for an empire. /// </summary> /// <param name="obj"></param> /// <param name="abilityName"></param> /// <returns></returns> public static bool HasAbility(this ICommonAbilityObject obj, string abilityName, Empire emp, bool includeShared = true) { IEnumerable <Ability> abils; if (includeShared) { abils = obj.EmpireAbilities(emp).Union(obj.SharedAbilities(emp)); } else { abils = obj.EmpireAbilities(emp); } return(abils.Any(abil => abil.Rule != null && abil.Rule.Matches(abilityName))); }