diff --git a/src/core/render/preset/damage.ts b/src/core/render/preset/damage.ts index e94cc10..d54ecdf 100644 --- a/src/core/render/preset/damage.ts +++ b/src/core/render/preset/damage.ts @@ -340,7 +340,7 @@ export class Damage extends Sprite { }; block.add(dam1).add(dam2); - if (real.special.includes(8) && real.togetherNum) { + if (real.special.has(8) && real.togetherNum) { const dam3: DamageRenderable = { align: 'right', baseline: 'top', @@ -352,7 +352,7 @@ export class Damage extends Sprite { }; block.add(dam3); } - if (real.special.includes(30)) { + if (real.special.has(30)) { const dam4: DamageRenderable = { align: 'left', baseline: 'top', diff --git a/src/game/enemy/battle.ts b/src/game/enemy/battle.ts index d530361..ccc51a1 100644 --- a/src/game/enemy/battle.ts +++ b/src/game/enemy/battle.ts @@ -192,7 +192,7 @@ function init() { core.status.hero.statistics.battle++; // 智慧之源 - if (special.includes(14) && flags.hard === 2) { + if (special.has(14) && flags.hard === 2) { core.addFlag( 'inte_' + floorId, Math.ceil((core.status.hero.mdef / 10) * 0.3) * 10 @@ -202,11 +202,11 @@ function init() { } // 极昼永夜 - if (special.includes(22)) { + if (special.has(22)) { flags[`night_${floorId}`] ??= 0; flags[`night_${floorId}`] -= enemy.info.night!; } - if (special.includes(23)) { + if (special.has(23)) { flags[`night_${floorId}`] ??= 0; flags[`night_${floorId}`] += enemy.info.day; } @@ -216,7 +216,7 @@ function init() { // } // 如果是融化怪,需要特殊标记一下 - if (special.includes(25) && has(x) && has(y)) { + if (special.has(25) && has(x) && has(y)) { flags[`melt_${floorId}`] ??= {}; flags[`melt_${floorId}`][`${x},${y}`] = enemy.info.melt; } diff --git a/src/game/enemy/damage.ts b/src/game/enemy/damage.ts index 891a365..8adafce 100644 --- a/src/game/enemy/damage.ts +++ b/src/game/enemy/damage.ts @@ -1,12 +1,6 @@ import { getHeroStatusOf, getHeroStatusOn } from '@/game/state/hero'; import { Range, RangeCollection } from '@/plugin/game/range'; -import { - checkV2, - ensureArray, - formatDamage, - has, - manhattan -} from '@/plugin/game/utils'; +import { ensureArray, has, manhattan } from '@/plugin/game/utils'; import EventEmitter from 'eventemitter3'; // todo: 光环划分优先级,从而可以实现光环的多级运算 @@ -24,11 +18,11 @@ interface HaloType { }; } -export interface EnemyInfo extends Partial { +export interface EnemyInfo extends Partial> { atk: number; def: number; hp: number; - special: number[]; + special: Set; damageDecline: number; atkBuff_: number; defBuff_: number; @@ -280,7 +274,7 @@ export class DamageEnemy { hp: enemy.hp, atk: enemy.atk, def: enemy.def, - special: enemy.special.slice(), + special: new Set(enemy.special), damageDecline: 0, atkBuff_: 0, defBuff_: 0, @@ -323,7 +317,7 @@ export class DamageEnemy { } // 智慧之源 - if (flags.hard === 2 && special.includes(14)) { + if (flags.hard === 2 && special.has(14)) { info.atk += flags[`inte_${floorId}`] ?? 0; } @@ -368,21 +362,17 @@ export class DamageEnemy { return this.info; } - getHaloSpecials(): number[] { - if (!this.floorId) return []; - if (!has(this.x) || !has(this.y)) return []; + getHaloSpecials(): Set { + if (!this.floorId) return new Set(); + if (!has(this.x) || !has(this.y)) return new Set(); const special = this.info.special ?? this.enemy.special; - const filter = special.filter(v => { - return haloSpecials.has(v) && !this.providedHalo.has(v); + const res = new Set(); + special.forEach(v => { + if (haloSpecials.has(v) && !this.providedHalo.has(v)) { + res.add(v); + } }); - if (filter.length === 0) return []; - const collection = this.col ?? core.status.maps[this.floorId].enemy; - if (!collection) { - throw new Error( - `Unexpected undefined of enemy collection in floor ${this.floorId}.` - ); - } - return filter; + return res; } /** @@ -421,9 +411,7 @@ export class DamageEnemy { const s = enemy.specialHalo!; for (const spe of s) { - // 防止重复 - if (!e.special.includes(spe)) - e.special.push(spe); + e.special.add(spe); } // 如果是自身,就不进行特殊属性数值处理了 if (e === this.info) return; @@ -476,14 +464,14 @@ export class DamageEnemy { // e 是被加成怪的属性,enemy 是施加光环的怪 // 抱团 - if (special.includes(8)) { + if (special.has(8)) { col.applyHalo( 'square', { x: this.x, y: this.y, d: 5 }, this, (e, enemy) => { if ( - e.special.includes(8) && + e.special.has(8) && (e.x !== this.x || this.y !== e.y) ) { e.atkBuff_ += enemy.together ?? 0; @@ -497,7 +485,7 @@ export class DamageEnemy { } // 冰封光环 - if (special.includes(21)) { + if (special.has(21)) { square7.push(e => { e.damageDecline += this.info.iceHalo ?? 0; }); @@ -511,7 +499,7 @@ export class DamageEnemy { } // 冰封之核 - if (special.includes(26)) { + if (special.has(26)) { square5.push(e => { e.defBuff_ += this.info.iceCore ?? 0; }); @@ -525,7 +513,7 @@ export class DamageEnemy { } // 火焰之核 - if (special.includes(27)) { + if (special.has(27)) { square5.push(e => { e.atkBuff_ += this.info.fireCore ?? 0; }); @@ -539,7 +527,7 @@ export class DamageEnemy { } // 再生光环 - if (special.includes(31)) { + if (special.has(31)) { square7.push(e => { e.hpBuff_ += this.info.hpHalo ?? 0; }); @@ -553,7 +541,7 @@ export class DamageEnemy { } // 同化,它不会被光环类属性影响,因此放到这 - if (special.includes(32)) { + if (special.has(32)) { const e = this.info; const type = 'square'; const r = Math.floor(e.assimilateRange!); @@ -567,10 +555,7 @@ export class DamageEnemy { for (const spe of s) { if (unassimilatable.has(spe)) continue; - // 防止重复 - if (!enemy.special.includes(spe)) { - enemy.special.push(spe); - } + enemy.special.add(spe); } // 然后计算特殊属性数值 for (const spec of s) { @@ -643,7 +628,7 @@ export class DamageEnemy { const h = floor.height; // 突刺 - if (this.info.special.includes(15)) { + if (this.info.special.has(15)) { const range = enemy.range ?? 1; const startX = Math.max(0, this.x - range); const startY = Math.max(0, this.y - range); @@ -666,7 +651,7 @@ export class DamageEnemy { } // 射击 - if (this.info.special.includes(24)) { + if (this.info.special.has(24)) { const dirs: Dir[] = ['left', 'down', 'up', 'right']; const dam = Math.max((enemy.atk ?? 0) - hero.def!, 0); const objs = core.getMapBlocksObj(this.floorId); @@ -683,8 +668,6 @@ export class DamageEnemy { if ( block && block.event.noPass && - block.event.cls !== 'enemys' && - block.event.cls !== 'enemy48' && block.id !== 141 && block.id !== 151 ) { @@ -696,7 +679,7 @@ export class DamageEnemy { } // 电摇嘲讽 - if (this.info.special.includes(19)) { + if (this.info.special.has(19)) { const objs = core.getMapBlocksObj(this.floorId); for (let nx = 0; nx < w; nx++) { const loc = `${nx},${this.y}` as LocString; @@ -719,7 +702,7 @@ export class DamageEnemy { } // 追猎 - if (this.info.special.includes(12)) { + if (this.info.special.has(12)) { const objs = core.getMapBlocksObj(this.floorId); for (let nx = 0; nx < w; nx++) { const loc = `${nx},${this.y}` as LocString; @@ -922,13 +905,13 @@ export class DamageEnemy { const add = info.def + info.hp - core.status.hero.mana; // 坚固,不可能通过攻击秒杀 - if (info.special.includes(3)) { + if (info.special.has(3)) { return Infinity; } // 列方程求解,拿笔算一下就知道了 // 饥渴,会偷取勇士攻击 - if (info.special.includes(7)) { + if (info.special.has(7)) { if (info.damageDecline === 0) { return add / (1 - this.enemy.hungry! / 100); } else { @@ -942,7 +925,7 @@ export class DamageEnemy { } // 霜冻 - if (info.special.includes(20) && !core.hasEquip('I589')) { + if (info.special.has(20) && !core.hasEquip('I589')) { return ( info.def + info.hp / (1 - this.enemy.ice! / 100) - @@ -998,7 +981,7 @@ export function calDamageWith( let damage = 0; // 饥渴 - if (special.includes(7)) { + if (special.has(7)) { const delta = Math.floor((atk * info.hungry!) / 100); atk -= delta; monAtk += delta; @@ -1007,10 +990,10 @@ export function calDamageWith( let heroPerDamage: number; // 绝对防御 - if (special.includes(9)) { + if (special.has(9)) { heroPerDamage = atk + mana - monDef; if (heroPerDamage <= 0) return null; - } else if (special.includes(3)) { + } else if (special.has(3)) { // 由于坚固的特性,只能放到这来计算了 if (atk > enemy.def) heroPerDamage = 1 + mana; else return null; @@ -1021,7 +1004,7 @@ export function calDamageWith( } // 霜冻 - if (special.includes(20) && !core.hasEquip('I589')) { + if (special.has(20) && !core.hasEquip('I589')) { heroPerDamage *= 1 - info.ice! / 100; } @@ -1030,7 +1013,7 @@ export function calDamageWith( let enemyPerDamage: number; // 魔攻 - if (special.includes(2) || special.includes(13)) { + if (special.has(2) || special.has(13)) { enemyPerDamage = monAtk; enemyPerDamage -= magicDef; } else { @@ -1038,38 +1021,38 @@ export function calDamageWith( } // 连击 - if (special.includes(4)) enemyPerDamage *= 2; - if (special.includes(5)) enemyPerDamage *= 3; - if (special.includes(6)) enemyPerDamage *= info.n!; + if (special.has(4)) enemyPerDamage *= 2; + if (special.has(5)) enemyPerDamage *= 3; + if (special.has(6)) enemyPerDamage *= info.n!; if (enemyPerDamage < 0) enemyPerDamage = 0; // 苍蓝刻 - if (special.includes(28)) { + if (special.has(28)) { heroPerDamage *= 1 - info.paleShield! / 100; } let turn = Math.ceil(monHp / heroPerDamage); // 致命一击 - if (special.includes(1)) { + if (special.has(1)) { const times = Math.floor(turn / 5); damage += ((times * (info.crit! - 100)) / 100) * enemyPerDamage; } // 勇气之刃 - if (turn > 1 && special.includes(10)) { + if (turn > 1 && special.has(10)) { damage += (info.courage! / 100 - 1) * enemyPerDamage; } // 勇气冲锋 - if (special.includes(11)) { + if (special.has(11)) { damage += (info.charge! / 100) * enemyPerDamage; turn += 5; } // 先攻 - if (special.includes(17)) { + if (special.has(17)) { damage += enemyPerDamage; } diff --git a/src/plugin/game/replay.ts b/src/plugin/game/replay.ts index 3ef5f68..b86bce9 100644 --- a/src/plugin/game/replay.ts +++ b/src/plugin/game/replay.ts @@ -45,25 +45,6 @@ export function init() { return true; }); - core.registerReplayAction('study', name => { - if (!name.startsWith('study:')) return false; - const [num, x, y] = name - .slice(6) - .split(',') - .map(v => parseInt(v)); - if (!canStudySkill(num)) return false; - const id = core.getBlockId(x, y); - ensureFloorDamage(core.status.floorId); - const col = core.status.thisMap.enemy; - col.calRealAttribute(); - const enemy = col.list.find(v => v.x === x && v.y === y)!.info; - if (!enemy.special.includes(num)) return false; - studySkill(enemy, num); - core.status.route.push(name); - core.replay(); - return true; - }); - // 商店 let shopOpened = false; let openedShopId = ''; diff --git a/src/plugin/ui/fixed.ts b/src/plugin/ui/fixed.ts index 1bb60ea..8e68a84 100644 --- a/src/plugin/ui/fixed.ts +++ b/src/plugin/ui/fixed.ts @@ -28,7 +28,7 @@ export function getDetailedEnemy( ) => { return typeof func === 'string' ? func : func(enemy); }; - const special: [string, string, string][] = enemy.info.special + const special: [string, string, string][] = [...enemy.info.special] .filter(v => !enemy.info.specialHalo?.includes(v)) .map(vv => { const s = Mota.require('var', 'enemySpecials')[vv]; diff --git a/src/ui/fixed.vue b/src/ui/fixed.vue index 8499e8f..80b93be 100644 --- a/src/ui/fixed.vue +++ b/src/ui/fixed.vue @@ -73,7 +73,7 @@ const detail = ((): [number, string, string][] => { ]; })(); const special = (() => { - const s = enemy.info.special; + const s = [...enemy.info.special]; const fromFunc = ( func: string | ((enemy: EnemyInfo) => string),