diff --git a/assets/script/game/map/MissionHeroComp.ts b/assets/script/game/map/MissionHeroComp.ts index 5125d659..1e2b59eb 100644 --- a/assets/script/game/map/MissionHeroComp.ts +++ b/assets/script/game/map/MissionHeroComp.ts @@ -58,34 +58,22 @@ export class MissionHeroCompComp extends CCComp { } private async call_hero(event: string, args: any){ + if (this.is_merging) return; const uuid = Number(args?.uuid ?? 1001); const hero_lv = Math.max(1, Number(args?.hero_lv ?? 1)); + this.addHero(uuid, hero_lv); const aliveHeroes = this.getAliveHeroes(); - const mergeHeroes = this.pickMergeHeroes(aliveHeroes, uuid, hero_lv); - if (mergeHeroes.length === 2) { - if (this.is_merging) return; + const mergeHeroes = this.pickMergeHeroes(aliveHeroes, uuid, hero_lv, 3); + if (mergeHeroes.length === 3) { this.is_merging = true; try { - let sumAp = 0; - let sumHpMax = 0; - for (let i = 0; i < mergeHeroes.length; i++) { - const model = mergeHeroes[i].get(HeroAttrsComp); - if (!model) continue; - sumAp += model.ap; - sumHpMax += model.hp_max; - } - let hero_pos = 0; - const landingPos:Vec3 = HeroPos[hero_pos].pos; - const spawnPos:Vec3 = v3(landingPos.x, landingPos.y + MissionHeroCompComp.HERO_DROP_HEIGHT, 0); - await this.mergeDestroyAtBirth(mergeHeroes, spawnPos); - await this.playMergeBoomFx(spawnPos); - this.addMergedHero(uuid, hero_lv + 1, sumAp, sumHpMax); + const mergedLv = await this.mergeGroupHeroes(mergeHeroes, uuid, hero_lv); + await this.tryChainMerge(uuid, mergedLv); } finally { this.is_merging = false; } return; } - this.addHero(uuid, hero_lv); } /** 添加英雄 */ private addHero(uuid:number=1001,hero_lv:number=1) { @@ -99,14 +87,15 @@ export class MissionHeroCompComp extends CCComp { return hero; } - private addMergedHero(uuid:number, hero_lv:number, ap:number, hp_max:number) { + private addMergedHero(uuid:number, hero_lv:number, ap:number, hp_max:number): number { const hero = this.addHero(uuid, hero_lv); const model = hero.get(HeroAttrsComp); - if (!model) return; + if (!model) return hero_lv; model.ap = Math.max(0, ap); model.hp_max = Math.max(1, hp_max); model.hp = model.hp_max; model.dirty_hp = true; + return model.lv; } private getAliveHeroes(): Hero[] { @@ -121,7 +110,7 @@ export class MissionHeroCompComp extends CCComp { return heroes; } - private pickMergeHeroes(aliveHeroes: Hero[], uuid: number, hero_lv: number): Hero[] { + private pickMergeHeroes(aliveHeroes: Hero[], uuid: number, hero_lv: number, needCount: number = 3): Hero[] { const mergeHeroes: Hero[] = []; for (let i = 0; i < aliveHeroes.length; i++) { const model = aliveHeroes[i].get(HeroAttrsComp); @@ -129,11 +118,23 @@ export class MissionHeroCompComp extends CCComp { if (model.hero_uuid !== uuid) continue; if (model.lv !== hero_lv) continue; mergeHeroes.push(aliveHeroes[i]); - if (mergeHeroes.length === 2) break; + if (mergeHeroes.length === needCount) break; } return mergeHeroes; } + private countMergeHeroes(aliveHeroes: Hero[], uuid: number, hero_lv: number): number { + let count = 0; + for (let i = 0; i < aliveHeroes.length; i++) { + const model = aliveHeroes[i].get(HeroAttrsComp); + if (!model) continue; + if (model.hero_uuid !== uuid) continue; + if (model.lv !== hero_lv) continue; + count += 1; + } + return count; + } + private mergeDestroyAtBirth(mergeHeroes: Hero[], spawnPos: Vec3): Promise { return new Promise((resolve) => { let doneCount = 0; @@ -179,6 +180,41 @@ export class MissionHeroCompComp extends CCComp { }); } + private async mergeGroupHeroes(mergeHeroes: Hero[], uuid: number, hero_lv: number): Promise { + let sumAp = 0; + let sumHpMax = 0; + for (let i = 0; i < mergeHeroes.length; i++) { + const model = mergeHeroes[i].get(HeroAttrsComp); + if (!model) continue; + sumAp += model.ap; + sumHpMax += model.hp_max; + } + let hero_pos = 0; + const landingPos:Vec3 = HeroPos[hero_pos].pos; + const spawnPos:Vec3 = v3(landingPos.x, landingPos.y + MissionHeroCompComp.HERO_DROP_HEIGHT, 0); + await this.mergeDestroyAtBirth(mergeHeroes, spawnPos); + await this.playMergeBoomFx(spawnPos); + return this.addMergedHero(uuid, hero_lv + 1, sumAp, sumHpMax); + } + + private async tryChainMerge(uuid: number, startLv: number) { + let checkLv = Math.max(1, startLv); + let guard = 0; + while (guard < 20) { + guard += 1; + const aliveHeroes = this.getAliveHeroes(); + const sameCount = this.countMergeHeroes(aliveHeroes, uuid, checkLv); + if (sameCount < 3) { + break; + } + const mergeHeroes = this.pickMergeHeroes(aliveHeroes, uuid, checkLv, 3); + if (mergeHeroes.length < 3) { + break; + } + checkLv = await this.mergeGroupHeroes(mergeHeroes, uuid, checkLv); + } + } +