mirror of
				https://github.com/unanmed/HumanBreak.git
				synced 2025-11-04 07:02:58 +08:00 
			
		
		
		
	彻底修正伤害计算
This commit is contained in:
		
							parent
							
								
									061e25e8d1
								
							
						
					
					
						commit
						b9c1142d14
					
				@ -29,6 +29,9 @@ interface EnemyInfo {
 | 
				
			|||||||
    defBuff: number;
 | 
					    defBuff: number;
 | 
				
			||||||
    hpBuff: number;
 | 
					    hpBuff: number;
 | 
				
			||||||
    enemy: Enemy;
 | 
					    enemy: Enemy;
 | 
				
			||||||
 | 
					    x?: number;
 | 
				
			||||||
 | 
					    y?: number;
 | 
				
			||||||
 | 
					    floorId?: FloorIds;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface DamageInfo {
 | 
					interface DamageInfo {
 | 
				
			||||||
@ -71,7 +74,7 @@ interface CriticalDamageDelta extends Omit<DamageDelta, 'info'> {
 | 
				
			|||||||
type HaloFn = (info: EnemyInfo, enemy: Enemy) => void;
 | 
					type HaloFn = (info: EnemyInfo, enemy: Enemy) => void;
 | 
				
			||||||
type DamageDir = Dir | 'none';
 | 
					type DamageDir = Dir | 'none';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const haloSpecials: number[] = [21, 25, 26, 27];
 | 
					export const haloSpecials: number[] = [8, 21, 25, 26, 27];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class EnemyCollection implements RangeCollection<DamageEnemy> {
 | 
					export class EnemyCollection implements RangeCollection<DamageEnemy> {
 | 
				
			||||||
    floorId: FloorIds;
 | 
					    floorId: FloorIds;
 | 
				
			||||||
@ -105,9 +108,17 @@ export class EnemyCollection implements RangeCollection<DamageEnemy> {
 | 
				
			|||||||
     * @param noCache 是否不使用缓存
 | 
					     * @param noCache 是否不使用缓存
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    calRealAttribute(noCache: boolean = false) {
 | 
					    calRealAttribute(noCache: boolean = false) {
 | 
				
			||||||
 | 
					        if (!noCache) return;
 | 
				
			||||||
        this.list.forEach(v => {
 | 
					        this.list.forEach(v => {
 | 
				
			||||||
            if (noCache) v.reset();
 | 
					            v.reset();
 | 
				
			||||||
            v.calRealAttribute();
 | 
					            v.preProvideHalo();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        this.list.forEach(v => {
 | 
				
			||||||
 | 
					            v.calAttribute();
 | 
				
			||||||
 | 
					            v.provideHalo();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        this.list.forEach(v => {
 | 
				
			||||||
 | 
					            v.getRealInfo();
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -116,11 +127,8 @@ export class EnemyCollection implements RangeCollection<DamageEnemy> {
 | 
				
			|||||||
     * @param noCache 是否不使用缓存
 | 
					     * @param noCache 是否不使用缓存
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    calDamage(noCache: boolean = false, onMap: boolean = false) {
 | 
					    calDamage(noCache: boolean = false, onMap: boolean = false) {
 | 
				
			||||||
 | 
					        if (noCache) this.calRealAttribute(noCache);
 | 
				
			||||||
        this.list.forEach(v => {
 | 
					        this.list.forEach(v => {
 | 
				
			||||||
            if (noCache || v.needCalculate) {
 | 
					 | 
				
			||||||
                v.reset();
 | 
					 | 
				
			||||||
                v.calRealAttribute();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            v.calDamage(void 0, onMap);
 | 
					            v.calDamage(void 0, onMap);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -161,13 +169,13 @@ export class EnemyCollection implements RangeCollection<DamageEnemy> {
 | 
				
			|||||||
        if (!recursion) {
 | 
					        if (!recursion) {
 | 
				
			||||||
            arr.forEach(v => {
 | 
					            arr.forEach(v => {
 | 
				
			||||||
                enemy.forEach(e => {
 | 
					                enemy.forEach(e => {
 | 
				
			||||||
                    e.injectHalo(v);
 | 
					                    e.injectHalo(v, e.enemy);
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            enemy.forEach(e => {
 | 
					            enemy.forEach(e => {
 | 
				
			||||||
                arr.forEach(v => {
 | 
					                arr.forEach(v => {
 | 
				
			||||||
                    e.injectHalo(v);
 | 
					                    e.injectHalo(v, e.enemy);
 | 
				
			||||||
                    e.preProvideHalo();
 | 
					                    e.preProvideHalo();
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
@ -333,8 +341,6 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
 | 
				
			|||||||
     * -> provide inject 光环 -> 计算怪物的光环加成 -> 计算完毕
 | 
					     * -> provide inject 光环 -> 计算怪物的光环加成 -> 计算完毕
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    info!: EnemyInfo;
 | 
					    info!: EnemyInfo;
 | 
				
			||||||
    /** 是否需要计算属性 */
 | 
					 | 
				
			||||||
    needCalculate: boolean = true;
 | 
					 | 
				
			||||||
    /** 怪物伤害 */
 | 
					    /** 怪物伤害 */
 | 
				
			||||||
    damage?: DamageInfo[];
 | 
					    damage?: DamageInfo[];
 | 
				
			||||||
    /** 是否需要计算伤害 */
 | 
					    /** 是否需要计算伤害 */
 | 
				
			||||||
@ -376,38 +382,25 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
 | 
				
			|||||||
            atkBuff: 0,
 | 
					            atkBuff: 0,
 | 
				
			||||||
            defBuff: 0,
 | 
					            defBuff: 0,
 | 
				
			||||||
            hpBuff: 0,
 | 
					            hpBuff: 0,
 | 
				
			||||||
            enemy: this.enemy
 | 
					            enemy: this.enemy,
 | 
				
			||||||
 | 
					            x: this.x,
 | 
				
			||||||
 | 
					            y: this.y,
 | 
				
			||||||
 | 
					            floorId: this.floorId
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        this.progress = 0;
 | 
					        this.progress = 0;
 | 
				
			||||||
        this.needCalculate = true;
 | 
					 | 
				
			||||||
        this.needCalDamage = true;
 | 
					        this.needCalDamage = true;
 | 
				
			||||||
 | 
					        this.providedHalo = [];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 计算怪物在不计光环下的属性,在inject光环之前,预平衡光环之后执行
 | 
					     * 计算怪物在不计光环下的属性,在inject光环之前,预平衡光环之后执行
 | 
				
			||||||
     * @param hero 勇士属性
 | 
					 | 
				
			||||||
     * @param getReal 是否获取勇士真实属性,默认获取
 | 
					 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    calAttribute(
 | 
					    calAttribute() {
 | 
				
			||||||
        hero: Partial<HeroStatus> = core.status.hero,
 | 
					 | 
				
			||||||
        getReal: boolean = true
 | 
					 | 
				
			||||||
    ) {
 | 
					 | 
				
			||||||
        if (this.progress !== 1) return;
 | 
					        if (this.progress !== 1) return;
 | 
				
			||||||
        this.progress = 2;
 | 
					        this.progress = 2;
 | 
				
			||||||
        const special = this.info.special;
 | 
					        const special = this.info.special;
 | 
				
			||||||
        const info = this.info;
 | 
					        const info = this.info;
 | 
				
			||||||
        const enemy = this.enemy;
 | 
					 | 
				
			||||||
        const floorId = this.floorId ?? core.status.floorId;
 | 
					        const floorId = this.floorId ?? core.status.floorId;
 | 
				
			||||||
        const { atk } = getReal
 | 
					 | 
				
			||||||
            ? getHeroStatusOf(hero, ['atk'], hero.x, hero.y, hero.floorId)
 | 
					 | 
				
			||||||
            : hero;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (!has(atk)) return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // 饥渴
 | 
					 | 
				
			||||||
        if (special.includes(7)) {
 | 
					 | 
				
			||||||
            info.atk += (atk * (enemy.hungry ?? 0)) / 100;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // 智慧之源
 | 
					        // 智慧之源
 | 
				
			||||||
        if (flags.hard === 2 && special.includes(14)) {
 | 
					        if (flags.hard === 2 && special.includes(14)) {
 | 
				
			||||||
@ -418,11 +411,6 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
 | 
				
			|||||||
        info.atk -= flags[`night_${floorId}`] ?? 0;
 | 
					        info.atk -= flags[`night_${floorId}`] ?? 0;
 | 
				
			||||||
        info.def -= flags[`night_${floorId}`] ?? 0;
 | 
					        info.def -= flags[`night_${floorId}`] ?? 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // 坚固
 | 
					 | 
				
			||||||
        if (special.includes(3) && enemy.def < atk - 1) {
 | 
					 | 
				
			||||||
            info.def = atk - 1;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // 融化,融化不属于怪物光环,因此不能用provide和inject计算,需要在这里计算
 | 
					        // 融化,融化不属于怪物光环,因此不能用provide和inject计算,需要在这里计算
 | 
				
			||||||
        if (has(flags[`melt_${floorId}`]) && has(this.x) && has(this.y)) {
 | 
					        if (has(flags[`melt_${floorId}`]) && has(this.x) && has(this.y)) {
 | 
				
			||||||
            for (const [loc, per] of Object.entries(flags[`melt_${floorId}`])) {
 | 
					            for (const [loc, per] of Object.entries(flags[`melt_${floorId}`])) {
 | 
				
			||||||
@ -439,42 +427,24 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
 | 
				
			|||||||
     * 获取怪物的真实属性信息,在inject光环后执行
 | 
					     * 获取怪物的真实属性信息,在inject光环后执行
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    getRealInfo() {
 | 
					    getRealInfo() {
 | 
				
			||||||
 | 
					        if (this.progress < 3) {
 | 
				
			||||||
 | 
					            throw new Error(
 | 
				
			||||||
 | 
					                `Unexpected early real info calculating. Progress: ${this.progress}`
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        if (this.progress === 4) return this.info;
 | 
					        if (this.progress === 4) return this.info;
 | 
				
			||||||
        if (this.progress <= 3) this.ensureCaled(3);
 | 
					 | 
				
			||||||
        this.progress = 4;
 | 
					        this.progress = 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // 此时已经inject光环,因此直接计算真实属性
 | 
					        // 此时已经inject光环,因此直接计算真实属性
 | 
				
			||||||
        const info = this.info;
 | 
					        const info = this.info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        info.atk = Math.floor(info.atk * (info.atkBuff / 100 + 1));
 | 
					        info.atk = Math.floor(info.atk * (info.atkBuff / 100 + 1));
 | 
				
			||||||
        info.def = Math.floor(info.def * (info.defBuff / 100 + 1));
 | 
					        info.def = Math.floor(info.def * (info.defBuff / 100 + 1));
 | 
				
			||||||
        info.hp = Math.floor(info.hp * (info.hpBuff / 100 + 1));
 | 
					        info.hp = Math.floor(info.hp * (info.hpBuff / 100 + 1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.needCalculate = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return this.info;
 | 
					        return this.info;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * 计算真实属性
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    calRealAttribute() {
 | 
					 | 
				
			||||||
        this.preProvideHalo();
 | 
					 | 
				
			||||||
        this.calAttribute();
 | 
					 | 
				
			||||||
        this.provideHalo();
 | 
					 | 
				
			||||||
        this.getRealInfo();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * 确保怪物属性计算已经到达某个进度
 | 
					 | 
				
			||||||
     * @param progress 期望进度
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    ensureCaled(progress: number) {
 | 
					 | 
				
			||||||
        if (progress >= 1) this.preProvideHalo();
 | 
					 | 
				
			||||||
        if (progress >= 2) this.calAttribute();
 | 
					 | 
				
			||||||
        if (progress >= 3) this.provideHalo();
 | 
					 | 
				
			||||||
        if (progress >= 4) this.getRealInfo();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    getHaloSpecials(): number[] {
 | 
					    getHaloSpecials(): number[] {
 | 
				
			||||||
        if (!this.floorId) return [];
 | 
					        if (!this.floorId) return [];
 | 
				
			||||||
        if (!core.has(this.x) || !core.has(this.y)) return [];
 | 
					        if (!core.has(this.x) || !core.has(this.y)) return [];
 | 
				
			||||||
@ -510,15 +480,17 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
 | 
				
			|||||||
        if (!core.has(this.x) || !core.has(this.y)) return;
 | 
					        if (!core.has(this.x) || !core.has(this.y)) return;
 | 
				
			||||||
        const col = this.col ?? core.status.maps[this.floorId].enemy;
 | 
					        const col = this.col ?? core.status.maps[this.floorId].enemy;
 | 
				
			||||||
        if (!col) return;
 | 
					        if (!col) return;
 | 
				
			||||||
        const speical = this.getHaloSpecials();
 | 
					        const special = this.getHaloSpecials();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const square7: HaloFn[] = [];
 | 
					        const square7: HaloFn[] = [];
 | 
				
			||||||
        const square5: HaloFn[] = [];
 | 
					        const square5: HaloFn[] = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // e 是被加成怪的属性,enemy 是施加光环的怪
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // 抱团
 | 
					        // 抱团
 | 
				
			||||||
        if (speical.includes(8)) {
 | 
					        if (special.includes(8)) {
 | 
				
			||||||
            square5.push((e, enemy) => {
 | 
					            square5.push((e, enemy) => {
 | 
				
			||||||
                if (e.special.includes(8)) {
 | 
					                if (e.special.includes(8) && e.x !== this.x && this.y !== e.y) {
 | 
				
			||||||
                    e.atkBuff += enemy.together ?? 0;
 | 
					                    e.atkBuff += enemy.together ?? 0;
 | 
				
			||||||
                    e.defBuff += enemy.together ?? 0;
 | 
					                    e.defBuff += enemy.together ?? 0;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@ -527,25 +499,25 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // 冰封光环
 | 
					        // 冰封光环
 | 
				
			||||||
        if (speical.includes(21)) {
 | 
					        if (special.includes(21)) {
 | 
				
			||||||
            square7.push((e, enemy) => {
 | 
					            square7.push(e => {
 | 
				
			||||||
                e.damageDecline += enemy.iceDecline ?? 0;
 | 
					                e.damageDecline += this.enemy.iceHalo ?? 0;
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
            this.providedHalo.push(21);
 | 
					            this.providedHalo.push(21);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // 冰封之核
 | 
					        // 冰封之核
 | 
				
			||||||
        if (speical.includes(26)) {
 | 
					        if (special.includes(26)) {
 | 
				
			||||||
            square5.push((e, enemy) => {
 | 
					            square5.push(e => {
 | 
				
			||||||
                e.defBuff += enemy.iceCore ?? 0;
 | 
					                e.defBuff += this.enemy.iceCore ?? 0;
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
            this.providedHalo.push(26);
 | 
					            this.providedHalo.push(26);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // 火焰之核
 | 
					        // 火焰之核
 | 
				
			||||||
        if (speical.includes(27)) {
 | 
					        if (special.includes(27)) {
 | 
				
			||||||
            square5.push((e, enemy) => {
 | 
					            square5.push(e => {
 | 
				
			||||||
                e.atkBuff += enemy.fireCore ?? 0;
 | 
					                e.atkBuff += this.enemy.fireCore ?? 0;
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
            this.providedHalo.push(27);
 | 
					            this.providedHalo.push(27);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -557,8 +529,8 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
 | 
				
			|||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 接受其他怪的光环
 | 
					     * 接受其他怪的光环
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    injectHalo(halo: HaloFn) {
 | 
					    injectHalo(halo: HaloFn, enemy: Enemy) {
 | 
				
			||||||
        halo.call(this, this.info, this.enemy);
 | 
					        halo(this.info, enemy);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@ -687,14 +659,10 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
 | 
				
			|||||||
    ): DamageInfo[] {
 | 
					    ): DamageInfo[] {
 | 
				
			||||||
        const damageCache: Record<string, number> = {};
 | 
					        const damageCache: Record<string, number> = {};
 | 
				
			||||||
        const dirs = ensureArray(dir);
 | 
					        const dirs = ensureArray(dir);
 | 
				
			||||||
 | 
					        const enemy = this.getRealInfo();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return dirs.map(dir => {
 | 
					        return dirs.map(dir => {
 | 
				
			||||||
            const status = getHeroStatusOf(hero, realStatus);
 | 
					            const status = getHeroStatusOf(hero, realStatus);
 | 
				
			||||||
            let enemy: EnemyInfo;
 | 
					 | 
				
			||||||
            this.reset();
 | 
					 | 
				
			||||||
            this.preProvideHalo();
 | 
					 | 
				
			||||||
            this.calAttribute(status, false);
 | 
					 | 
				
			||||||
            enemy = this.getRealInfo();
 | 
					 | 
				
			||||||
            let damage = calDamageWith(enemy, status) ?? Infinity;
 | 
					            let damage = calDamageWith(enemy, status) ?? Infinity;
 | 
				
			||||||
            let skill = -1;
 | 
					            let skill = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -705,13 +673,6 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
 | 
				
			|||||||
                    if (!flags[unlock]) continue;
 | 
					                    if (!flags[unlock]) continue;
 | 
				
			||||||
                    flags[condition] = true;
 | 
					                    flags[condition] = true;
 | 
				
			||||||
                    const status = getHeroStatusOf(hero, realStatus);
 | 
					                    const status = getHeroStatusOf(hero, realStatus);
 | 
				
			||||||
                    // 这几个技能会导致怪物属性也改变,需要重新计算怪物属性
 | 
					 | 
				
			||||||
                    if (needCalSpecial.some(v => enemy.special.includes(v))) {
 | 
					 | 
				
			||||||
                        this.reset();
 | 
					 | 
				
			||||||
                        this.preProvideHalo();
 | 
					 | 
				
			||||||
                        this.calAttribute(status, false);
 | 
					 | 
				
			||||||
                        enemy = this.getRealInfo();
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    const id = `${status.atk},${status.def}`;
 | 
					                    const id = `${status.atk},${status.def}`;
 | 
				
			||||||
                    const d =
 | 
					                    const d =
 | 
				
			||||||
@ -727,12 +688,6 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
 | 
				
			|||||||
                    damageCache[id] = d;
 | 
					                    damageCache[id] = d;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            if (needCalSpecial.some(v => enemy.special.includes(v))) {
 | 
					 | 
				
			||||||
                this.reset();
 | 
					 | 
				
			||||||
                this.preProvideHalo();
 | 
					 | 
				
			||||||
                this.calAttribute(status, false);
 | 
					 | 
				
			||||||
                this.getRealInfo();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            let x: number | undefined;
 | 
					            let x: number | undefined;
 | 
				
			||||||
            let y: number | undefined;
 | 
					            let y: number | undefined;
 | 
				
			||||||
@ -960,10 +915,6 @@ const skills: [unlock: string, condition: string][] = [
 | 
				
			|||||||
    ['bladeOn', 'blade'],
 | 
					    ['bladeOn', 'blade'],
 | 
				
			||||||
    ['shieldOn', 'shield']
 | 
					    ['shieldOn', 'shield']
 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * 需要在每次切换技能时都重新计算怪物属性的特殊属性
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
const needCalSpecial = [3, 7];
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * 获取需要计算怪物伤害的方向
 | 
					 * 获取需要计算怪物伤害的方向
 | 
				
			||||||
@ -1017,13 +968,15 @@ export function calDamageWith(
 | 
				
			|||||||
): number | null {
 | 
					): number | null {
 | 
				
			||||||
    const { hp, hpmax, mana, mdef } = core.status.hero;
 | 
					    const { hp, hpmax, mana, mdef } = core.status.hero;
 | 
				
			||||||
    let { atk, def } = hero as HeroStatus;
 | 
					    let { atk, def } = hero as HeroStatus;
 | 
				
			||||||
    const { hp: monHp, atk: monAtk, def: monDef, special, enemy } = info;
 | 
					    let { hp: monHp, atk: monAtk, def: monDef, special, enemy } = info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let damage = 0;
 | 
					    let damage = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 饥渴
 | 
					    // 饥渴
 | 
				
			||||||
    if (special.includes(7)) {
 | 
					    if (special.includes(7)) {
 | 
				
			||||||
        atk *= 1 - enemy.hungry! / 100;
 | 
					        const delta = Math.floor((atk * enemy.hungry!) / 100);
 | 
				
			||||||
 | 
					        atk -= delta;
 | 
				
			||||||
 | 
					        monAtk += delta;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let heroPerDamage: number;
 | 
					    let heroPerDamage: number;
 | 
				
			||||||
@ -1032,12 +985,23 @@ export function calDamageWith(
 | 
				
			|||||||
    if (special.includes(9)) {
 | 
					    if (special.includes(9)) {
 | 
				
			||||||
        heroPerDamage = atk + mana - monDef;
 | 
					        heroPerDamage = atk + mana - monDef;
 | 
				
			||||||
        if (heroPerDamage <= 0) return null;
 | 
					        if (heroPerDamage <= 0) return null;
 | 
				
			||||||
 | 
					    } else if (special.includes(3)) {
 | 
				
			||||||
 | 
					        // 由于坚固的特性,只能放到这来计算了
 | 
				
			||||||
 | 
					        if (atk > enemy.def) heroPerDamage = 1 + mana;
 | 
				
			||||||
 | 
					        else return null;
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        heroPerDamage = atk - monDef;
 | 
					        heroPerDamage = atk - monDef;
 | 
				
			||||||
        if (heroPerDamage > 0) heroPerDamage += mana;
 | 
					        if (heroPerDamage > 0) heroPerDamage += mana;
 | 
				
			||||||
        else return null;
 | 
					        else return null;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 霜冻
 | 
				
			||||||
 | 
					    if (special.includes(20) && !core.hasEquip('I589')) {
 | 
				
			||||||
 | 
					        heroPerDamage *= 1 - enemy.ice! / 100;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    heroPerDamage *= 1 - info.damageDecline / 100;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let enemyPerDamage: number;
 | 
					    let enemyPerDamage: number;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 魔攻
 | 
					    // 魔攻
 | 
				
			||||||
@ -1048,17 +1012,16 @@ export function calDamageWith(
 | 
				
			|||||||
        if (enemyPerDamage < 0) enemyPerDamage = 0;
 | 
					        if (enemyPerDamage < 0) enemyPerDamage = 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 先攻
 | 
				
			||||||
 | 
					    if (special.includes(17)) {
 | 
				
			||||||
 | 
					        damage += enemyPerDamage;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 连击
 | 
					    // 连击
 | 
				
			||||||
    if (special.includes(4)) enemyPerDamage *= 2;
 | 
					    if (special.includes(4)) enemyPerDamage *= 2;
 | 
				
			||||||
    if (special.includes(5)) enemyPerDamage *= 3;
 | 
					    if (special.includes(5)) enemyPerDamage *= 3;
 | 
				
			||||||
    if (special.includes(6)) enemyPerDamage *= enemy.n!;
 | 
					    if (special.includes(6)) enemyPerDamage *= enemy.n!;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 霜冻
 | 
					 | 
				
			||||||
    if (special.includes(20) && !core.hasEquip('I589')) {
 | 
					 | 
				
			||||||
        heroPerDamage *= 1 - enemy.ice! / 100;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    heroPerDamage *= 1 - info.damageDecline;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // 苍蓝刻
 | 
					    // 苍蓝刻
 | 
				
			||||||
    if (special.includes(28)) {
 | 
					    if (special.includes(28)) {
 | 
				
			||||||
        heroPerDamage *= 1 - enemy.paleShield! / 100;
 | 
					        heroPerDamage *= 1 - enemy.paleShield! / 100;
 | 
				
			||||||
 | 
				
			|||||||
@ -17,6 +17,7 @@ core.control.updateDamage = function (floorId = core.status.floorId, ctx) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    // 计算伤害
 | 
					    // 计算伤害
 | 
				
			||||||
    core.plugin.damage.ensureFloorDamage(floorId);
 | 
					    core.plugin.damage.ensureFloorDamage(floorId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    floor.enemy.calDamage(true, onMap);
 | 
					    floor.enemy.calDamage(true, onMap);
 | 
				
			||||||
    floor.enemy.calMapDamage(true);
 | 
					    floor.enemy.calMapDamage(true);
 | 
				
			||||||
    core.status.damage.data = [];
 | 
					    core.status.damage.data = [];
 | 
				
			||||||
 | 
				
			|||||||
@ -72,21 +72,17 @@ export class Range<C extends Partial<Loc>> {
 | 
				
			|||||||
Range.registerRangeType(
 | 
					Range.registerRangeType(
 | 
				
			||||||
    'square',
 | 
					    'square',
 | 
				
			||||||
    (col, { x, y, d }) => {
 | 
					    (col, { x, y, d }) => {
 | 
				
			||||||
        const cache = (col.cache.square ??= {});
 | 
					 | 
				
			||||||
        const index = `${x},${y},${d}`;
 | 
					 | 
				
			||||||
        if (index in cache) return cache[index];
 | 
					 | 
				
			||||||
        const list = col.collection.list;
 | 
					        const list = col.collection.list;
 | 
				
			||||||
 | 
					        const r = Math.floor(d / 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const r = Math.floor(d);
 | 
					        return list.filter(v => {
 | 
				
			||||||
 | 
					 | 
				
			||||||
        return (cache[index] = list.filter(v => {
 | 
					 | 
				
			||||||
            return (
 | 
					            return (
 | 
				
			||||||
                core.has(v.x) &&
 | 
					                core.has(v.x) &&
 | 
				
			||||||
                core.has(v.y) &&
 | 
					                core.has(v.y) &&
 | 
				
			||||||
                Math.abs(v.x - x) <= r &&
 | 
					                Math.abs(v.x - x) <= r &&
 | 
				
			||||||
                Math.abs(v.y - y) <= r
 | 
					                Math.abs(v.y - y) <= r
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
        }));
 | 
					        });
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    (col, { x, y, d }, item) => {
 | 
					    (col, { x, y, d }, item) => {
 | 
				
			||||||
        const r = Math.floor(d / 2);
 | 
					        const r = Math.floor(d / 2);
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										3
									
								
								src/types/enemy.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								src/types/enemy.d.ts
									
									
									
									
										vendored
									
									
								
							@ -25,7 +25,8 @@ type PartialNumbericEnemyProperty =
 | 
				
			|||||||
    | 'crit'
 | 
					    | 'crit'
 | 
				
			||||||
    | 'courage'
 | 
					    | 'courage'
 | 
				
			||||||
    | 'charge'
 | 
					    | 'charge'
 | 
				
			||||||
    | 'paleShield';
 | 
					    | 'paleShield'
 | 
				
			||||||
 | 
					    | 'iceHalo';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type BooleanEnemyProperty =
 | 
					type BooleanEnemyProperty =
 | 
				
			||||||
    | 'zoneSquare'
 | 
					    | 'zoneSquare'
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user