import { _decorator, Component, Vec3 } from 'cc'; import { BattleDataManager } from '../BattleDataManager'; import { MonsterType } from '../../../manager/MonsterDataManager'; import { Monster } from '../Monster'; const { ccclass } = _decorator; /** * 雷电球:按 index 左 / 右 / 下 平移(速度取武器表 speed),在持续时间内按间隔 * 以当前位置为圆心对范围内怪物直接扣血(无母体特殊技能链,与 ColaMucus 等区域 tick 一致用 subHP)。 */ @ccclass('ThunderboltSchedule') export class ThunderboltSchedule extends Component { _dt: number = 0; _weaponid: number = 0; /** 分裂配置伤害比例:damageRate/10000,乘在 allAtk 上再 subHP */ _atkScale: number = 1; _addBuffInterval: number = 1; _repeatCount: number = 1; _bombPos: Vec3 = null; _damageRadius: number = 0; curRepeatCount: number = 0; _continueTime: number = 0; _continueTimeDt: number = 0; /** 发射方块的俄罗斯方块等级,参与 getWeaponAddProperty */ _tetriLevel: number = 1; /** 世界空间移动方向(单位向量) */ private _dirX: number = 0; private _dirY: number = 0; private _speed: number = 0; update(deltaTime: number): void { const battle = gg.game?.CurentBattle; // if (!battle?.canUpdateFrame?.()) return; const dt = deltaTime * battle.TimeScale; if (this._speed > 0 && (this._dirX !== 0 || this._dirY !== 0)) { const w = this.node.worldPosition; this.node.setWorldPosition( w.x + this._dirX * this._speed * dt, w.y + this._dirY * this._speed * dt, w.z, ); } this._dt += dt; this._continueTimeDt += dt; if (this._continueTimeDt >= this._continueTime) { this.removeSelf(); return; } if (this._dt < this._addBuffInterval) return; this._dt = 0; this.curRepeatCount++; const bombMonsters = battle.MonsterSpawner.getMonstersInArea(this.node.worldPosition, this._damageRadius); for (let i = 0; i < bombMonsters.length; i++) { const monster = bombMonsters[i]; const monsterComp = monster.getComponent(Monster); if (!monsterComp || monsterComp.IsDead) continue; const allBuff = monsterComp.getAllBuff(); const wp = BattleDataManager.getWeaponAddProperty(this._weaponid, allBuff, this._tetriLevel); let dmg = wp.allAtk * this._atkScale; if (monsterComp.Data && monsterComp.Data.type == MonsterType.TreasureBox) { dmg *= 1 + gg.game.CurentBattle.fubenBoxAddDamage / 10000; } monsterComp.subHP(this._weaponid, dmg, wp.isCrit, wp.addRateAtk); } } resetThunderboltSchedule( bombPos: Vec3, damageRadius: number, damageTimes: number, weaponid: number, damageInterval: number, repeatCount: number, continueT: number, tetriLevel: number = 1, splitMoveIndex: number = 0, moveSpeed: number = 300, ): void { this._dt = 0; this._continueTimeDt = 0; this.curRepeatCount = 0; this._addBuffInterval = 0.1//Math.max(0.05, damageInterval); this._repeatCount = Math.max(1, repeatCount); this._weaponid = weaponid; const scale = typeof damageTimes === 'number' && Number.isFinite(damageTimes) && damageTimes > 0 ? damageTimes : 1; this._atkScale = scale; this._bombPos = bombPos; this._damageRadius = damageRadius; this._continueTime = Math.max(this._addBuffInterval, continueT); this._tetriLevel = tetriLevel > 0 ? tetriLevel : 1; this._speed = Math.max(0, moveSpeed); const idx = Math.abs(Math.floor(splitMoveIndex)) % 3; if (idx === 0) { this._dirX = -1; this._dirY = 0; } else if (idx === 1) { this._dirX = 1; this._dirY = 0; } else { this._dirX = 0; this._dirY = -1; } if (this.node?.isValid && bombPos) { this.node.worldPosition = bombPos.clone(); } } removeSelf(): void { const n = this.node; if (this.isValid) { this.destroy(); } if (n?.isValid) { gg.res.putNode(n); } } onDestroy(): void { // noop } }