WeaponInfo.ts 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  1. import { _decorator, Component, Node } from 'cc';
  2. import { WeaponConfig } from '../../Core/ConfigManager';
  3. const { ccclass, property } = _decorator;
  4. /**
  5. * 武器信息组件
  6. * 用于存储和管理挂载到武器节点上的武器配置信息
  7. */
  8. @ccclass('WeaponInfo')
  9. export class WeaponInfo extends Component {
  10. // 编辑器面板可见属性
  11. @property({ displayName: "武器ID", readonly: true })
  12. public weaponId: string = "";
  13. @property({ displayName: "武器名称", readonly: true })
  14. public weaponName: string = "";
  15. @property({ displayName: "武器等级", readonly: true })
  16. public weaponLevel: number = 1;
  17. @property({ displayName: "武器伤害", readonly: true })
  18. public weaponDamage: number = 0;
  19. @property({ displayName: "射速", readonly: true })
  20. public fireRate: number = 0;
  21. @property({ displayName: "射程", readonly: true })
  22. public range: number = 0;
  23. @property({ displayName: "是否激活", readonly: true })
  24. public activeStatus: boolean = false;
  25. @property({ displayName: "总伤害", readonly: true })
  26. public totalDamage: number = 0;
  27. @property({ displayName: "击杀数", readonly: true })
  28. public killCount: number = 0;
  29. @property({ displayName: "剩余冷却时间(秒)", readonly: true })
  30. public remainingCooldown: number = 0;
  31. // 武器配置数据
  32. private _weaponConfig: WeaponConfig | null = null;
  33. // 武器等级(用于升级系统)
  34. private _weaponLevel: number = 1;
  35. // 武器是否已激活(用于战斗状态管理)
  36. private _isActive: boolean = false;
  37. // 武器最后开火时间(用于冷却计算)
  38. private _lastFireTime: number = 0;
  39. // 武器当前弹药数(如果适用)
  40. private _currentAmmo: number = -1; // -1表示无限弹药
  41. // 武器累计伤害统计
  42. private _totalDamageDealt: number = 0;
  43. // 武器击杀数统计
  44. private _killCount: number = 0;
  45. /**
  46. * 设置武器配置
  47. * @param config 武器配置数据
  48. */
  49. public setWeaponConfig(config: WeaponConfig): void {
  50. this._weaponConfig = config;
  51. this._weaponLevel = 1;
  52. this._isActive = true;
  53. this._lastFireTime = 0;
  54. this._totalDamageDealt = 0;
  55. this._killCount = 0;
  56. // 更新编辑器面板可见属性
  57. this.weaponId = config.id;
  58. this.weaponName = config.name;
  59. this.weaponLevel = this._weaponLevel;
  60. this.weaponDamage = this.getDamage();
  61. this.fireRate = config.stats.fireRate;
  62. this.range = config.stats.range;
  63. this.activeStatus = this._isActive;
  64. this.totalDamage = this._totalDamageDealt;
  65. this.killCount = this._killCount;
  66. this.remainingCooldown = 0;
  67. // 如果武器配置中有弹药限制,设置初始弹药数
  68. if (config.bulletConfig && config.bulletConfig.count) {
  69. // 这里可以根据具体需求设置弹药数,目前设为无限
  70. this._currentAmmo = -1;
  71. }
  72. // 武器配置已设置
  73. }
  74. /**
  75. * 获取武器配置
  76. * @returns 武器配置数据
  77. */
  78. public getWeaponConfig(): WeaponConfig | null {
  79. return this._weaponConfig;
  80. }
  81. /**
  82. * 获取武器ID
  83. * @returns 武器ID
  84. */
  85. public getWeaponId(): string | null {
  86. return this._weaponConfig ? this._weaponConfig.id : null;
  87. }
  88. /**
  89. * 获取武器名称
  90. * @returns 武器名称
  91. */
  92. public getWeaponName(): string | null {
  93. return this._weaponConfig ? this._weaponConfig.name : null;
  94. }
  95. /**
  96. * 获取武器类型
  97. * @returns 武器类型
  98. */
  99. public getWeaponType(): string | null {
  100. return this._weaponConfig ? this._weaponConfig.type : null;
  101. }
  102. /**
  103. * 获取武器稀有度
  104. * @returns 武器稀有度
  105. */
  106. public getWeaponRarity(): string | null {
  107. return this._weaponConfig ? (this._weaponConfig.rarity || 'common') : null;
  108. }
  109. /**
  110. * 设置武器等级
  111. * @param level 武器等级
  112. */
  113. public setWeaponLevel(level: number): void {
  114. if (level < 1) {
  115. console.warn(`[WeaponInfo] 武器等级不能小于1,当前设置: ${level}`);
  116. return;
  117. }
  118. const maxLevel = this._weaponConfig?.upgradeConfig?.maxLevel || 10;
  119. if (level > maxLevel) {
  120. console.warn(`[WeaponInfo] 武器等级不能超过最大等级 ${maxLevel},当前设置: ${level}`);
  121. return;
  122. }
  123. this._weaponLevel = level;
  124. // 更新编辑器面板可见属性
  125. this.weaponLevel = this._weaponLevel;
  126. this.weaponDamage = this.getDamage();
  127. // 武器等级已设置
  128. }
  129. /**
  130. * 获取武器等级
  131. * @returns 武器等级
  132. */
  133. public getWeaponLevel(): number {
  134. return this._weaponLevel;
  135. }
  136. /**
  137. * 获取武器最大等级
  138. * @returns 武器最大等级
  139. */
  140. public getMaxWeaponLevel(): number {
  141. return this._weaponConfig?.upgradeConfig?.maxLevel || 10;
  142. }
  143. /**
  144. * 设置武器激活状态
  145. * @param active 是否激活
  146. */
  147. public setActive(active: boolean): void {
  148. this._isActive = active;
  149. // 更新编辑器面板可见属性
  150. this.activeStatus = this._isActive;
  151. // 武器激活状态已设置
  152. }
  153. /**
  154. * 获取武器激活状态
  155. * @returns 是否激活
  156. */
  157. public isActive(): boolean {
  158. return this._isActive;
  159. }
  160. /**
  161. * 检查武器是否可以开火(基于冷却时间)
  162. * @returns 是否可以开火
  163. */
  164. public canFire(): boolean {
  165. if (!this._isActive || !this._weaponConfig) {
  166. this.remainingCooldown = 0;
  167. return false;
  168. }
  169. const currentTime = Date.now() / 1000; // 转换为秒
  170. const fireRate = this._weaponConfig.stats.fireRate || 1.0;
  171. const cooldown = 1.0 / fireRate; // 计算冷却时间
  172. const timeSinceLastFire = currentTime - this._lastFireTime;
  173. // 更新剩余冷却时间
  174. this.remainingCooldown = Math.max(0, cooldown - timeSinceLastFire);
  175. return timeSinceLastFire >= cooldown;
  176. }
  177. /**
  178. * 记录开火时间
  179. */
  180. public recordFireTime(): void {
  181. this._lastFireTime = Date.now() / 1000;
  182. // 开火后立即设置冷却时间
  183. if (this._weaponConfig) {
  184. const fireRate = this._weaponConfig.stats.fireRate || 1.0;
  185. this.remainingCooldown = 1.0 / fireRate;
  186. }
  187. }
  188. /**
  189. * 获取武器伤害值(考虑等级加成)
  190. * @returns 武器伤害值
  191. */
  192. public getDamage(): number {
  193. if (!this._weaponConfig) {
  194. return 0;
  195. }
  196. if (this._weaponLevel === 0) {
  197. return 0; // 未解锁武器伤害为0
  198. }
  199. // 优先从武器配置的upgradeConfig中获取伤害值
  200. if (this._weaponConfig.upgradeConfig && this._weaponConfig.upgradeConfig.levels) {
  201. const levelConfig = this._weaponConfig.upgradeConfig.levels[this._weaponLevel.toString()];
  202. if (levelConfig && typeof levelConfig.damage === 'number') {
  203. return levelConfig.damage;
  204. }
  205. }
  206. // 如果upgradeConfig中没有伤害值,使用基础伤害 + 等级加成作为后备
  207. const baseDamage = this._weaponConfig.stats.damage || 0;
  208. return baseDamage + (this._weaponLevel - 1);
  209. }
  210. /**
  211. * 获取武器射程
  212. * @returns 武器射程
  213. */
  214. public getRange(): number {
  215. return this._weaponConfig?.stats.range || 0;
  216. }
  217. /**
  218. * 获取武器射速
  219. * @returns 武器射速
  220. */
  221. public getFireRate(): number {
  222. return this._weaponConfig?.stats.fireRate || 1.0;
  223. }
  224. /**
  225. * 获取子弹速度
  226. * @returns 子弹速度
  227. */
  228. public getBulletSpeed(): number {
  229. return this._weaponConfig?.stats.bulletSpeed || 100;
  230. }
  231. /**
  232. * 获取武器精度
  233. * @returns 武器精度
  234. */
  235. public getAccuracy(): number {
  236. return this._weaponConfig?.stats.accuracy || 1.0;
  237. }
  238. /**
  239. * 获取当前剩余冷却时间
  240. * @returns 剩余冷却时间(秒)
  241. */
  242. public getRemainingCooldown(): number {
  243. if (!this._isActive || !this._weaponConfig) {
  244. return 0;
  245. }
  246. const currentTime = Date.now() / 1000;
  247. const fireRate = this._weaponConfig.stats.fireRate || 1.0;
  248. const cooldown = 1.0 / fireRate;
  249. const timeSinceLastFire = currentTime - this._lastFireTime;
  250. const remaining = Math.max(0, cooldown - timeSinceLastFire);
  251. this.remainingCooldown = remaining; // 同时更新编辑器属性
  252. return remaining;
  253. }
  254. /**
  255. * 添加伤害统计
  256. * @param damage 造成的伤害
  257. */
  258. public addDamageDealt(damage: number): void {
  259. this._totalDamageDealt += damage;
  260. // 更新编辑器面板可见属性
  261. this.totalDamage = this._totalDamageDealt;
  262. // 累计伤害已更新
  263. }
  264. /**
  265. * 获取总伤害统计
  266. * @returns 总伤害
  267. */
  268. public getTotalDamageDealt(): number {
  269. return this._totalDamageDealt;
  270. }
  271. /**
  272. * 增加击杀数
  273. */
  274. public addKill(): void {
  275. this._killCount++;
  276. // 更新编辑器面板可见属性
  277. this.killCount = this._killCount;
  278. // 击杀数已更新
  279. }
  280. /**
  281. * 获取击杀数
  282. * @returns 击杀数
  283. */
  284. public getKillCount(): number {
  285. return this._killCount;
  286. }
  287. /**
  288. * 重置统计数据
  289. */
  290. public resetStats(): void {
  291. this._totalDamageDealt = 0;
  292. this._killCount = 0;
  293. this._lastFireTime = 0;
  294. // 更新编辑器面板可见属性
  295. this.totalDamage = this._totalDamageDealt;
  296. this.killCount = this._killCount;
  297. this.remainingCooldown = 0;
  298. // 武器统计数据已重置
  299. }
  300. /**
  301. * 获取武器升级所需费用
  302. * @param targetLevel 目标等级
  303. * @returns 升级费用,如果无法升级返回-1
  304. */
  305. public getUpgradeCost(targetLevel?: number): number {
  306. if (!this._weaponConfig || !this._weaponConfig.upgradeConfig) {
  307. return -1;
  308. }
  309. const level = targetLevel || (this._weaponLevel + 1);
  310. const levelConfig = this._weaponConfig.upgradeConfig.levels?.[level.toString()];
  311. return levelConfig?.cost || -1;
  312. }
  313. /**
  314. * 检查是否可以升级
  315. * @returns 是否可以升级
  316. */
  317. public canUpgrade(): boolean {
  318. if (!this._weaponConfig || !this._weaponConfig.upgradeConfig) {
  319. return false;
  320. }
  321. const maxLevel = this._weaponConfig.upgradeConfig.maxLevel || 10;
  322. return this._weaponLevel < maxLevel;
  323. }
  324. /**
  325. * 升级武器
  326. * @returns 是否升级成功
  327. */
  328. public upgrade(): boolean {
  329. if (!this.canUpgrade()) {
  330. return false;
  331. }
  332. this._weaponLevel++;
  333. // 更新编辑器面板可见属性
  334. this.weaponLevel = this._weaponLevel;
  335. this.weaponDamage = this.getDamage();
  336. // 武器升级完成
  337. return true;
  338. }
  339. /**
  340. * 更新所有编辑器面板可见属性
  341. * 用于确保编辑器中显示的信息与内部状态同步
  342. */
  343. private updateEditorProperties(): void {
  344. if (this._weaponConfig) {
  345. this.weaponId = this._weaponConfig.id;
  346. this.weaponName = this._weaponConfig.name;
  347. this.fireRate = this._weaponConfig.stats.fireRate;
  348. this.range = this._weaponConfig.stats.range;
  349. }
  350. this.weaponLevel = this._weaponLevel;
  351. this.weaponDamage = this.getDamage();
  352. this.activeStatus = this._isActive;
  353. this.totalDamage = this._totalDamageDealt;
  354. this.killCount = this._killCount;
  355. // 更新剩余冷却时间
  356. if (this._weaponConfig && this._isActive) {
  357. const currentTime = Date.now() / 1000;
  358. const fireRate = this._weaponConfig.stats.fireRate || 1.0;
  359. const cooldown = 1.0 / fireRate;
  360. const timeSinceLastFire = currentTime - this._lastFireTime;
  361. this.remainingCooldown = Math.max(0, cooldown - timeSinceLastFire);
  362. } else {
  363. this.remainingCooldown = 0;
  364. }
  365. }
  366. /**
  367. * 获取武器信息摘要
  368. * @returns 武器信息字符串
  369. */
  370. public getWeaponSummary(): string {
  371. if (!this._weaponConfig) {
  372. return '无武器配置';
  373. }
  374. return `${this._weaponConfig.name} (Lv.${this._weaponLevel}) - 伤害:${this.getDamage()} 射速:${this.getFireRate()} 射程:${this.getRange()}`;
  375. }
  376. /**
  377. * 组件销毁时清理
  378. */
  379. onDestroy(): void {
  380. this._weaponConfig = null;
  381. }
  382. }