Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / room / DefaultDungeonRule.cs
  1.  
  2. using System.Collections.Generic;
  3. using Godot;
  4.  
  5. /// <summary>
  6. /// 默认实现地牢房间规则
  7. /// </summary>
  8. public class DefaultDungeonRule : DungeonRule
  9. {
  10. //用于排除上一级房间
  11. private List<RoomInfo> excludePrevRoom = new List<RoomInfo>();
  12. //战斗房间尝试链接次数
  13. private int battleTryCount = 0;
  14. private int battleMaxTryCount = 3;
  15.  
  16. //结束房间尝试链接次数
  17. private int outletTryCount = 0;
  18. //奖励房间绑定的上一个房间
  19. private List<RoomInfo> rewardBindRoom = new List<RoomInfo>();
  20. private readonly RoomDirection[] _roomDirections = new []{ RoomDirection.Up, RoomDirection.Down, RoomDirection.Left, RoomDirection.Right };
  21. public DefaultDungeonRule(DungeonGenerator generator) : base(generator)
  22. {
  23. }
  24.  
  25. public override bool CanOverGenerator()
  26. {
  27. return Generator.BattleRoomInfos.Count >= Config.BattleRoomCount && Generator.EndRoomInfos.Count >= Config.OutRoomCount;
  28. }
  29.  
  30. public override RoomInfo GetConnectPrevRoom(RoomInfo prevRoom, DungeonRoomType nextRoomType)
  31. {
  32. if (nextRoomType == DungeonRoomType.Inlet)
  33. {
  34. return null;
  35. }
  36. else if (nextRoomType == DungeonRoomType.Boss)
  37. {
  38. return Generator.FindMaxLayerRoom(DungeonRoomType.Battle | DungeonRoomType.Shop, excludePrevRoom);
  39. }
  40. else if (nextRoomType == DungeonRoomType.Outlet || nextRoomType == DungeonRoomType.Shop || nextRoomType == DungeonRoomType.Event)
  41. {
  42. return prevRoom;
  43. }
  44. else if (nextRoomType == DungeonRoomType.Reward)
  45. {
  46. if (Generator.BattleRoomInfos.Count == 0)
  47. {
  48. return prevRoom;
  49. }
  50. foreach (var temp in rewardBindRoom)
  51. {
  52. if (!excludePrevRoom.Contains(temp))
  53. {
  54. excludePrevRoom.Add(temp);
  55. }
  56. }
  57.  
  58. return Generator.FindMaxLayerRoom(DungeonRoomType.Battle | DungeonRoomType.Shop | DungeonRoomType.Event, excludePrevRoom);
  59. }
  60. else if (nextRoomType == DungeonRoomType.Battle)
  61. {
  62. if (battleTryCount < battleMaxTryCount)
  63. {
  64. if (prevRoom == null || prevRoom.Layer >= Config.MaxLayer - 1) //层数太高, 下一个房间生成在低层级
  65. {
  66. return Generator.RandomRoomLessThanLayer(DungeonRoomType.Battle | DungeonRoomType.Shop | DungeonRoomType.Event | DungeonRoomType.Inlet, Mathf.Max(1, Config.MaxLayer / 2));
  67. }
  68.  
  69. return prevRoom;
  70. }
  71. return Generator.GetRandomRoom(DungeonRoomType.Battle | DungeonRoomType.Shop | DungeonRoomType.Event | DungeonRoomType.Inlet);
  72. }
  73. return Generator.GetRandomRoom(DungeonRoomType.None);
  74. }
  75.  
  76. public override DungeonRoomType GetNextRoomType(RoomInfo prevRoom)
  77. {
  78. if (Generator.StartRoomInfo == null) //生成第一个房间
  79. {
  80. return DungeonRoomType.Inlet;
  81. }
  82.  
  83. if (prevRoom != null)
  84. {
  85. if (prevRoom.RoomType == DungeonRoomType.Boss) //boss房间后生成结束房间
  86. {
  87. return DungeonRoomType.Outlet;
  88. }
  89.  
  90. if (Generator.RewardRoomInfos.Count < Config.RewardRoomCount)
  91. {
  92. if (Generator.BattleRoomInfos.Count == Config.BattleRoomCount / (Config.RewardRoomCount + 1) * (Generator.RewardRoomInfos.Count + 1)) //奖励房间
  93. {
  94. return DungeonRoomType.Reward;
  95. }
  96. }
  97. if (Generator.ShopRoomInfos.Count < Config.ShopRoomCount)
  98. {
  99. if (Generator.BattleRoomInfos.Count == Config.BattleRoomCount / (Config.ShopRoomCount + 1) * (Generator.ShopRoomInfos.Count + 1)) //商店
  100. {
  101. return DungeonRoomType.Shop;
  102. }
  103. }
  104. }
  105.  
  106. if (Generator.BattleRoomInfos.Count >= Config.BattleRoomCount) //战斗房间已满
  107. {
  108. if (Generator.BossRoomInfos.Count < Config.BossRoomCount) //最后一个房间是boss房间
  109. {
  110. if (RoomGroup.BossList.Count == 0) //没有预设boss房间
  111. {
  112. return DungeonRoomType.Battle;
  113. }
  114. //生成boss房间
  115. return DungeonRoomType.Boss;
  116. }
  117. }
  118. return DungeonRoomType.Battle;
  119. }
  120.  
  121. public override void GenerateRoomSuccess(RoomInfo prevRoom, RoomInfo roomInfo)
  122. {
  123. if (roomInfo.RoomType == DungeonRoomType.Boss) //boss房间
  124. {
  125. roomInfo.CanRollback = true;
  126. excludePrevRoom.Clear();
  127. }
  128. else if (roomInfo.RoomType == DungeonRoomType.Battle)
  129. {
  130. battleTryCount = 0;
  131. battleMaxTryCount = Random.RandomRangeInt(1, 3);
  132. }
  133. else if (roomInfo.RoomType == DungeonRoomType.Outlet)
  134. {
  135. outletTryCount = 0;
  136. Generator.SubmitCanRollbackRoom();
  137. }
  138. else if (roomInfo.RoomType == DungeonRoomType.Reward)
  139. {
  140. rewardBindRoom.Add(prevRoom);
  141. excludePrevRoom.Clear();
  142. }
  143.  
  144. if (prevRoom != null && prevRoom.CanRollback)
  145. {
  146. roomInfo.CanRollback = true;
  147. }
  148. }
  149.  
  150. public override void GenerateRoomFail(RoomInfo prevRoom, DungeonRoomType roomType)
  151. {
  152. if (roomType == DungeonRoomType.Boss || roomType == DungeonRoomType.Reward)
  153. {
  154. //生成房间失败
  155. excludePrevRoom.Add(prevRoom);
  156. if (excludePrevRoom.Count >= Generator.RoomInfos.Count)
  157. {
  158. //全都没找到合适的, 那就再来一遍
  159. excludePrevRoom.Clear();
  160. }
  161. }
  162. else if (roomType == DungeonRoomType.Outlet)
  163. {
  164. outletTryCount++;
  165. if (outletTryCount >= 3 && prevRoom != null) //生成结束房间失败, 那么只能回滚boss房间
  166. {
  167. outletTryCount = 0;
  168. Generator.RollbackRoom(prevRoom);
  169. }
  170. }
  171. else if (roomType == DungeonRoomType.Battle)
  172. {
  173. battleTryCount++;
  174. }
  175. }
  176.  
  177. public override RoomDirection GetNextRoomDoorDirection(RoomInfo prevRoom, DungeonRoomType roomType)
  178. {
  179. return Random.RandomChoose(_roomDirections);
  180. }
  181.  
  182. public override int GetNextRoomInterval(RoomInfo prevRoom, DungeonRoomType roomType, RoomDirection direction)
  183. {
  184. return Random.RandomRangeInt(Config.RoomMinInterval, Config.RoomMaxInterval);
  185. }
  186.  
  187. public override int GetNextRoomOffset(RoomInfo prevRoom, DungeonRoomType roomType, RoomDirection direction)
  188. {
  189. //为什么最后的值要减4或者5? 因为这个值是房间地板向外扩充的格子数量
  190. if (roomType == DungeonRoomType.Outlet)
  191. {
  192. if (direction == RoomDirection.Up || direction == RoomDirection.Down)
  193. {
  194. return (int)(prevRoom.Size.X * 0.5f - 4);
  195. }
  196. return (int)(prevRoom.Size.Y * 0.5f - 5);
  197. }
  198. if (direction == RoomDirection.Up || direction == RoomDirection.Down)
  199. {
  200. return Random.RandomRangeInt((int)(prevRoom.Size.X * Config.RoomVerticalMinDispersion),
  201. (int)(prevRoom.Size.X * Config.RoomVerticalMaxDispersion)) + (int)(prevRoom.Size.X * 0.5f - 4);
  202. }
  203. return Random.RandomRangeInt((int)(prevRoom.Size.Y * Config.RoomHorizontalMinDispersion),
  204. (int)(prevRoom.Size.Y * Config.RoomHorizontalMaxDispersion)) + (int)(prevRoom.Size.Y * 0.5f - 5);
  205. }
  206. }