Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / room / DefaultDungeonRule.cs
@小李xl 小李xl on 17 Feb 2024 7 KB 2格高墙壁, 开发中
  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. foreach (var temp in rewardBindRoom)
  47. {
  48. if (!excludePrevRoom.Contains(temp))
  49. {
  50. excludePrevRoom.Add(temp);
  51. }
  52. }
  53.  
  54. return Generator.FindMaxLayerRoom(DungeonRoomType.Battle | DungeonRoomType.Shop | DungeonRoomType.Event, excludePrevRoom);
  55. }
  56. else if (nextRoomType == DungeonRoomType.Battle)
  57. {
  58. if (battleTryCount < battleMaxTryCount)
  59. {
  60. if (prevRoom == null || prevRoom.Layer >= Config.MaxLayer - 1) //层数太高, 下一个房间生成在低层级
  61. {
  62. return Generator.RandomRoomLessThanLayer(DungeonRoomType.Battle | DungeonRoomType.Shop | DungeonRoomType.Event | DungeonRoomType.Inlet, Mathf.Max(1, Config.MaxLayer / 2));
  63. }
  64.  
  65. return prevRoom;
  66. }
  67. return Generator.GetRandomRoom(DungeonRoomType.Battle | DungeonRoomType.Shop | DungeonRoomType.Event | DungeonRoomType.Inlet);
  68. }
  69. return Generator.GetRandomRoom(DungeonRoomType.None);
  70. }
  71.  
  72. public override DungeonRoomType GetNextRoomType(RoomInfo prevRoom)
  73. {
  74. if (Generator.StartRoomInfo == null) //生成第一个房间
  75. {
  76. return DungeonRoomType.Inlet;
  77. }
  78.  
  79. if (prevRoom != null)
  80. {
  81. if (prevRoom.RoomType == DungeonRoomType.Boss) //boss房间后生成结束房间
  82. {
  83. return DungeonRoomType.Outlet;
  84. }
  85.  
  86. if (Generator.RewardRoomInfos.Count < Config.RewardRoomCount)
  87. {
  88. if (Generator.BattleRoomInfos.Count == Config.BattleRoomCount / (Config.RewardRoomCount + 1) * (Generator.RewardRoomInfos.Count + 1)) //奖励房间
  89. {
  90. return DungeonRoomType.Reward;
  91. }
  92. }
  93. if (Generator.ShopRoomInfos.Count < Config.ShopRoomCount)
  94. {
  95. if (Generator.BattleRoomInfos.Count == Config.BattleRoomCount / (Config.ShopRoomCount + 1) * (Generator.ShopRoomInfos.Count + 1)) //商店
  96. {
  97. return DungeonRoomType.Shop;
  98. }
  99. }
  100. }
  101.  
  102. if (Generator.BattleRoomInfos.Count >= Config.BattleRoomCount) //战斗房间已满
  103. {
  104. if (Generator.BossRoomInfos.Count < Config.BossRoomCount) //最后一个房间是boss房间
  105. {
  106. if (RoomGroup.BossList.Count == 0) //没有预设boss房间
  107. {
  108. return DungeonRoomType.Battle;
  109. }
  110. //生成boss房间
  111. return DungeonRoomType.Boss;
  112. }
  113. }
  114. return DungeonRoomType.Battle;
  115. }
  116.  
  117. public override void GenerateRoomSuccess(RoomInfo prevRoom, RoomInfo roomInfo)
  118. {
  119. if (roomInfo.RoomType == DungeonRoomType.Boss) //boss房间
  120. {
  121. roomInfo.CanRollback = true;
  122. excludePrevRoom.Clear();
  123. }
  124. else if (roomInfo.RoomType == DungeonRoomType.Battle)
  125. {
  126. battleTryCount = 0;
  127. battleMaxTryCount = Random.RandomRangeInt(1, 3);
  128. }
  129. else if (roomInfo.RoomType == DungeonRoomType.Outlet)
  130. {
  131. outletTryCount = 0;
  132. Generator.SubmitCanRollbackRoom();
  133. }
  134. else if (roomInfo.RoomType == DungeonRoomType.Reward)
  135. {
  136. rewardBindRoom.Add(prevRoom);
  137. excludePrevRoom.Clear();
  138. }
  139.  
  140. if (prevRoom != null && prevRoom.CanRollback)
  141. {
  142. roomInfo.CanRollback = true;
  143. }
  144. }
  145.  
  146. public override void GenerateRoomFail(RoomInfo prevRoom, DungeonRoomType roomType)
  147. {
  148. if (roomType == DungeonRoomType.Boss || roomType == DungeonRoomType.Reward)
  149. {
  150. //生成房间失败
  151. excludePrevRoom.Add(prevRoom);
  152. if (excludePrevRoom.Count >= Generator.RoomInfos.Count)
  153. {
  154. //全都没找到合适的, 那就再来一遍
  155. excludePrevRoom.Clear();
  156. }
  157. }
  158. else if (roomType == DungeonRoomType.Outlet)
  159. {
  160. outletTryCount++;
  161. if (outletTryCount >= 3 && prevRoom != null) //生成结束房间失败, 那么只能回滚boss房间
  162. {
  163. outletTryCount = 0;
  164. Generator.RollbackRoom(prevRoom);
  165. }
  166. }
  167. else if (roomType == DungeonRoomType.Battle)
  168. {
  169. battleTryCount++;
  170. }
  171. }
  172.  
  173. public override RoomDirection GetNextRoomDoorDirection(RoomInfo prevRoom, DungeonRoomType roomType)
  174. {
  175. return Random.RandomChoose(_roomDirections);
  176. }
  177.  
  178. public override int GetNextRoomInterval(RoomInfo prevRoom, DungeonRoomType roomType, RoomDirection direction)
  179. {
  180. return Random.RandomRangeInt(Config.RoomMinInterval, Config.RoomMaxInterval);
  181. }
  182.  
  183. public override int GetNextRoomOffset(RoomInfo prevRoom, DungeonRoomType roomType, RoomDirection direction)
  184. {
  185. //为什么最后的值要减4或者5? 因为这个值是房间地板向外扩充的格子数量
  186. if (roomType == DungeonRoomType.Outlet)
  187. {
  188. if (direction == RoomDirection.Up || direction == RoomDirection.Down)
  189. {
  190. return (int)(prevRoom.Size.X * 0.5f - 4);
  191. }
  192. return (int)(prevRoom.Size.Y * 0.5f - 5);
  193. }
  194. if (direction == RoomDirection.Up || direction == RoomDirection.Down)
  195. {
  196. return Random.RandomRangeInt((int)(prevRoom.Size.X * Config.RoomVerticalMinDispersion),
  197. (int)(prevRoom.Size.X * Config.RoomVerticalMaxDispersion)) + (int)(prevRoom.Size.X * 0.5f - 4);
  198. }
  199. return Random.RandomRangeInt((int)(prevRoom.Size.Y * Config.RoomHorizontalMinDispersion),
  200. (int)(prevRoom.Size.Y * Config.RoomHorizontalMaxDispersion)) + (int)(prevRoom.Size.Y * 0.5f - 5);
  201. }
  202. }