private static void LoadRoomPrototypesRecur(AbstractDungeonElement styledElement, IDictionary <string, RoomCollection> collector, Func <string, RoomCollection> roomLoader) { var style = styledElement.Style; if (!collector.ContainsKey(style)) { collector.Add(style, roomLoader(style)); } styledElement.SubElements.ForEach(element => LoadRoomPrototypesRecur(element, collector, roomLoader)); }
private static void AddParentTagsRecursive(AbstractDungeonElement element, IEnumerable <string> tags) { element.SubElements.ForEach(s => AddParentTagsRecursive(s, tags)); tags.ForEach(element.ElementMetaData.AddTag); }
private static AbstractDungeonElement ReadElement(ConfigNode config, ISet <string> nestedDungeonCollector) { AbstractDungeonElement element = null; config.TryQuery(NODE).IfPresent(node => { var nodeElementBuilder = DungeonElementBuilder .NodeElement(node.AsString()) .SetMetaData(CollectMetaData(config)); config.TryQuery(SUBS).IfPresent(subElementNodes => subElementNodes.AsList() .Select(subNode => ReadElement(subNode.AsNode(), nestedDungeonCollector)) .ForEach(subElement => nodeElementBuilder.AddSubElement(subElement))); element = nodeElementBuilder.Build(); }); if (element == null) { config.TryQuery(CONNECTION).IfPresent(connection => { var style = connection.AsString(); var length = config.Query(LENGTH).AsRangeI().ToTaurusRange(); var connectionElementBuilder = DungeonElementBuilder .ConnectionElement(style, length) .SetMetaData(CollectMetaData(config)); config.TryQuery(SUBS).IfPresent(subElementNodes => subElementNodes.AsList() .Select(queryResult => ReadElement(queryResult.AsNode(), nestedDungeonCollector)) .ForEach(subElement => connectionElementBuilder.AddSubElement(subElement))); element = connectionElementBuilder.Build(); }); } if (element == null) { config.TryQuery(NESTED).IfPresent(nested => { var path = nested.AsString(); nestedDungeonCollector.Add(path); var nestedElementBuilder = DungeonElementBuilder .NestedDungeonElement(path) .SetMetaData(CollectMetaData(config)); config.TryQuery(SUBS).IfPresent(subElementNodes => subElementNodes.AsList() .Select(node => ReadElement(node.AsNode(), nestedDungeonCollector)) .ForEach(subElement => nestedElementBuilder.AddSubElement(subElement))); element = nestedElementBuilder.Build(); }); } if (element == null) { throw new Exception("unknown dungeon element type!"); } return(element); }
internal static DungeonNode ConcretizeDungeonTree(AbstractDungeonElement inputElement, Random random, ReadOnlyDictionary <string, AbstractDungeonStructure> embeddedDungeons) { { if (inputElement is NodeElement node) { DungeonNode copyNode; if (node.IsEndNode) { copyNode = new DungeonNode(node.Style, (NodeMetaData)node.ElementMetaData.Clone()); } else { List <DungeonNode> subElements = node.SubElements.Select(element => ConcretizeDungeonTree(element, random, embeddedDungeons)).ToList(); copyNode = new DungeonNode(node.Style, (NodeMetaData)node.ElementMetaData.Clone(), subElements); } return(copyNode); } } { if (inputElement is ConnectionElement connection) { var connectionLength = connection.Length.RandomNumberInRange(random); DungeonNode replacementNode = null; if (connection.SubElements.Count == 1) { DungeonNode nextElement = ConcretizeDungeonTree(connection.SubElements.Single(), random, embeddedDungeons); replacementNode = nextElement; } for (int i = 0; i < connectionLength; i++) { replacementNode = replacementNode != null ? new DungeonNode(connection.Style, (NodeMetaData)connection.ElementMetaData.Clone(), new List <DungeonNode> { replacementNode }) : new DungeonNode(connection.Style, (NodeMetaData)connection.ElementMetaData.Clone()); } if (replacementNode == null) { throw new Exception("This should not happen"); } return(replacementNode); } } { if (inputElement is NestedDungeon nested) { DungeonNode[] abstractSubElements = nested.SubElements.Select(element => ConcretizeDungeonTree(element, random, embeddedDungeons)).ToArray(); DungeonNode nestedStartNode = ConcretizeStructure(embeddedDungeons[nested.Path], random).StartElement; nestedStartNode.TraverseDepthFirst().ForEach(x => x.MetaData.AddTag(NESTED_TAG)); if (abstractSubElements.Length > 0) { List <DungeonNode> endNodeCollector = new List <DungeonNode>(); CollectEndNodes(nestedStartNode, endNodeCollector); endNodeCollector.Shuffle(random); for (int i = 0; i < abstractSubElements.Length; i++) { endNodeCollector[i].AddSubElement(abstractSubElements[i]); } } return(nestedStartNode); } } throw new Exception($"Unknown AbstractDungeonElement type: {inputElement.GetType()}"); }