Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / room / DungeonManager.cs
  1.  
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using Godot;
  6.  
  7. /// <summary>
  8. /// 地牢管理器
  9. /// </summary>
  10. public partial class DungeonManager : Node2D
  11. {
  12. /// <summary>
  13. /// 起始房间
  14. /// </summary>
  15. public RoomInfo StartRoomInfo => _dungeonGenerator?.StartRoomInfo;
  16. /// <summary>
  17. /// 当前玩家所在的房间
  18. /// </summary>
  19. public RoomInfo ActiveRoomInfo => Player.Current?.AffiliationArea?.RoomInfo;
  20. /// <summary>
  21. /// 当前玩家所在的区域
  22. /// </summary>
  23. public AffiliationArea ActiveAffiliationArea => Player.Current?.AffiliationArea;
  24.  
  25. /// <summary>
  26. /// 是否在地牢里
  27. /// </summary>
  28. public bool IsInDungeon { get; private set; }
  29.  
  30. /// <summary>
  31. /// 是否是编辑器模式
  32. /// </summary>
  33. public bool IsEditorMode { get; private set; }
  34. /// <summary>
  35. /// 当前使用的配置
  36. /// </summary>
  37. public DungeonConfig CurrConfig { get; private set; }
  38. /// <summary>
  39. /// 当前使用的世界对象
  40. /// </summary>
  41. public World World { get; private set; }
  42. private UiBase _prevUi;
  43. private DungeonTileMap _dungeonTileMap;
  44. private AutoTileConfig _autoTileConfig;
  45. private DungeonGenerator _dungeonGenerator;
  46. //房间内所有静态导航网格数据
  47. private List<NavigationPolygonData> _roomStaticNavigationList;
  48. //用于检查房间敌人的计时器
  49. private float _checkEnemyTimer = 0;
  50.  
  51.  
  52. public DungeonManager()
  53. {
  54. //绑定事件
  55. EventManager.AddEventListener(EventEnum.OnPlayerFirstEnterRoom, OnPlayerFirstEnterRoom);
  56. EventManager.AddEventListener(EventEnum.OnPlayerEnterRoom, OnPlayerEnterRoom);
  57. }
  58. /// <summary>
  59. /// 加载地牢
  60. /// </summary>
  61. public void LoadDungeon(DungeonConfig config, Action finish = null)
  62. {
  63. IsEditorMode = false;
  64. CurrConfig = config;
  65. GameApplication.Instance.StartCoroutine(RunLoadDungeonCoroutine(finish));
  66. }
  67. /// <summary>
  68. /// 重启地牢
  69. /// </summary>
  70. public void RestartDungeon(DungeonConfig config)
  71. {
  72. IsEditorMode = false;
  73. CurrConfig = config;
  74. ExitDungeon(() =>
  75. {
  76. LoadDungeon(CurrConfig);
  77. });
  78. }
  79.  
  80. /// <summary>
  81. /// 退出地牢
  82. /// </summary>
  83. public void ExitDungeon(Action finish = null)
  84. {
  85. IsInDungeon = false;
  86. GameApplication.Instance.StartCoroutine(RunExitDungeonCoroutine(finish));
  87. }
  88. //-------------------------------------------------------------------------------------
  89.  
  90. /// <summary>
  91. /// 在编辑器模式下进入地牢
  92. /// </summary>
  93. /// <param name="config">地牢配置</param>
  94. public void EditorPlayDungeon(DungeonConfig config)
  95. {
  96. IsEditorMode = true;
  97. CurrConfig = config;
  98. if (_prevUi != null)
  99. {
  100. _prevUi.HideUi();
  101. }
  102. GameApplication.Instance.StartCoroutine(RunLoadDungeonCoroutine(null));
  103. }
  104. /// <summary>
  105. /// 在编辑器模式下进入地牢
  106. /// </summary>
  107. /// <param name="prevUi">记录上一个Ui</param>
  108. /// <param name="config">地牢配置</param>
  109. public void EditorPlayDungeon(UiBase prevUi, DungeonConfig config)
  110. {
  111. IsEditorMode = true;
  112. CurrConfig = config;
  113. _prevUi = prevUi;
  114. if (_prevUi != null)
  115. {
  116. _prevUi.HideUi();
  117. }
  118. GameApplication.Instance.StartCoroutine(RunLoadDungeonCoroutine(null));
  119. }
  120.  
  121. /// <summary>
  122. /// 在编辑器模式下退出地牢, 并且打开上一个Ui
  123. /// </summary>
  124. public void EditorExitDungeon()
  125. {
  126. IsInDungeon = false;
  127. GameApplication.Instance.StartCoroutine(RunExitDungeonCoroutine(() =>
  128. {
  129. IsEditorMode = false;
  130. //显示上一个Ui
  131. if (_prevUi != null)
  132. {
  133. _prevUi.ShowUi();
  134. }
  135. }));
  136. }
  137. //-------------------------------------------------------------------------------------
  138.  
  139. public override void _Process(double delta)
  140. {
  141. if (IsInDungeon)
  142. {
  143. _checkEnemyTimer += (float)delta;
  144. if (_checkEnemyTimer >= 1)
  145. {
  146. _checkEnemyTimer %= 1;
  147. //检查房间内的敌人存活状况
  148. OnCheckEnemy();
  149. }
  150. //更新敌人视野
  151. UpdateEnemiesView();
  152. if (GameApplication.Instance.Debug)
  153. {
  154. QueueRedraw();
  155. }
  156. }
  157. }
  158.  
  159. //执行加载地牢协程
  160. private IEnumerator RunLoadDungeonCoroutine(Action finish)
  161. {
  162. //打开 loading UI
  163. UiManager.Open_Loading();
  164. yield return 0;
  165. //创建世界场景
  166. World = GameApplication.Instance.CreateNewWorld();
  167. yield return new WaitForFixedProcess(10);
  168. //生成地牢房间
  169. _dungeonGenerator = new DungeonGenerator(CurrConfig);
  170. _dungeonGenerator.Generate();
  171. yield return 0;
  172. //填充地牢
  173. _autoTileConfig = new AutoTileConfig();
  174. _dungeonTileMap = new DungeonTileMap(World.TileRoot);
  175. _dungeonTileMap.AutoFillRoomTile(_autoTileConfig, _dungeonGenerator.StartRoomInfo, _dungeonGenerator.Random);
  176. yield return 0;
  177. //生成寻路网格, 这一步操作只生成过道的导航
  178. _dungeonTileMap.GenerateNavigationPolygon(GameConfig.AisleFloorMapLayer);
  179. yield return 0;
  180. //挂载过道导航区域
  181. _dungeonTileMap.MountNavigationPolygon(World.TileRoot);
  182. yield return 0;
  183. //过道导航区域数据
  184. _roomStaticNavigationList = new List<NavigationPolygonData>();
  185. _roomStaticNavigationList.AddRange(_dungeonTileMap.GetPolygonData());
  186. yield return 0;
  187. //门导航区域数据
  188. _roomStaticNavigationList.AddRange(_dungeonTileMap.GetConnectDoorPolygonData());
  189. yield return new WaitForFixedProcess(10);
  190. //初始化所有房间
  191. _dungeonGenerator.EachRoom(InitRoom);
  192. yield return new WaitForFixedProcess(10);
  193.  
  194. //播放bgm
  195. //SoundManager.PlayMusic(ResourcePath.resource_sound_bgm_Intro_ogg, -17f);
  196.  
  197. //初始房间创建玩家标记
  198. var playerBirthMark = StartRoomInfo.RoomPreinstall.GetPlayerBirthMark();
  199. //创建玩家
  200. var player = ActivityObject.Create<Player>(ActivityObject.Ids.Id_role0001);
  201. if (playerBirthMark != null)
  202. {
  203. //player.Position = new Vector2(50, 50);
  204. player.Position = playerBirthMark.Position;
  205. }
  206. player.Name = "Player";
  207. player.PutDown(RoomLayerEnum.YSortLayer);
  208. Player.SetCurrentPlayer(player);
  209. //地牢加载即将完成
  210. _dungeonGenerator.EachRoom(info => info.OnReady());
  211.  
  212. //玩家手上添加武器
  213. //player.PickUpWeapon(ActivityObject.Create<Weapon>(ActivityObject.Ids.Id_weapon0001));
  214. // var weapon = ActivityObject.Create<Weapon>(ActivityObject.Ids.Id_weapon0001);
  215. // weapon.PutDown(player.Position, RoomLayerEnum.NormalLayer);
  216. // var weapon2 = ActivityObject.Create<Weapon>(ActivityObject.Ids.Id_weapon0002);
  217. // weapon2.PutDown(player.Position, RoomLayerEnum.NormalLayer);
  218. // var weapon3 = ActivityObject.Create<Weapon>(ActivityObject.Ids.Id_weapon0003);
  219. // weapon3.PutDown(player.Position, RoomLayerEnum.NormalLayer);
  220. // var weapon4 = ActivityObject.Create<Weapon>(ActivityObject.Ids.Id_weapon0004);
  221. // weapon4.PutDown(player.Position, RoomLayerEnum.NormalLayer);
  222.  
  223. GameApplication.Instance.Cursor.SetGuiMode(false);
  224. yield return 0;
  225. //打开游戏中的ui
  226. UiManager.Open_RoomUI();
  227. //派发进入地牢事件
  228. EventManager.EmitEvent(EventEnum.OnEnterDungeon);
  229. IsInDungeon = true;
  230. QueueRedraw();
  231. yield return 0;
  232. //关闭 loading UI
  233. UiManager.Destroy_Loading();
  234. if (finish != null)
  235. {
  236. finish();
  237. }
  238. }
  239.  
  240. private IEnumerator RunExitDungeonCoroutine(Action finish)
  241. {
  242. //打开 loading UI
  243. UiManager.Open_Loading();
  244. yield return 0;
  245. World.Pause = true;
  246. yield return 0;
  247. _dungeonGenerator.EachRoom(DisposeRoomInfo);
  248. yield return 0;
  249. _dungeonTileMap = null;
  250. _autoTileConfig = null;
  251. _dungeonGenerator = null;
  252. _roomStaticNavigationList.Clear();
  253. _roomStaticNavigationList = null;
  254. UiManager.Hide_RoomUI();
  255. yield return new WaitForFixedProcess(10);
  256. Player.SetCurrentPlayer(null);
  257. World = null;
  258. GameApplication.Instance.DestroyWorld();
  259. yield return new WaitForFixedProcess(10);
  260. QueueRedraw();
  261. //鼠标还原
  262. GameApplication.Instance.Cursor.SetGuiMode(true);
  263. //派发退出地牢事件
  264. EventManager.EmitEvent(EventEnum.OnExitDungeon);
  265. yield return 0;
  266. //关闭 loading UI
  267. UiManager.Destroy_Loading();
  268. if (finish != null)
  269. {
  270. finish();
  271. }
  272. }
  273. // 初始化房间
  274. private void InitRoom(RoomInfo roomInfo)
  275. {
  276. //挂载房间导航区域
  277. MountNavFromRoomInfo(roomInfo);
  278. //创建门
  279. CreateDoor(roomInfo);
  280. //创建房间归属区域
  281. CreateRoomAffiliation(roomInfo);
  282. //创建静态精灵画布
  283. CreateRoomStaticSpriteCanvas(roomInfo);
  284. }
  285. //挂载房间导航区域
  286. private void MountNavFromRoomInfo(RoomInfo roomInfo)
  287. {
  288. var polygonArray = roomInfo.RoomSplit.TileInfo.NavigationList;
  289. var polygon = new NavigationPolygon();
  290. var offset = roomInfo.GetOffsetPosition();
  291. for (var i = 0; i < polygonArray.Count; i++)
  292. {
  293. var navigationPolygonData = polygonArray[i];
  294. var tempPosArray = navigationPolygonData.GetPoints();
  295. var polygonPointArray = new Vector2[tempPosArray.Length];
  296. //这里的位置需要加上房间位置
  297. for (var j = 0; j < tempPosArray.Length; j++)
  298. {
  299. polygonPointArray[j] = tempPosArray[j] + roomInfo.GetWorldPosition() - offset;
  300. }
  301. polygon.AddOutline(polygonPointArray);
  302.  
  303. //存入汇总列表
  304. var polygonData = new NavigationPolygonData(navigationPolygonData.Type);
  305. polygonData.SetPoints(polygonPointArray);
  306. _roomStaticNavigationList.Add(polygonData);
  307. }
  308. polygon.MakePolygonsFromOutlines();
  309. var navigationPolygon = new NavigationRegion2D();
  310. navigationPolygon.Name = "NavigationRegion" + (GetChildCount() + 1);
  311. navigationPolygon.NavigationPolygon = polygon;
  312. World.TileRoot.AddChild(navigationPolygon);
  313. }
  314.  
  315. //创建门
  316. private void CreateDoor(RoomInfo roomInfo)
  317. {
  318. foreach (var doorInfo in roomInfo.Doors)
  319. {
  320. RoomDoor door;
  321. switch (doorInfo.Direction)
  322. {
  323. case DoorDirection.E:
  324. door = ActivityObject.Create<RoomDoor>(ActivityObject.Ids.Id_other_door_e);
  325. door.Position = (doorInfo.OriginPosition + new Vector2(0.5f, 2)) * GameConfig.TileCellSize;
  326. door.ZIndex = GameConfig.TopMapLayer;
  327. break;
  328. case DoorDirection.W:
  329. door = ActivityObject.Create<RoomDoor>(ActivityObject.Ids.Id_other_door_w);
  330. door.Position = (doorInfo.OriginPosition + new Vector2(-0.5f, 2)) * GameConfig.TileCellSize;
  331. door.ZIndex = GameConfig.TopMapLayer;
  332. break;
  333. case DoorDirection.S:
  334. door = ActivityObject.Create<RoomDoor>(ActivityObject.Ids.Id_other_door_s);
  335. door.Position = (doorInfo.OriginPosition + new Vector2(2f, 1.5f)) * GameConfig.TileCellSize;
  336. door.ZIndex = GameConfig.TopMapLayer;
  337. break;
  338. case DoorDirection.N:
  339. door = ActivityObject.Create<RoomDoor>(ActivityObject.Ids.Id_other_door_n);
  340. door.Position = (doorInfo.OriginPosition + new Vector2(2f, -0.5f)) * GameConfig.TileCellSize;
  341. door.ZIndex = GameConfig.MiddleMapLayer;
  342. break;
  343. default:
  344. return;
  345. }
  346. doorInfo.Door = door;
  347. door.Init(doorInfo);
  348. door.PutDown(RoomLayerEnum.NormalLayer, false);
  349. }
  350. }
  351.  
  352. //创建房间归属区域
  353. private void CreateRoomAffiliation(RoomInfo roomInfo)
  354. {
  355. var affiliation = new AffiliationArea();
  356. affiliation.Name = "AffiliationArea" + roomInfo.Id;
  357. affiliation.Init(roomInfo, new Rect2(
  358. roomInfo.GetWorldPosition() + new Vector2(GameConfig.TileCellSize, GameConfig.TileCellSize),
  359. (roomInfo.Size - new Vector2I(2, 2)) * GameConfig.TileCellSize));
  360. roomInfo.AffiliationArea = affiliation;
  361. World.AffiliationAreaRoot.AddChild(affiliation);
  362. }
  363.  
  364. //创建静态精灵画布
  365. private void CreateRoomStaticSpriteCanvas(RoomInfo roomInfo)
  366. {
  367. var worldPos = roomInfo.GetWorldPosition();
  368. var pos = new Vector2I((int)worldPos.X, (int)worldPos.Y);
  369. int minX = pos.X;
  370. int minY = pos.Y;
  371. int maxX = minX + roomInfo.GetWidth();
  372. int maxY = minY + roomInfo.GetHeight();
  373.  
  374. //遍历每一个连接的门, 计算计算canvas覆盖范围
  375. foreach (var doorInfo in roomInfo.Doors)
  376. {
  377. var connectDoor = doorInfo.ConnectDoor;
  378. switch (connectDoor.Direction)
  379. {
  380. case DoorDirection.E:
  381. case DoorDirection.W:
  382. {
  383. var (px1, py1) = connectDoor.GetWorldOriginPosition();
  384. var py2 = py1 + 4 * GameConfig.TileCellSize;
  385. if (px1 < minX)
  386. {
  387. minX = px1;
  388. }
  389. else if (px1 > maxX)
  390. {
  391. maxX = px1;
  392. }
  393.  
  394. if (py1 < minY)
  395. {
  396. minY = py1;
  397. }
  398. else if (py1 > maxY)
  399. {
  400. maxY = py1;
  401. }
  402. if (py2 < minY)
  403. {
  404. minY = py2;
  405. }
  406. else if (py2 > maxY)
  407. {
  408. maxY = py2;
  409. }
  410. }
  411. break;
  412. case DoorDirection.S:
  413. case DoorDirection.N:
  414. {
  415. var (px1, py1) = connectDoor.GetWorldOriginPosition();
  416. var px2 = px1 + 4 * GameConfig.TileCellSize;
  417. if (px1 < minX)
  418. {
  419. minX = px1;
  420. }
  421. else if (px1 > maxX)
  422. {
  423. maxX = px1;
  424. }
  425.  
  426. if (py1 < minY)
  427. {
  428. minY = py1;
  429. }
  430. else if (py1 > maxY)
  431. {
  432. maxY = py1;
  433. }
  434. if (px2 < minX)
  435. {
  436. minX = px2;
  437. }
  438. else if (px2 > maxX)
  439. {
  440. maxX = px2;
  441. }
  442. }
  443. break;
  444. }
  445. }
  446.  
  447. minX -= GameConfig.TileCellSize;
  448. minY -= GameConfig.TileCellSize;
  449. maxX += GameConfig.TileCellSize;
  450. maxY += GameConfig.TileCellSize;
  451. var staticSpriteCanvas = new RoomStaticImageCanvas(
  452. World.StaticSpriteRoot,
  453. new Vector2I(minX, minY),
  454. maxX - minX, maxY - minY
  455. );
  456. staticSpriteCanvas.RoomOffset = new Vector2I(worldPos.X - minX, worldPos.Y - minY);
  457. roomInfo.StaticImageCanvas = staticSpriteCanvas;
  458. }
  459.  
  460. /// <summary>
  461. /// 玩家第一次进入某个房间回调
  462. /// </summary>
  463. private void OnPlayerFirstEnterRoom(object o)
  464. {
  465. var room = (RoomInfo)o;
  466. room.OnFirstEnter();
  467. //如果关门了, 那么房间外的敌人就会丢失目标
  468. if (room.IsSeclusion)
  469. {
  470. var playerAffiliationArea = Player.Current.AffiliationArea;
  471. foreach (var enemy in World.Enemy_InstanceList)
  472. {
  473. //不与玩家处于同一个房间
  474. if (enemy.AffiliationArea != playerAffiliationArea)
  475. {
  476. if (enemy.StateController.CurrState != AiStateEnum.AiNormal)
  477. {
  478. enemy.StateController.ChangeState(AiStateEnum.AiNormal);
  479. }
  480. }
  481. }
  482. }
  483. }
  484.  
  485. /// <summary>
  486. /// 玩家进入某个房间回调
  487. /// </summary>
  488. private void OnPlayerEnterRoom(object o)
  489. {
  490. }
  491. /// <summary>
  492. /// 检测当前房间敌人是否已经消灭干净, 应当每秒执行一次
  493. /// </summary>
  494. private void OnCheckEnemy()
  495. {
  496. var activeRoom = ActiveRoomInfo;
  497. if (activeRoom != null)
  498. {
  499. if (activeRoom.RoomPreinstall.IsRunWave) //正在生成标记
  500. {
  501. if (activeRoom.RoomPreinstall.IsCurrWaveOver()) //所有标记执行完成
  502. {
  503. //房间内是否有存活的敌人
  504. var flag = ActiveAffiliationArea.ExistEnterItem(
  505. activityObject => activityObject.CollisionWithMask(PhysicsLayer.Enemy)
  506. );
  507. //GD.Print("当前房间存活数量: " + count);
  508. if (!flag)
  509. {
  510. activeRoom.OnClearRoom();
  511. }
  512. }
  513. }
  514. }
  515. }
  516.  
  517. /// <summary>
  518. /// 更新敌人视野
  519. /// </summary>
  520. private void UpdateEnemiesView()
  521. {
  522. World.Enemy_IsFindTarget = false;
  523. World.Enemy_FindTargetAffiliationSet.Clear();
  524. for (var i = 0; i < World.Enemy_InstanceList.Count; i++)
  525. {
  526. var enemy = World.Enemy_InstanceList[i];
  527. var state = enemy.StateController.CurrState;
  528. if (state == AiStateEnum.AiFollowUp || state == AiStateEnum.AiSurround) //目标在视野内
  529. {
  530. if (!World.Enemy_IsFindTarget)
  531. {
  532. World.Enemy_IsFindTarget = true;
  533. World.Enemy_FindTargetPosition = Player.Current.GetCenterPosition();
  534. World.Enemy_FindTargetAffiliationSet.Add(Player.Current.AffiliationArea);
  535. }
  536. World.Enemy_FindTargetAffiliationSet.Add(enemy.AffiliationArea);
  537. }
  538. }
  539. }
  540.  
  541. private void DisposeRoomInfo(RoomInfo roomInfo)
  542. {
  543. roomInfo.Destroy();
  544. }
  545. public override void _Draw()
  546. {
  547. if (GameApplication.Instance.Debug)
  548. {
  549. if (_dungeonTileMap != null)
  550. {
  551. //绘制ai寻路区域
  552. Utils.DrawNavigationPolygon(this, _roomStaticNavigationList.ToArray());
  553. }
  554. //绘制房间区域
  555. // if (_dungeonGenerator != null)
  556. // {
  557. // DrawRoomInfo(StartRoom);
  558. // }
  559. //绘制边缘线
  560. }
  561. }
  562. //绘制房间区域, debug 用
  563. private void DrawRoomInfo(RoomInfo roomInfo)
  564. {
  565. var cellSize = World.TileRoot.CellQuadrantSize;
  566. var pos1 = (roomInfo.Position + roomInfo.Size / 2) * cellSize;
  567. //绘制下一个房间
  568. foreach (var nextRoom in roomInfo.Next)
  569. {
  570. var pos2 = (nextRoom.Position + nextRoom.Size / 2) * cellSize;
  571. DrawLine(pos1, pos2, Colors.Red);
  572. DrawRoomInfo(nextRoom);
  573. }
  574.  
  575. DrawString(ResourceManager.DefaultFont16Px, pos1 - new Vector2I(0, 10), "Id: " + roomInfo.Id.ToString());
  576. DrawString(ResourceManager.DefaultFont16Px, pos1 + new Vector2I(0, 10), "Layer: " + roomInfo.Layer.ToString());
  577.  
  578. //绘制门
  579. foreach (var roomDoor in roomInfo.Doors)
  580. {
  581. var originPos = roomDoor.OriginPosition * cellSize;
  582. switch (roomDoor.Direction)
  583. {
  584. case DoorDirection.E:
  585. DrawLine(originPos, originPos + new Vector2(3, 0) * cellSize, Colors.Yellow);
  586. DrawLine(originPos + new Vector2(0, 4) * cellSize, originPos + new Vector2(3, 4) * cellSize,
  587. Colors.Yellow);
  588. break;
  589. case DoorDirection.W:
  590. DrawLine(originPos, originPos - new Vector2(3, 0) * cellSize, Colors.Yellow);
  591. DrawLine(originPos + new Vector2(0, 4) * cellSize, originPos - new Vector2(3, -4) * cellSize,
  592. Colors.Yellow);
  593. break;
  594. case DoorDirection.S:
  595. DrawLine(originPos, originPos + new Vector2(0, 3) * cellSize, Colors.Yellow);
  596. DrawLine(originPos + new Vector2(4, 0) * cellSize, originPos + new Vector2(4, 3) * cellSize,
  597. Colors.Yellow);
  598. break;
  599. case DoorDirection.N:
  600. DrawLine(originPos, originPos - new Vector2(0, 3) * cellSize, Colors.Yellow);
  601. DrawLine(originPos + new Vector2(4, 0) * cellSize, originPos - new Vector2(-4, 3) * cellSize,
  602. Colors.Yellow);
  603. break;
  604. }
  605. //绘制房间区域
  606. DrawRect(new Rect2(roomInfo.Position * cellSize, roomInfo.Size * cellSize), Colors.Blue, false);
  607.  
  608. if (roomDoor.HasCross && roomDoor.RoomInfo.Id < roomDoor.ConnectRoom.Id)
  609. {
  610. DrawRect(new Rect2(roomDoor.Cross * cellSize, new Vector2(cellSize * 4, cellSize * 4)), Colors.Yellow, false);
  611. }
  612. }
  613. }
  614. /// <summary>
  615. /// 将房间类型枚举转为字符串
  616. /// </summary>
  617. public static string DungeonRoomTypeToString(DungeonRoomType roomType)
  618. {
  619. switch (roomType)
  620. {
  621. case DungeonRoomType.Battle: return "battle";
  622. case DungeonRoomType.Inlet: return "inlet";
  623. case DungeonRoomType.Outlet: return "outlet";
  624. case DungeonRoomType.Boss: return "boss";
  625. case DungeonRoomType.Reward: return "reward";
  626. case DungeonRoomType.Shop: return "shop";
  627. case DungeonRoomType.Event: return "event";
  628. }
  629.  
  630. return "battle";
  631. }
  632. /// <summary>
  633. /// 将房间类型枚举转为描述字符串
  634. /// </summary>
  635. public static string DungeonRoomTypeToDescribeString(DungeonRoomType roomType)
  636. {
  637. switch (roomType)
  638. {
  639. case DungeonRoomType.Battle: return "战斗房间";
  640. case DungeonRoomType.Inlet: return "起始房间";
  641. case DungeonRoomType.Outlet: return "结束房间";
  642. case DungeonRoomType.Boss: return "Boss房间";
  643. case DungeonRoomType.Reward: return "奖励房间";
  644. case DungeonRoomType.Shop: return "商店房间";
  645. case DungeonRoomType.Event: return "事件房间";
  646. }
  647.  
  648. return "战斗房间";
  649. }
  650.  
  651. /// <summary>
  652. /// 检测地牢是否可以执行生成
  653. /// </summary>
  654. /// <param name="groupName">组名称</param>
  655. public static DungeonCheckState CheckDungeon(string groupName)
  656. {
  657. if (GameApplication.Instance.RoomConfig.TryGetValue(groupName, out var group))
  658. {
  659. //验证该组是否满足生成地牢的条件
  660. if (group.InletList.Count == 0)
  661. {
  662. return new DungeonCheckState(true, "当没有可用的起始房间!");
  663. }
  664. else if (group.OutletList.Count == 0)
  665. {
  666. return new DungeonCheckState(true, "没有可用的结束房间!");
  667. }
  668. else if (group.BattleList.Count == 0)
  669. {
  670. return new DungeonCheckState(true, "没有可用的战斗房间!");
  671. }
  672.  
  673. return new DungeonCheckState(false, null);
  674. }
  675.  
  676. return new DungeonCheckState(true, "未找到地牢组");
  677. }
  678. }