/// <summary> /// Add a new cell to the layout that correspond to a certain node in the mission graph /// </summary> /// <param name="node">corresponding node in the mission graph</param> /// <param name="parentID">the id of the parent that the new cell should be connected to</param> /// <returns>True if it succeed and False otherwise</returns> public bool addCell(MissionGraph.Node node, int parentID) { if (node.type == MissionGraph.NodeType.Lock) { OpenNode selected = this.getWorkingLocation(parentID, node.accessLevel - 1); if (selected == null) { return(false); } Cell newCell = new Cell(selected.x, selected.y, CellType.Normal, node); newCell.connectCells(selected.parent, DoorType.KeyLock); newCell.parent = selected.parent; this.addNewNode(newCell, node.accessLevel, node.id); } else if (node.type == MissionGraph.NodeType.Puzzle) { OpenNode selected = this.getWorkingLocation(parentID, node.accessLevel); if (selected == null) { return(false); } Cell newCell = new Cell(selected.x, selected.y, CellType.Normal, node); newCell.connectCells(selected.parent, DoorType.Open); newCell.parent = selected.parent; this.addNewNode(newCell, node.accessLevel + 1, node.id); } else if (node.type == MissionGraph.NodeType.Lever) { OpenNode selected = this.getWorkingLocation(parentID, node.accessLevel); if (selected == null) { return(false); } Cell newCell = new Cell(selected.x, selected.y, CellType.Normal, node); newCell.connectCells(selected.parent, DoorType.Open); newCell.parent = selected.parent; this.usedSpaces.Add(newCell.getLocationString(), newCell); } else { OpenNode selected = this.getWorkingLocation(parentID, node.accessLevel); if (selected == null) { return(false); } Cell newCell = new Cell(selected.x, selected.y, CellType.Normal, node); if (selected.parent.node.type == MissionGraph.NodeType.Puzzle) { newCell.connectCells(selected.parent, DoorType.PuzzleLock); } else if (selected.parent.node.type == MissionGraph.NodeType.Lever) { newCell.connectCells(selected.parent, DoorType.LeverLock); } else { newCell.connectCells(selected.parent, DoorType.Open); } if (node.getChildren().Count == 0) { this.usedSpaces.Add(newCell.getLocationString(), newCell); } else { this.addNewNode(newCell, node.accessLevel, parentID); } newCell.parent = selected.parent; } return(true); }
/// <summary> /// Generate a map layout that correspond to the input mission graph /// </summary> /// <param name="graph">the mission graph that need to be mapped to a 2D layout</param> /// <returns>a 2D layout of the mission graph</returns> public Map generateDungeon(MissionGraph.Graph graph) { Map result = new Map(this.random); result.initializeCell(graph.nodes[0]); #region make initial dungeon List <MissionGraph.Node> open = new List <MissionGraph.Node>(); Dictionary <MissionGraph.Node, int> parentIDs = new Dictionary <MissionGraph.Node, int>(); foreach (MissionGraph.Node child in graph.nodes[0].getChildren()) { open.Add(child); parentIDs.Add(child, 0); } HashSet <MissionGraph.Node> nodes = new HashSet <MissionGraph.Node>(); nodes.Add(graph.nodes[0]); while (open.Count > 0) { MissionGraph.Node current = open[0]; open.RemoveAt(0); if (nodes.Contains(current)) { continue; } nodes.Add(current); if (!result.addCell(current, parentIDs[current])) { return(null); } foreach (MissionGraph.Node child in current.getChildren()) { if (!parentIDs.ContainsKey(child)) { if (current.type == MissionGraph.NodeType.Lock || current.type == MissionGraph.NodeType.Puzzle) { parentIDs.Add(child, current.id); } else { parentIDs.Add(child, parentIDs[current]); } } open.Add(child); } } #endregion #region make lever connections open.Clear(); nodes.Clear(); open.Add(graph.nodes[0]); while (open.Count > 0) { MissionGraph.Node current = open[0]; open.RemoveAt(0); if (nodes.Contains(current)) { continue; } nodes.Add(current); foreach (MissionGraph.Node child in current.getChildren()) { Cell from = result.getCell(current.id); Cell to = result.getCell(child.id); if (current.type == MissionGraph.NodeType.Lever) { if (!result.makeConnection(from, to, nodes.Count * nodes.Count)) { return(null); } } open.Add(child); } } #endregion return(result); }