public BodyTemplate process(RawBodyTemplate rawTemplate) { BodyTemplate template = new BodyTemplate(rawTemplate); log("processing " + rawTemplate.name + " body template"); Dictionary <string, RawBodyPart> rawPartMap = rawTemplate.body .ToDictionary(part => part.name, part => part); // part name to part log(" rawPartMap " + rawPartMap.Count + " " + rawPartMap.Keys); updateLimbsMirroringFlags(rawPartMap); log(" unmirrored slots " + rawTemplate.slots.Count); mirrorSlots(rawTemplate, rawPartMap); foreach (var slot in rawTemplate.slots) // copy slots to new template { template.slots.Add(slot[0], slot.GetRange(1, slot.Count - 1)); } log(" mirrored slots " + template.slots.Count + " " + template.slots.Keys); doubleMirroredParts(rawPartMap); log(" doubled parts " + rawPartMap.Count + " " + rawPartMap.Keys); fillBodyParts(rawPartMap, template); return(template); }
/** * Mirrors slots which use only mirrored parts (boots etc.). * Mirrors only limbs in a slot, if there are non-mirrored limbs in that slot (pants). * Side prefixes are added in this method. After mirroring limbs, limbs and slots become consistent. * Also mirrors desired slots. */ private void mirrorSlots(RawBodyTemplate rawTemplate, Dictionary <string, RawBodyPart> rawPartMap) { List <List <string> > newSlots = new List <List <string> >(); foreach (List <string> slot in rawTemplate.slots) { string slotName = slot[0]; List <string> slotLimbs = slot.GetRange(1, slot.Count - 1); if (containsOnlyMirroredLimbs(slotLimbs, rawPartMap)) // create two slots (names are prefixed) { log(" slot " + slotName + " gets mirroring"); newSlots.Add(slot.Select(s => LEFT_PREFIX + s).ToList()); // left copy of a slot newSlots.Add(slot.Select(s => RIGHT_PREFIX + s).ToList()); // right copy of a slot if (rawTemplate.desiredSlots.Contains(slotName)) { rawTemplate.desiredSlots.Remove(slotName); rawTemplate.desiredSlots.Add(LEFT_PREFIX + slotName); rawTemplate.desiredSlots.Add(RIGHT_PREFIX + slotName); } } else // some limbs are single, so mirrored limbs are duplicated in same slot { int notMirroredLimbsSize = slotLimbs.Count; List <string> newSlotLimbs = slotLimbs // copy some limbs with prefixes .SelectMany(s => rawPartMap[s].mirrored ? new[] { LEFT_PREFIX + s, RIGHT_PREFIX + s } :new[] { s }) .ToList(); if (newSlotLimbs.Count > notMirroredLimbsSize) { log(" " + (newSlotLimbs.Count - notMirroredLimbsSize) + " limb(s) got mirrored in slot " + slotName); } newSlotLimbs.Insert(0, slotName); newSlots.Add(newSlotLimbs); } } rawTemplate.slots = newSlots; }