public IReadOnlyList <SlotDefinition> For(IRecord record, int slotCount) { var entityType = record.Type; var index = record.Index; var id = (record as IHasId)?.Id; var slotsDefs = GetDefinitions(entityType).Where(def => (def.EntityIds.Count == 0 && def.TemplateIds.Count == 0) || def.EntityIds.Contains(index) || def.EntityIds.Contains(id) || ( record is Party party && party.party_template_id.Entity is PartyTemplate template && ( def.TemplateIds.Contains(template.Index) || def.TemplateIds.Contains(template.Definition?.Id)))); var slotDefs = new SlotDefinition[slotCount]; for (int i = 0; i < slotCount; ++i) { SlotDefinition?slotDef = null; foreach (var slotsDef in slotsDefs) { var newDef = slotsDef.SlotDefinitions[i]; if (newDef != null) { slotDef = newDef; } } slotDefs[i] = slotDef ?? new SlotDefinition(i); } return(slotDefs); }
public static SlotsDefinition Parse(XElement element, ModuleMetadata module) { var xmlns = ModuleMetadata.XmlNamespace; var entityType = module.GetType(element.Attribute("of")); IEnumerable <object> ParseId(string token, XAttribute attr) { if (int.TryParse(token, out var n)) { return(new object[] { n }); } else if (token.StartsWith("$")) { var groupDef = module.GroupsDefinitions.GetGroupDefinition(entityType, token, attr); return(groupDef.Ranges.SelectMany(range => range.Cast <object>())); } else { return(new object[] { token }); } } IEnumerable <object> ParseIds(XAttribute attr) => ((string)attr ?? "") .Split(whitespace, StringSplitOptions.RemoveEmptyEntries) .SelectMany(s => ParseId(s, attr)) .Distinct(); var entityIds = ParseIds(element.Attribute("id")); var templateIds = ParseIds(element.Attribute("template-id")); ISlotDefinitions slotDefinitions; var arrayElement = element.Element(xmlns + "array"); if (arrayElement != null) { slotDefinitions = new ArraySlotDefinitions(module.GetType(arrayElement.Attribute("type"))); } else { var slotDefs = new Dictionary <int, SlotDefinition>(); foreach (var slotElement in element.Elements(xmlns + "slot")) { var slotDef = SlotDefinition.Parse(slotElement, module); if (slotDefs.ContainsKey(slotDef.Index)) { throw slotElement.InvalidXml($"Slot {slotDef.Index} is already defined for {entityType.Name}"); } slotDefs.Add(slotDef.Index, slotDef); } slotDefinitions = new SlotDefinitions(slotDefs.Values); } return(new SlotsDefinition(entityType, entityIds, templateIds, slotDefinitions)); }