/// <summary> /// Defines a custom NPC group to add to the database. Must be called after entity groups loaded, but before mods /// finish loading (PostSetupContent, etc.). /// </summary> /// <param name="groupName"></param> /// <param name="groupDependencies">Other groups the current group references.</param> /// <param name="matcher">Function to use to match NPCs for this group.</param> public static void AddCustomNPCGroup(string groupName, string[] groupDependencies, NPCGroupMatcher matcher) { lock (EntityGroups.MyLock) { var entGrps = ModHelpersMod.Instance.EntityGroups; if (!entGrps.IsEnabled) { throw new Exception("Entity groups not enabled."); } if (entGrps.CustomNPCMatchers == null) { throw new Exception("Mods loaded; cannot add new groups."); } var entry = new EntityGroupMatcherDefinition <NPC>(groupName, groupDependencies, matcher); entGrps.CustomNPCMatchers.Add(entry); } }
private void ComputeGroups <T>(IList <EntityGroupMatcherDefinition <T> > matchers, ref IDictionary <string, IReadOnlySet <int> > groups, ref IDictionary <int, IReadOnlySet <string> > groupsPerEnt) where T : Entity { var rawGroupsPerEnt = new Dictionary <int, ISet <string> >(); IList <T> pool = this.GetPool <T>(); for (int i = 0; i < matchers.Count; i++) { EntityGroupMatcherDefinition <T> matcher = matchers[i]; ISet <int> grp; if (!this.ComputeGroupMatch(pool, matcher, out grp)) { matchers.Add(matchers[i]); continue; } lock (EntityGroups.MyLock) { groups[matcher.GroupName] = new ReadOnlySet <int>(grp); } foreach (int idx in grp) { if (!rawGroupsPerEnt.ContainsKey(idx)) { rawGroupsPerEnt[idx] = new HashSet <string>(); } rawGroupsPerEnt[idx].Add(matcher.GroupName); } } lock (EntityGroups.MyLock) { foreach (var kv in rawGroupsPerEnt) { groupsPerEnt[kv.Key] = new ReadOnlySet <string>(kv.Value); } } }
private bool ComputeGroupMatch <T>(IList <T> entityPool, EntityGroupMatcherDefinition <T> matcher, out ISet <int> entityIdsOfGroup) where T : Entity { entityIdsOfGroup = new HashSet <int>(); EntityGroupDependencies deps = this.GetGroups <T>(matcher.GroupName, matcher.GroupDependencies); for (int i = 1; i < entityPool.Count; i++) { try { lock (EntityGroups.MyLock) { if (matcher.Matcher.MatcherFunc(entityPool[i], deps)) { entityIdsOfGroup.Add(i); } } } catch (Exception) { LogHelpers.Alert("Compute fail for '" + matcher.GroupName + "' with ent (" + i + ") " + (entityPool[i] == null ? "null" : entityPool[i].ToString())); } } return(true); }