void RemoveRoom(DungeonRoom room) { removedRoom = room; Rooms.Remove(room); foreach (var portal in room.Portals) { portal.ConnectedRoom = null; } }
/// <summary> /// 消えた部屋につながっていた袋小路の処理 /// </summary> /// <param name="room"></param> void ProcessDeadEnd(DungeonRoom room) { var deadends = new List<DungeonPath>(); UpdateAccessibility(); foreach (var portal in room.Portals) { if (portal.ConnectedPaths.Count == 0) continue; var path = portal.ConnectedPaths[0]; if (path.Accessible) { // 袋小路をリストアップ deadends.Add(path); } else { // 孤立している通路は消す RemovePath(path); } } var selector = new RandomSelector<DeadEndDisposal>(Rand); selector.Add(40, DeadEndDisposal.CONNECT); selector.Add(55, DeadEndDisposal.REMOVE); selector.Add(5, DeadEndDisposal.LEAVE); while (deadends.Count > 0) { var disposal = selector.Get(); if (disposal == DeadEndDisposal.CONNECT && deadends.Count >= 2) { var another = Rand.Next(1, deadends.Count); var portals = new DungeonPortal[2]{ deadends[0].GetTerminalPortal(), deadends[another].GetTerminalPortal() }; var path = GeneratePath( portals[0], portals[1], IsHorizontalPortals(portals[0], portals[1]) ); if (path != null) { AddPath(path); deadends.RemoveAt(another); } deadends.RemoveAt(0); } else if (disposal == DeadEndDisposal.REMOVE) { RemovePath(deadends[0]); deadends.RemoveAt(0); } else if (disposal == DeadEndDisposal.LEAVE) { deadends.RemoveAt(0); } } }
/// <summary> /// 隣同士の部屋をつなぐためのポータル(出入口)のペアを生成 /// </summary> void GenerateRoomPortals( DungeonRoom startRoom, DungeonRoom endRoom, bool isHorizontal, out DungeonPortal startPortal, out DungeonPortal endPortal) { startPortal = new DungeonPortal( startRoom.GetRandomPortalPoint(isHorizontal ? DungeonRoom.Side.Right : DungeonRoom.Side.Bottom)); startPortal.ConnectedRoom = startRoom; startRoom.Portals.Add(startPortal); endPortal = new DungeonPortal( endRoom.GetRandomPortalPoint(isHorizontal ? DungeonRoom.Side.Left : DungeonRoom.Side.Top)); endPortal.ConnectedRoom = endRoom; endRoom.Portals.Add(endPortal); }
/// <summary> /// 部屋をいくつか間引く /// </summary> void ThinOutRooms() { var removeNum = Rand.Next(7, 12); for (var i = 0; i < removeNum; ++i) { removedRoom = null; removedPaths.Clear(); addedPaths.Clear(); ThinOutRoom(); if (!IsValidMap()) { UndoRoom(); UndoPaths(); i--; } } }
/// <summary> /// 隣同士の部屋をつなぐ通路を生成 /// </summary> void GenerateRoomPaths(DungeonRoom startRoom, DungeonRoom endRoom, bool isHorizontal) { var portals = new DungeonPortal[2]; GenerateRoomPortals( startRoom, endRoom, isHorizontal, out portals[0], out portals[1]); Paths.Add(GeneratePath(portals[0], portals[1], isHorizontal)); Portals.Add(portals[0]); Portals.Add(portals[1]); }