Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / manager / FireManager.cs
  1.  
  2. using Config;
  3. using Godot;
  4.  
  5. public static class FireManager
  6. {
  7. /// <summary>
  8. /// 投抛弹壳的默认实现方式, shellId为弹壳id
  9. /// </summary>
  10. public static ActivityObject ThrowShell(Weapon weapon, ExcelConfig.ActivityBase shell, float speedScale = 1)
  11. {
  12. var startPos = weapon.ShellPoint.GlobalPosition;
  13. float startHeight;
  14. var master = weapon.Master;
  15. if (master != null)
  16. {
  17. var shellPosition = master.MountPoint.Position + weapon.ShellPoint.Position;
  18. startHeight = -shellPosition.Y;
  19. startPos.Y += startHeight;
  20. }
  21. else
  22. {
  23. startHeight = weapon.Altitude;
  24. }
  25.  
  26. var direction = weapon.GlobalRotationDegrees + Utils.Random.RandomRangeInt(-30, 30) + 180;
  27. var verticalSpeed = Utils.Random.RandomRangeInt((int)(60 * speedScale), (int)(120 * speedScale));
  28. var velocity = new Vector2(Utils.Random.RandomRangeInt((int)(20 * speedScale), (int)(60 * speedScale)), 0).Rotated(direction * Mathf.Pi / 180);
  29. var rotate = Utils.Random.RandomRangeInt((int)(-720 * speedScale), (int)(720 * speedScale));
  30. var shellInstance = ActivityObject.Create(shell);
  31. shellInstance.Rotation = (master != null ? master.MountPoint.RealRotation : weapon.Rotation);
  32. shellInstance.Throw(startPos, startHeight, verticalSpeed, velocity, rotate);
  33. shellInstance.InheritVelocity(master != null ? master : weapon);
  34. if (master == null)
  35. {
  36. weapon.AffiliationArea.InsertItem(shellInstance);
  37. }
  38. else
  39. {
  40. master.AffiliationArea.InsertItem(shellInstance);
  41. }
  42. return shellInstance;
  43. }
  44.  
  45. /// <summary>
  46. /// 根据武器创建 BulletData
  47. /// </summary>
  48. public static BulletData GetBulletData(Weapon weapon, float fireRotation, ExcelConfig.BulletBase bullet)
  49. {
  50. if (bullet.Type == 1) //实体子弹
  51. {
  52. return CreateSolidBulletData(weapon, fireRotation, bullet);
  53. }
  54. else if (bullet.Type == 2) //激光子弹
  55. {
  56. return CreateLaserData(weapon, fireRotation, bullet);
  57. }
  58. else
  59. {
  60. Debug.LogError("暂未支持的子弹类型: " + bullet.Type);
  61. }
  62.  
  63. return null;
  64. }
  65. /// <summary>
  66. /// 根据角色创建 BulletData
  67. /// </summary>
  68. public static BulletData GetBulletData(Role trigger, float fireRotation, ExcelConfig.BulletBase bullet)
  69. {
  70. if (bullet.Type == 1) //实体子弹
  71. {
  72. return CreateSolidBulletData(trigger, fireRotation, bullet);
  73. }
  74.  
  75. return null;
  76. }
  77.  
  78. /// <summary>
  79. /// 计算进行抛物线运动的子弹击中目标所需要的速度等数据, 并设置
  80. /// </summary>
  81. public static void SetParabolaTarget(BulletData bulletData, Vector2 targetPosition)
  82. {
  83. var distance = bulletData.Position.DistanceTo(targetPosition);
  84. var height = bulletData.Altitude;
  85. var time = distance / bulletData.FlySpeed;
  86. bulletData.VerticalSpeed = -(height - 0.5f * GameConfig.G * time * time) / time;
  87. bulletData.Rotation = bulletData.Position.AngleToPoint(targetPosition);
  88. }
  89.  
  90. /// <summary>
  91. /// 通过武器发射子弹
  92. /// </summary>
  93. public static IBullet ShootBullet(Weapon weapon, float fireRotation, ExcelConfig.BulletBase bullet)
  94. {
  95. if (bullet.Type == 1) //实体子弹
  96. {
  97. return ShootSolidBullet(CreateSolidBulletData(weapon, fireRotation, bullet),
  98. weapon.TriggerRole != null ? weapon.TriggerRole.Camp : CampEnum.None);
  99. }
  100. else if (bullet.Type == 2) //激光子弹
  101. {
  102. return ShootLaser(CreateLaserData(weapon, fireRotation, bullet),
  103. weapon.TriggerRole != null ? weapon.TriggerRole.Camp : CampEnum.None);
  104. }
  105. else
  106. {
  107. Debug.LogError("暂未支持的子弹类型: " + bullet.Type);
  108. }
  109.  
  110. return null;
  111. }
  112.  
  113. /// <summary>
  114. /// 通 Role 对象直接发射子弹
  115. /// </summary>
  116. public static IBullet ShootBullet(Role trigger, float fireRotation, ExcelConfig.BulletBase bullet)
  117. {
  118. if (bullet.Type == 1) //实体子弹
  119. {
  120. return ShootSolidBullet(CreateSolidBulletData(trigger, fireRotation, bullet), trigger.Camp);
  121. }
  122.  
  123. return null;
  124. }
  125.  
  126. /// <summary>
  127. /// 通过 BulletData 直接发射子弹
  128. /// </summary>
  129. public static IBullet ShootBullet(BulletData bulletData, CampEnum camp)
  130. {
  131. if (bulletData.BulletBase.Type == 1) //实体子弹
  132. {
  133. return ShootSolidBullet(bulletData, camp);
  134. }
  135. else if (bulletData.BulletBase.Type == 2) //激光子弹
  136. {
  137. return ShootLaser(bulletData, camp);
  138. }
  139. else
  140. {
  141. Debug.LogError("暂未支持的子弹类型: " + bulletData.BulletBase.Type);
  142. }
  143.  
  144. return null;
  145. }
  146.  
  147. /// <summary>
  148. /// 发射子弹的默认实现方式
  149. /// </summary>
  150. private static Bullet ShootSolidBullet(BulletData bulletData, CampEnum camp)
  151. {
  152. //创建子弹
  153. var bulletInstance = ObjectManager.GetBullet(bulletData.BulletBase.Prefab);
  154. bulletInstance.InitData(bulletData, camp);
  155. return bulletInstance;
  156. }
  157.  
  158. /// <summary>
  159. /// 发射射线的默认实现方式
  160. /// </summary>
  161. private static Laser ShootLaser(BulletData bulletData, CampEnum camp)
  162. {
  163. //创建激光
  164. var laser = ObjectManager.GetLaser(bulletData.BulletBase.Prefab);
  165. laser.AddToActivityRoot(RoomLayerEnum.YSortLayer);
  166. laser.InitData(bulletData, camp, Laser.LaserDefaultWidth);
  167. return laser;
  168. }
  169. //-----------------------------------------------------------------------------------
  170.  
  171. private static BulletData CreateSolidBulletData(Weapon weapon, float fireRotation, ExcelConfig.BulletBase bullet)
  172. {
  173. var data = new BulletData(weapon.World)
  174. {
  175. Weapon = weapon,
  176. BulletBase = bullet,
  177. TriggerRole = weapon.TriggerRole,
  178. Harm = Utils.Random.RandomConfigRange(bullet.HarmRange),
  179. Repel = Utils.Random.RandomConfigRange(bullet.RepelRange),
  180. MaxDistance = Utils.Random.RandomConfigRange(bullet.DistanceRange),
  181. FlySpeed = Utils.Random.RandomConfigRange(bullet.SpeedRange),
  182. VerticalSpeed = Utils.Random.RandomConfigRange(bullet.VerticalSpeed),
  183. BounceCount = Utils.Random.RandomConfigRange(bullet.BounceCount),
  184. Penetration = Utils.Random.RandomConfigRange(bullet.Penetration),
  185. Position = weapon.FirePoint.GlobalPosition,
  186. };
  187. var deviationAngle = Utils.Random.RandomConfigRange(bullet.DeviationAngleRange);
  188. if (weapon.TriggerRole != null)
  189. {
  190. data.Altitude = weapon.TriggerRole.GetFirePointAltitude();
  191. var roleState = weapon.TriggerRole.RoleState;
  192. data.Harm = roleState.CalcDamage(data.Harm);
  193. data.Repel = roleState.CalcBulletRepel(data.Repel);
  194. data.FlySpeed = roleState.CalcBulletSpeed(data.FlySpeed);
  195. data.MaxDistance = roleState.CalcBulletDistance(data.MaxDistance);
  196. data.BounceCount = roleState.CalcBulletBounceCount(data.BounceCount);
  197. data.Penetration = roleState.CalcBulletPenetration(data.Penetration);
  198. deviationAngle = roleState.CalcBulletDeviationAngle(deviationAngle);
  199. if (weapon.TriggerRole.IsAi) //只有玩家使用该武器才能获得正常速度的子弹
  200. {
  201. data.FlySpeed *= weapon.AiUseAttribute.AiAttackAttr.BulletSpeedScale;
  202. }
  203. }
  204. else
  205. {
  206. data.Altitude = 1;
  207. }
  208.  
  209. data.Rotation = fireRotation + Mathf.DegToRad(deviationAngle);
  210. return data;
  211. }
  212. private static BulletData CreateSolidBulletData(Role role, float fireRotation, ExcelConfig.BulletBase bullet)
  213. {
  214. var data = new BulletData(role.World)
  215. {
  216. Weapon = null,
  217. BulletBase = bullet,
  218. TriggerRole = role,
  219. Harm = Utils.Random.RandomConfigRange(bullet.HarmRange),
  220. Repel = Utils.Random.RandomConfigRange(bullet.RepelRange),
  221. MaxDistance = Utils.Random.RandomConfigRange(bullet.DistanceRange),
  222. FlySpeed = Utils.Random.RandomConfigRange(bullet.SpeedRange),
  223. VerticalSpeed = Utils.Random.RandomConfigRange(bullet.VerticalSpeed),
  224. BounceCount = Utils.Random.RandomConfigRange(bullet.BounceCount),
  225. Penetration = Utils.Random.RandomConfigRange(bullet.Penetration),
  226. };
  227.  
  228. if (role is Enemy enemy)
  229. {
  230. data.Position = enemy.FirePoint.GlobalPosition;
  231. }
  232. else
  233. {
  234. data.Position = role.MountPoint.GlobalPosition;
  235. }
  236.  
  237. var deviationAngle = Utils.Random.RandomConfigRange(bullet.DeviationAngleRange);
  238. data.Altitude = role.GetFirePointAltitude();
  239. var roleState = role.RoleState;
  240. data.Harm = roleState.CalcDamage(data.Harm);
  241. data.Repel = roleState.CalcBulletRepel(data.Repel);
  242. data.FlySpeed = roleState.CalcBulletSpeed(data.FlySpeed);
  243. data.MaxDistance = roleState.CalcBulletDistance(data.MaxDistance);
  244. data.BounceCount = roleState.CalcBulletBounceCount(data.BounceCount);
  245. data.Penetration = roleState.CalcBulletPenetration(data.Penetration);
  246. deviationAngle = roleState.CalcBulletDeviationAngle(deviationAngle);
  247. // if (role.IsAi) //只有玩家使用该武器才能获得正常速度的子弹
  248. // {
  249. // data.FlySpeed *= weapon.AiUseAttribute.AiAttackAttr.BulletSpeedScale;
  250. // }
  251.  
  252. data.Rotation = fireRotation + Mathf.DegToRad(deviationAngle);
  253. return data;
  254. }
  255.  
  256. private static BulletData CreateLaserData(Weapon weapon, float fireRotation, ExcelConfig.BulletBase bullet)
  257. {
  258. var data = new BulletData(weapon.World)
  259. {
  260. Weapon = weapon,
  261. BulletBase = bullet,
  262. TriggerRole = weapon.TriggerRole,
  263. Harm = Utils.Random.RandomConfigRange(bullet.HarmRange),
  264. Repel = Utils.Random.RandomConfigRange(bullet.RepelRange),
  265. MaxDistance = Utils.Random.RandomConfigRange(bullet.DistanceRange),
  266. BounceCount = Utils.Random.RandomConfigRange(bullet.BounceCount),
  267. LifeTime = Utils.Random.RandomConfigRange(bullet.LifeTimeRange),
  268. Position = weapon.FirePoint.GlobalPosition,
  269. FlySpeed = Utils.Random.RandomConfigRange(bullet.SpeedRange),
  270. };
  271.  
  272. var deviationAngle = Utils.Random.RandomConfigRange(bullet.DeviationAngleRange);
  273. if (weapon.TriggerRole != null)
  274. {
  275. data.Altitude = weapon.TriggerRole.GetFirePointAltitude();
  276. var roleState = weapon.TriggerRole.RoleState;
  277. data.Harm = roleState.CalcDamage(data.Harm);
  278. data.Repel = roleState.CalcBulletRepel(data.Repel);
  279. data.BounceCount = roleState.CalcBulletBounceCount(data.BounceCount);
  280. deviationAngle = roleState.CalcBulletDeviationAngle(deviationAngle);
  281. }
  282. else
  283. {
  284. data.Altitude = 1;
  285. }
  286.  
  287. data.Rotation = fireRotation + Mathf.DegToRad(deviationAngle);
  288. return data;
  289. }
  290. }