From 6ce86501f1f90b951db5b830a13e63e9a2fdd25a Mon Sep 17 00:00:00 2001 From: unanmed <1319491857@qq.com> Date: Mon, 5 Feb 2024 19:06:00 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=88=98=E6=96=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/libs/control.js | 5 + public/project/enemys.js | 2 +- public/project/functions.js | 57 +++ public/project/plugins.js | 591 +++++++++++++++++++++++----- src/components/enemyOne.vue | 13 +- src/game/enemy/battle.ts | 110 ------ src/game/enemy/damage.ts | 256 +++--------- src/game/system.ts | 1 - src/plugin/fx/frag.ts | 35 +- src/plugin/game/enemy/checkblock.ts | 35 -- src/plugin/game/index.ts | 2 - src/plugin/game/range.ts | 18 + src/plugin/game/utils.ts | 3 +- src/plugin/ui/fixed.ts | 12 +- src/types/enemy.d.ts | 16 +- 15 files changed, 656 insertions(+), 500 deletions(-) delete mode 100644 src/plugin/game/enemy/checkblock.ts diff --git a/public/libs/control.js b/public/libs/control.js index 5f517ea..fbc8bf4 100644 --- a/public/libs/control.js +++ b/public/libs/control.js @@ -2933,6 +2933,11 @@ control.prototype.getBuff = function (name) { return core.getFlag('__' + name + '_buff__', 1); }; +////// 获得或移除毒衰咒效果 ////// +control.prototype.triggerDebuff = function (action, type) { + return this.controldata.triggerDebuff(action, type); +}; + ////// 设置勇士的位置 ////// control.prototype.setHeroLoc = function (name, value, noGather) { if (!core.status.hero) return; diff --git a/public/project/enemys.js b/public/project/enemys.js index a1964c1..4ee75dd 100644 --- a/public/project/enemys.js +++ b/public/project/enemys.js @@ -16,7 +16,7 @@ var enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80 = "bluePriest": {"name":"初级法师","hp":100,"atk":120,"def":0,"money":3,"exp":0,"point":1,"special":[9]}, "redPriest": {"name":"高级法师","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":[]}, "brownWizard": {"name":"初级巫师","hp":100,"atk":120,"def":0,"money":16,"exp":0,"point":0,"special":[15],"value":100,"range":2}, - "redWizard": {"name":"高级巫师","hp":1000,"atk":1200,"def":0,"money":160,"exp":0,"point":0,"special":[15,28],"value":200,"zoneSquare":true,"specialHalo":[6,16],"n":9,"haloRange":2,"haloSquare":true}, + "redWizard": {"name":"高级巫师","hp":1000,"atk":1200,"def":0,"money":160,"exp":0,"point":0,"special":[15,28],"value":200,"zoneSquare":true,"specialHalo":[6,16],"n":9,"haloRange":2,"haloSquare":true,"zone":200}, "swordsman": {"name":"双手剑士","hp":100,"atk":120,"def":0,"money":6,"exp":0,"point":0,"special":[4]}, "soldier": {"name":"冥战士","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":[]}, "yellowKnight": {"name":"金骑士","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":[]}, diff --git a/public/project/functions.js b/public/project/functions.js index 3af2b28..5865e54 100644 --- a/public/project/functions.js +++ b/public/project/functions.js @@ -365,6 +365,63 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = { if (callback) callback(); }); }, + triggerDebuff: function (action, type) { + // 毒衰咒效果的获得与解除 + // action:获得还是解除;'get'表示获得,'remove'表示解除 + // type:一个数组表示获得了哪些毒衰咒效果;poison, weak,curse + if (!(type instanceof Array)) type = [type]; + + if (action == 'get') { + if (core.inArray(type, 'poison') && !core.hasFlag('poison')) { + // 获得毒效果 + core.setFlag('poison', true); + } + if (core.inArray(type, 'weak') && !core.hasFlag('weak')) { + // 获得衰效果 + core.setFlag('weak', true); + if (core.values.weakValue >= 1) { + // >=1,直接扣数值 + core.addStatus('atk', -core.values.weakValue); + core.addStatus('def', -core.values.weakValue); + } else { + // <1,扣比例 + core.addBuff('atk', -core.values.weakValue); + core.addBuff('def', -core.values.weakValue); + } + } + if (core.inArray(type, 'curse') && !core.hasFlag('curse')) { + // 获得咒效果 + core.setFlag('curse', true); + } + } else if (action == 'remove') { + var success = false; + if (core.inArray(type, 'poison') && core.hasFlag('poison')) { + success = true; + // 移除毒效果 + core.setFlag('poison', false); + } + if (core.inArray(type, 'weak') && core.hasFlag('weak')) { + success = true; + // 移除衰效果 + core.setFlag('weak', false); + if (core.values.weakValue >= 1) { + // >=1,直接扣数值 + core.addStatus('atk', core.values.weakValue); + core.addStatus('def', core.values.weakValue); + } else { + // <1,扣比例 + core.addBuff('atk', core.values.weakValue); + core.addBuff('def', core.values.weakValue); + } + } + if (core.inArray(type, 'curse') && core.hasFlag('curse')) { + success = true; + // 移除咒效果 + core.setFlag('curse', false); + } + if (success) core.playSound('回血'); + } + }, updateStatusBar: function () { // 更新状态栏 diff --git a/public/project/plugins.js b/public/project/plugins.js index 9cd2730..5b53240 100644 --- a/public/project/plugins.js +++ b/public/project/plugins.js @@ -361,7 +361,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = { name: '破甲', desc: enemy => `战斗前,怪物附加角色防御的${Math.floor( - 100 * (enemy.breakArmor || core.values.breakArmor) + 100 * (enemy.breakArmor ?? core.values.breakArmor) )}%作为伤害"`, color: '#b67' }, @@ -370,7 +370,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = { name: '反击', desc: enemy => `战斗时,怪物每回合附加角色攻击的${Math.floor( - 100 * (enemy.counterAttack || core.values.counterAttack) + 100 * (enemy.counterAttack ?? core.values.counterAttack) )}%作为伤害,无视角色防御`, color: '#fa4' }, @@ -379,7 +379,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = { name: '净化', desc: enemy => `战斗前,怪物附加角色护盾的${ - enemy.purify || core.values.purify + enemy.purify ?? core.values.purify }倍作为伤害`, color: '#80eed6' }, @@ -578,6 +578,166 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = { battle: function () { // 这个插件负责战斗相关内容 + // --------------- 战后脚本 + // enemy: DamageEnemy实例,也就是怪物本身 + // x, y: 怪物坐标 + Mota.rewrite(core.events, 'afterBattle', 'full', (enemy, x, y) => { + const { has } = Mota.Plugin.require('utils_g'); + + const floorId = core.status.floorId; + const special = enemy.info.special; + + // 播放战斗动画 + let animate = 'hand'; + // 检查当前装备是否存在攻击动画 + const equipId = core.getEquip(0); + if (equipId && (core.material.items[equipId].equip || {}).animate) + animate = core.material.items[equipId].equip.animate; + + // 检查该动画是否存在SE,如果不存在则使用默认音效 + if (!core.material.animates[animate]?.se) + core.playSound('attack.mp3'); + + // 战斗伤害 + const info = enemy.calDamage(core.status.hero); + const damage = info.damage; + // 判定是否致死 + if (damage >= core.status.hero.hp) { + core.status.hero.hp = 0; + core.updateStatusBar(false, true); + core.events.lose('战斗失败'); + return; + } + + // 扣减体力值并记录统计数据 + core.status.hero.hp -= damage; + core.status.hero.statistics.battleDamage += damage; + core.status.hero.statistics.battle++; + + // 获得金币 + let money = enemy.enemy.money; + let exp = enemy.enemy.exp; + if (enemy.info.guard) { + enemy.info.guard.forEach(v => { + money += v.enemy.money; + exp += v.enemy.exp; + }); + } + core.status.hero.money += money; + core.status.hero.statistics.money += money; + + // 获得经验 + core.status.hero.exp += exp; + core.status.hero.statistics.exp += exp; + + const hint = + '打败 ' + + enemy.enemy.name + + ',金币+' + + money + + ',经验+' + + exp; + core.drawTip(hint, enemy.id); + + // 中毒 + if (special.includes(12)) { + core.triggerDebuff('get', 'poison'); + } + // 衰弱 + if (special.includes(13)) { + core.triggerDebuff('get', 'weak'); + } + // 诅咒 + if (special.includes(14)) { + core.triggerDebuff('get', 'curse'); + } + // 仇恨怪物将仇恨值减半 + if (special.includes(17)) { + core.setFlag( + 'hatred', + Math.floor(core.getFlag('hatred', 0) / 2) + ); + } + // 自爆 + if (special.includes(19)) { + core.status.hero.statistics.battleDamage += + core.status.hero.hp - 1; + core.status.hero.hp = 1; + } + // 退化 + if (special.includes(21)) { + core.status.hero.atk -= enemy.atkValue || 0; + core.status.hero.def -= enemy.defValue || 0; + if (core.status.hero.atk < 0) core.status.hero.atk = 0; + if (core.status.hero.def < 0) core.status.hero.def = 0; + } + // 增加仇恨值 + core.setFlag( + 'hatred', + core.getFlag('hatred', 0) + core.values.hatred + ); + + // 事件的处理 + const todo = []; + + // 战后事件 + if (has(core.status.floorId)) { + const loc = `${x},${y}`; + todo.push( + ...(core.floors[core.status.floorId].afterBattle[loc] ?? []) + ); + } + todo.push(...(enemy.enemy.afterBattle ?? [])); + + // 如果事件不为空,将其插入 + if (todo.length > 0) core.insertAction(todo, x, y); + + if (has(x) && has(y)) { + core.drawAnimate(animate, x, y); + if (special.includes(23)) core.hideBlock(x, y); + else core.removeBlock(x, y); + } else core.drawHeroAnimate(animate); + + // 如果已有事件正在处理中 + if (core.status.event.id == null) core.continueAutomaticRoute(); + else core.clearContinueAutomaticRoute(); + + // 打怪特效 + Mota.r(() => { + const setting = Mota.require('var', 'mainSetting'); + const { applyFragWith } = Mota.Plugin.require('frag_r'); + if (setting.getValue('fx.frag') && has(x) && has(y)) { + const frame = core.status.globalAnimateStatus % 2; + const canvas = document.createElement('canvas'); + canvas.width = 32; + canvas.height = 32; + core.drawIcon(canvas, enemy.id, 0, 0, 32, 32, frame); + const manager = applyFragWith(canvas); + const frag = manager.canvas; + frag.style.imageRendering = 'pixelated'; + frag.style.width = `${frag.width * core.domStyle.scale}px`; + frag.style.height = `${ + frag.height * core.domStyle.scale + }px`; + const left = + (x * 32 + 16 - frag.width / 2 - core.bigmap.offsetX) * + core.domStyle.scale; + const top = + (y * 32 + 16 - frag.height / 2 - core.bigmap.offsetY) * + core.domStyle.scale; + frag.style.left = `${left}px`; + frag.style.top = `${top}px`; + frag.style.zIndex = '45'; + frag.style.position = 'absolute'; + frag.style.filter = 'sepia(20%)brightness(120%)'; + core.dom.gameDraw.appendChild(frag); + manager.onEnd.then(() => { + frag.remove(); + }); + } + }); + }); + // --------------- 战斗伤害 const Damage = Mota.require('module', 'Damage'); @@ -590,7 +750,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = { // 返回null表示不能战斗,返回Infinity也可以 Mota.rewrite(Damage, 'calDamageWith', 'full', (info, hero) => { // 获取勇士属性,这几个属性直接从core.status.hero获取 - const { hp, mana } = core.status.hero; + const { hp, mana, manamax } = core.status.hero; // 获取勇士属性,这几个属性从勇士真实属性获取 // 分开获取是因为获取勇士真实属性会对性能造成一定影响 let { atk, def, mdef, hpmax } = hero; @@ -601,21 +761,40 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = { let damage = 0; /** 勇士单回合伤害 */ let heroPerDamage; + /** 战斗回合 */ + let turn = 0; + + // 无敌 + if (special.includes(20) && !core.hasItem('cross')) { + return null; + } if (special.includes(3)) { // 由于坚固的特性,只能放到这来计算了 if (atk > enemy.def) heroPerDamage = 1; else return null; } else { + // 模仿 + if (special.includes(10)) { + monAtk = atk; + monDef = def; + } heroPerDamage = atk - monDef; if (heroPerDamage <= 0) return null; } + // 吸血 + if (special.includes(11)) { + const vampire = hp * (info.vampire ?? 0); + if (info.add) monHp += vampire; + damage += vampire; + } + /** 怪物单回合伤害 */ let enemyPerDamage; // 魔攻 - if (special.includes(2) || special.includes(13)) { + if (special.includes(2)) { enemyPerDamage = monAtk; } else { enemyPerDamage = monAtk - def; @@ -623,22 +802,69 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = { } // 先攻 - if (special.includes(17)) { + if (special.includes(1)) { damage += enemyPerDamage; } // 连击 if (special.includes(4)) enemyPerDamage *= 2; if (special.includes(5)) enemyPerDamage *= 3; - if (special.includes(6)) enemyPerDamage *= enemy.n; + if (special.includes(6)) enemyPerDamage *= info.n; - /** 战斗回合 */ - let turn = Math.ceil(monHp / heroPerDamage); + // 破甲 + if (special.includes(7)) { + damage += def * (info.breakArmor ?? core.values.breakArmor); + } + // 反击 + if (special.includes(8)) { + enemyPerDamage += + atk * (info.counterAttack ?? core.values.counterAttack); + } + + // 净化 + if (special.includes(9)) { + damage += mdef * (info.purify ?? core.values.purify); + } + + turn = Math.ceil(monHp / heroPerDamage); + + // 支援,支援信息由光环计算而得,直接使用即可 + if (info.guard) { + const guardFirst = false; + const inGuard = core.getFlag('__inGuard__'); + if (!inGuard) + core.setFlag('__extraTurn__', guardFirst ? 0 : turn); + core.setFlag('__inGuard__', true); + for (const enemy of info.guard) { + const info = enemy.getRealInfo(); + damage += + Damage.calDamageWith(info, { + ...hero, + mdef: 0 + }) ?? Infinity; + if (!isFinite(damage)) return null; + } + if (!inGuard) core.removeFlag('__inGuard__'); + turn += core.getFlag('__extraTurn__', 0); + core.removeFlag('__extraTurn__'); + } + + // 计算最终伤害 damage += (turn - 1) * enemyPerDamage; damage -= mdef; if (!core.flags.enableNegativeDamage) damage = Math.max(0, damage); + // 仇恨 + if (special.includes(17)) { + damage += core.getFlag('hatred', 0); + } + + // 固伤 + if (special.includes(22)) { + damage += info.damage; + } + return damage; }); @@ -660,13 +886,33 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = { if (info.special.includes(3)) { return Infinity; } + // 模仿,不计算临界 + if (info.special.includes(10)) { + return Infinity; + } return add; } ); // --------------- 地图伤害 - // 全量复写地图伤害的计算函数,注意此处不能使用箭头函数,因为这是在原型上的函数,其this指向实例,也即怪物(DamageEnemy实例) + const { getHeroStatusOn } = Mota.requireAll('fn'); + const caledBetween = new Set(); + // 全量复写地图伤害计算,这个计算会调用所有的 DamageEnemy 的地图伤害计算 + Mota.rewrite( + Mota.require('class', 'EnemyCollection').prototype, + 'calMapDamage', + 'full', + function () { + this.mapDamage = {}; + caledBetween.clear(); + const hero = getHeroStatusOn(Damage.realStatus, this.floorId); + this.list.forEach(v => { + v.calMapDamage(this.mapDamage, hero); + }); + } + ); + // 全量复写单个怪物地图伤害的计算函数,注意此处不能使用箭头函数,因为这是在原型上的函数,其this指向实例,也即怪物(DamageEnemy实例) // 函数接收两个参数,damage和hero,前者表示要将结果存入的对象,后者是勇士真实属性 // 直接将damage返回即可,返回其他值有可能会引起出错 // 计算出伤害后直接调用this.setMapDamage即可将伤害传到对象中 @@ -678,21 +924,27 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = { // 功能函数,计算曼哈顿距离,和判断一个值是否存在 const { manhattan, has } = Mota.Plugin.require('utils_g'); // 判断这个怪物是不是在地图上 - if (!has(this.x) || !has(this.y) || !has(this.floorId)) + if ( + !has(this.x) || + !has(this.y) || + !has(this.floorId) || + !has(this.col) + ) { return damage; - const enemy = this.enemy; + } + const enemy = this.info; const floor = core.status.maps[this.floorId]; const w = floor.width; const h = floor.height; - // 突刺 + // 领域 if (this.info.special.includes(15)) { const range = enemy.range ?? 1; const startX = Math.max(0, this.x - range); const startY = Math.max(0, this.y - range); const endX = Math.min(floor.width - 1, this.x + range); const endY = Math.min(floor.height - 1, this.y + range); - const dam = Math.max((enemy.value ?? 0) - hero.def, 0); + const dam = Math.max(enemy.zone ?? 0, 0); for (let x = startX; x <= endX; x++) { for (let y = startY; y <= endY; y++) { @@ -703,16 +955,15 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = { continue; } const loc = `${x},${y}`; - this.setMapDamage(damage, loc, dam, '突刺'); + this.setMapDamage(damage, loc, dam, '领域'); } } } - // 射击 + // 激光 if (this.info.special.includes(24)) { const dirs = ['left', 'down', 'up', 'right']; - const dam = Math.max((enemy.atk ?? 0) - hero.def, 0); - const objs = core.getMapBlocksObj(this.floorId); + const dam = Math.max(enemy.laser ?? 0, 0); for (const dir of dirs) { let x = this.x; @@ -722,22 +973,75 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = { x += dx; y += dy; const loc = `${x},${y}`; - const block = objs[loc]; - if ( - block && - block.event.noPass && - block.event.cls !== 'enemys' && - block.event.cls !== 'enemy48' && - block.id !== 141 && - block.id !== 151 - ) { - break; - } - this.setMapDamage(damage, loc, dam, '射击'); + this.setMapDamage(damage, loc, dam, '激光'); } } } + // 夹击 + if (this.info.special.includes(16)) { + const dirs = ['left', 'down', 'up', 'right']; + const dam = Math.floor(core.status.hero.hp / 2); + + for (const dir of dirs) { + let x = this.x; + let y = this.y; + const { x: dx, y: dy } = core.utils.scan[dir]; + if (caledBetween.has(`${x + dx},${y + dy}`)) continue; + const e = this.col.list.find(v => { + return v.x === x + dx * 2 && v.y === y + dy * 2; + }); + if (e) { + const loc = `${x + dx},${y + dy}`; + this.setMapDamage(damage, loc, dam, '夹击'); + caledBetween.add(loc); + } + } + } + + // 阻击 + if (this.info.special.includes(18)) { + const range = 1; + const startX = Math.max(0, this.x - range); + const startY = Math.max(0, this.y - range); + const endX = Math.min(floor.width - 1, this.x + range); + const endY = Math.min(floor.height - 1, this.y + range); + const dam = Math.max(enemy.repulse ?? 0, 0); + + for (let x = startX; x <= endX; x++) { + for (let y = startY; y <= endY; y++) { + if ( + !enemy.zoneSquare && + manhattan(x, y, this.x, this.y) > range + ) { + continue; + } + const loc = `${x},${y}`; + this.setMapDamage(damage, loc, dam, '阻击'); + damage[loc].repulse = damage[loc].repulse ?? []; + damage[loc].repulse.push([this.x, this.y]); + } + } + } + + // 捕捉 + if (this.info.special.includes(27)) { + const dirs = ['left', 'down', 'up', 'right']; + for (const dir of dirs) { + let x = this.x; + let y = this.y; + const { x: dx, y: dy } = core.utils.scan[dir]; + this.col.list.forEach(v => { + if (v.x === x + dx * 2 && v.y === y + dy * 2) { + const loc = `${x + dx},${y + dy}`; + this.setMapDamage(damage, loc, 0); + } + damage[loc].ambush = damage[loc].ambush ?? []; + damage[loc].ambush.push(this); + }); + } + } + return damage; } ); @@ -750,7 +1054,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = { // 光环属性列表,是一个集合Set,你可以在这里配置会被视为光环的属性 const haloSpecials = Mota.require('module', 'Damage').haloSpecials; - haloSpecials.add(8).add(11); + haloSpecials.add(25).add(26).add(28); // ----- 计算第二类光环,即普通光环,这类光环更常见,因此放到前面了 Mota.rewrite( @@ -770,78 +1074,58 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = { // 获取所有还没有计算的光环,注意这里不能直接获取haloSpecial const special = this.getHaloSpecials(); - const square7 = []; - const square5 = []; - // e 是被加成怪的属性,enemy 是施加光环的怪 for (const halo of special) { switch (halo) { - case 8: - square5.push((e, enemy) => { - if ( - e.special.includes(8) && - (e.x !== this.x || this.y !== e.y) - ) { - e.atkBuff += enemy.together ?? 0; - e.defBuff += enemy.together ?? 0; - } + // 普通光环 + case 25: { + const e = this.enemy; + const type = e.haloSquare ? 'square' : 'manhattan'; + const r = Math.floor(e.haloRange); + const d = type === 'square' ? r * 2 + 1 : r; + const range = { x: this.x, y: this.y, d }; + + // 施加光环 + col.applyHalo(type, range, this, (e, enemy) => { + e.atkBuff += enemy.atkBuff ?? 0; + e.defBuff += enemy.defBuff ?? 0; + e.hpBuff += enemy.hpBuff ?? 0; }); - this.providedHalo.add(8); + // 向已施加的光环列表中添加 + this.providedHalo.add(25); break; - case 21: - square7.push(e => { - // e.damageDecline += this.enemy.iceHalo ?? 0; - }); - col.haloList.push({ - type: 'square', - data: { x: this.x, y: this.y, d: 7 }, - special: 21, - from: this - }); - this.providedHalo.add(21); - break; - case 26: - square5.push(e => { - e.defBuff += this.enemy.iceCore ?? 0; - }); - col.haloList.push({ - type: 'square', - data: { x: this.x, y: this.y, d: 5 }, - special: 26, - from: this + } + case 26: { + const range = { x: this.x, y: this.y, d: 1 }; + // 支援 + col.applyHalo('square', range, this, (e, enemy) => { + e.guard = e.guard ?? []; + e.guard.push(this); }); this.providedHalo.add(26); break; - case 27: - square5.push(e => { - e.atkBuff += this.enemy.fireCore ?? 0; - }); - col.haloList.push({ - type: 'square', - data: { x: this.x, y: this.y, d: 5 }, - special: 27, - from: this - }); - this.providedHalo.add(27); - break; + } } } - - col.applyHalo( - 'square', - { x: this.x, y: this.y, d: 7 }, - square7 - ); - col.applyHalo( - 'square', - { x: this.x, y: this.y, d: 5 }, - square5 - ); } ); // ----- 计算第一类光环 + const changeable = Mota.require('module', 'Damage').changeableHaloValue; + changeable + .set(21, ['atkValue', 'defValue']) + .set(7, ['breakArmor']) + .set(8, ['counterAttack']) + .set(22, ['damage']) + .set(25, ['haloRange']) + .set(24, ['laser']) + .set(6, ['n']) + .set(9, ['purify']) + .set(15, ['range']) + .set(18, ['repulse']) + .set(11, ['vampire']) + .set(15, ['zone']); Mota.rewrite( Mota.require('class', 'DamageEnemy').prototype, 'preProvideHalo', @@ -850,11 +1134,47 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = { if (this.progress !== 0) return; this.progress = 1; const special = this.getHaloSpecials(); + const col = this.col ?? core.status.maps[this.floorId].enemy; for (const halo of special) { switch (halo) { - default: - break; + case 28: { + // 特殊光环 + const e = this.enemy; + const type = e.haloSquare ? 'square' : 'manhattan'; + const r = Math.floor(e.haloRange); + const d = type === 'square' ? r * 2 + 1 : r; + const range = { x: this.x, y: this.y, d }; + + // 这一句必须放到applyHalo之前 + this.providedHalo.add(28); + + col.applyHalo( + type, + range, + this, + (e, enemy) => { + const s = enemy.specialHalo; + e.special.push(...s); + // 然后计算特殊属性数值 + for (const spec of s) { + const toChange = changeable.get(spec); + if (!toChange) continue; + for (const key of toChange) { + if (enemy.specialMultiply) { + e[key] = s[key] ?? 1; + e[key] *= enemy[key]; + } else { + e[key] = s[key] ?? 0; + e[key] += enemy[key]; + } + } + } + }, + // true表示递归计算,视为第一类光环 + true + ); + } } } } @@ -870,5 +1190,96 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = { halo(this.info, enemy); } ); + }, + checkBlock: function () { + Mota.rewrite(core.control, 'checkBlock', 'full', function () { + const x = core.getHeroLoc('x'), + y = core.getHeroLoc('y'), + loc = x + ',' + y; + const info = core.status.thisMap.enemy.mapDamage[loc]; + const damage = info?.damage; + const floor = core.status.thisMap; + if (damage) { + // 伤害弹出,在渲染进程中执行 + Mota.r(() => { + Mota.Plugin.require('pop_r').addPop( + (x - core.bigmap.offsetX / 32) * 32 + 12, + (y - core.bigmap.offsetY / 32) * 32 + 20, + (-damage).toString() + ); + }); + core.status.hero.hp -= damage; + const type = [...info.type]; + const text = type.join(',') || '伤害'; + core.drawTip('受到' + text + damage + '点'); + core.drawHeroAnimate('zone'); + this._checkBlock_disableQuickShop(); + core.status.hero.statistics.extraDamage += damage; + if (core.status.hero.hp <= 0) { + core.status.hero.hp = 0; + core.updateStatusBar(); + core.events.lose(); + return; + } else { + core.updateStatusBar(); + } + } + const { findDir, ofDir } = Mota.Plugin.require('utils_g'); + + // 阻击处理 + if (info?.repulse) { + const actions = []; + for (const [ex, ey] of info.repulse) { + const dir = findDir({ x, y }, { x: ex, y: ey }); + const [tx, ty] = ofDir(ex, ey, dir); + if ( + tx < 0 || + ty < 0 || + tx >= floor.width || + ty >= floor.height || + core.getBlock(tx, ty) + ) { + continue; + } + actions.push({ + type: 'move', + loc: [ex, ey], + steps: [findDir({ x, y }, { x: ex, y: ey })], + time: 250, + keep: true, + async: true + }); + } + actions.push({ type: 'waitAsync' }); + core.insertAction(actions); + } + // 捕捉处理 + if (info?.ambush) { + const actions = []; + for (const enemy of info.ambush) { + actions.push({ + type: 'move', + loc: [enemy.x, enemy.y], + steps: [findDir(enemy, { x, y })], + time: 250, + keep: false, + async: true + }); + } + actions.push({ type: 'waitAsync' }); + // 强制战斗 + for (const enemy of info.ambush) { + actions.push({ + type: 'function', + function: + 'function() { ' + + `core.battle(${enemy.x}, ${enemy.y}, true, core.doAction); ` + + '}', + async: true + }); + } + core.insertAction(actions); + } + }); } }; diff --git a/src/components/enemyOne.vue b/src/components/enemyOne.vue index f04baf6..a81ca21 100644 --- a/src/components/enemyOne.vue +++ b/src/components/enemyOne.vue @@ -19,11 +19,14 @@ class="special-text" v-if="has(enemy.special) && enemy.special.length > 0" > -  {{ text[0] }}  +
无属性
diff --git a/src/game/enemy/battle.ts b/src/game/enemy/battle.ts index 521d3f5..d24a9f5 100644 --- a/src/game/enemy/battle.ts +++ b/src/game/enemy/battle.ts @@ -58,116 +58,6 @@ function init() { callback?.(); }; - core.events.afterBattle = function afterBattle( - enemy: DamageEnemy, - x?: number, - y?: number - ) { - const floorId = core.status.floorId; - const special = enemy.info.special; - - // 播放战斗动画 - let animate: AnimationIds = 'hand'; - // 检查当前装备是否存在攻击动画 - const equipId = core.getEquip(0); - if (equipId && (core.material.items[equipId].equip || {}).animate) - animate = core.material.items[equipId].equip.animate; - - // 检查该动画是否存在SE,如果不存在则使用默认音效 - if (!core.material.animates[animate]?.se) core.playSound('attack.mp3'); - - // 战斗伤害 - const info = enemy.calDamage(core.status.hero); - const damage = info.damage; - // 判定是否致死 - if (damage >= core.status.hero.hp) { - core.status.hero.hp = 0; - core.updateStatusBar(false, true); - core.events.lose('战斗失败'); - return; - } - - // 扣减体力值并记录统计数据 - core.status.hero.hp -= damage; - core.status.hero.statistics.battleDamage += damage; - core.status.hero.statistics.battle++; - - // 智慧之源 - if (special.includes(14) && flags.hard === 2) { - core.addFlag( - 'inte_' + floorId, - Math.ceil((core.status.hero.mdef / 10) * 0.3) * 10 - ); - core.status.hero.mdef -= - Math.ceil((core.status.hero.mdef / 10) * 0.3) * 10; - } - - // 极昼永夜 - if (special.includes(22)) { - flags[`night_${floorId}`] ??= 0; - flags[`night_${floorId}`] -= enemy.enemy.night!; - } - if (special.includes(23)) { - flags[`night_${floorId}`] ??= 0; - flags[`night_${floorId}`] += enemy.enemy.day; - } - - // if (core.plugin.skillTree.getSkillLevel(11) > 0) { - // core.plugin.study.declineStudiedSkill(); - // } - - // 如果是融化怪,需要特殊标记一下 - if (special.includes(25) && has(x) && has(y)) { - flags[`melt_${floorId}`] ??= {}; - flags[`melt_${floorId}`][`${x},${y}`] = enemy.enemy.melt; - } - - // 获得金币 - const money = enemy.enemy.money; - core.status.hero.money += money; - core.status.hero.statistics.money += money; - - // 获得经验 - const exp = enemy.enemy.exp; - core.status.hero.exp += exp; - core.status.hero.statistics.exp += exp; - - const hint = - '打败 ' + enemy.enemy.name + ',金币+' + money + ',经验+' + exp; - core.drawTip(hint, enemy.id); - - if (core.getFlag('bladeOn') && core.getFlag('blade')) { - core.setFlag('blade', false); - } - if (core.getFlag('shieldOn') && core.getFlag('shield')) { - core.setFlag('shield', false); - } - - // 事件的处理 - const todo: MotaEvent = []; - - // 战后事件 - if (has(core.status.floorId)) { - const loc = `${x},${y}` as LocString; - todo.push( - ...(core.floors[core.status.floorId].afterBattle[loc] ?? []) - ); - } - todo.push(...(enemy.enemy.afterBattle ?? [])); - - // 如果事件不为空,将其插入 - if (todo.length > 0) core.insertAction(todo, x, y); - - if (has(x) && has(y)) { - core.drawAnimate(animate, x, y); - core.removeBlock(x, y); - } else core.drawHeroAnimate(animate); - - // 如果已有事件正在处理中 - if (core.status.event.id == null) core.continueAutomaticRoute(); - else core.clearContinueAutomaticRoute(); - }; - core.enemys.getCurrentEnemys = function getCurrentEnemys( floorId = core.status.floorId ) { diff --git a/src/game/enemy/damage.ts b/src/game/enemy/damage.ts index 927c9ab..e403d31 100644 --- a/src/game/enemy/damage.ts +++ b/src/game/enemy/damage.ts @@ -14,9 +14,14 @@ interface HaloType { y: number; d: number; }; + manhattan: { + x: number; + y: number; + d: number; + }; } -interface EnemyInfo { +interface EnemyInfo extends Partial> { atk: number; def: number; hp: number; @@ -25,6 +30,7 @@ interface EnemyInfo { defBuff: number; hpBuff: number; enemy: Enemy; + guard?: DamageEnemy[]; x?: number; y?: number; floorId?: FloorIds; @@ -39,7 +45,8 @@ interface DamageInfo { interface MapDamage { damage: number; type: Set; - mockery?: LocArr[]; + repulse?: LocArr[]; + ambush?: DamageEnemy[]; } interface HaloData { @@ -103,6 +110,8 @@ export class EnemyCollection implements RangeCollection { this.haloList = []; this.list.forEach(v => { v.reset(); + }); + this.list.forEach(v => { v.preProvideHalo(); }); this.list.forEach(v => { @@ -146,21 +155,22 @@ export class EnemyCollection implements RangeCollection { applyHalo( type: K, data: HaloType[K], + enemy: DamageEnemy, halo: HaloFn | HaloFn[], recursion: boolean = false ) { const arr = ensureArray(halo); - const enemy = this.range.scan(type, data); + const enemys = this.range.scan(type, data); if (!recursion) { arr.forEach(v => { - enemy.forEach(e => { - e.injectHalo(v, e.enemy); + enemys.forEach(e => { + e.injectHalo(v, enemy.enemy); }); }); } else { - enemy.forEach(e => { + enemys.forEach(e => { arr.forEach(v => { - e.injectHalo(v, e.enemy); + e.injectHalo(v, enemy.enemy); e.preProvideHalo(); }); }); @@ -260,6 +270,26 @@ export class EnemyCollection implements RangeCollection { alpha: 1 }); } + + if (dam.ambush) { + core.status.damage.extraData.push({ + text: '!', + px: 32 * x + 16, + py: 32 * y + 16, + color: '#fa3', + alpha: 1 + }); + } + + if (dam.repulse) { + core.status.damage.extraData.push({ + text: '阻', + px: 32 * x + 16, + py: 32 * y + 16, + color: '#fa3', + alpha: 1 + }); + } } } } @@ -320,8 +350,15 @@ export class DamageEnemy { y: this.y, floorId: this.floorId }; + + for (const [key, value] of Object.entries(enemy)) { + if (!(key in this.info) && has(value)) { + // @ts-ignore + this.info[key] = value; + } + } this.progress = 0; - this.providedHalo = new Set(); + this.providedHalo.clear(); } /** @@ -381,6 +418,7 @@ export class DamageEnemy { if (!this.floorId) return []; if (!has(this.x) || !has(this.y)) return []; const special = this.info.special ?? this.enemy.special; + const filter = special.filter(v => { return Damage.haloSpecials.has(v) && !this.providedHalo.has(v); }); @@ -397,92 +435,12 @@ export class DamageEnemy { /** * 光环预提供,用于平衡所有怪的光环属性,避免出现不同情况下光环效果不一致的现象 */ - preProvideHalo() { - if (this.progress !== 0) return; - this.progress = 1; - const special = this.getHaloSpecials(); - - for (const halo of special) { - switch (halo) { - default: - break; - } - } - } + preProvideHalo() {} /** * 向其他怪提供光环 */ - provideHalo() { - if (this.progress !== 2) return; - this.progress = 3; - if (!this.floorId) return; - if (!has(this.x) || !has(this.y)) return; - const col = this.col ?? core.status.maps[this.floorId].enemy; - if (!col) return; - const special = this.getHaloSpecials(); - - const square7: HaloFn[] = []; - const square5: HaloFn[] = []; - - // e 是被加成怪的属性,enemy 是施加光环的怪 - - for (const halo of special) { - switch (halo) { - case 8: - square5.push((e, enemy) => { - if ( - e.special.includes(8) && - (e.x !== this.x || this.y !== e.y) - ) { - e.atkBuff += enemy.together ?? 0; - e.defBuff += enemy.together ?? 0; - } - }); - this.providedHalo.add(8); - break; - case 21: - square7.push(e => { - // e.damageDecline += this.enemy.iceHalo ?? 0; - }); - col.haloList.push({ - type: 'square', - data: { x: this.x, y: this.y, d: 7 }, - special: 21, - from: this - }); - this.providedHalo.add(21); - break; - case 26: - square5.push(e => { - e.defBuff += this.enemy.iceCore ?? 0; - }); - col.haloList.push({ - type: 'square', - data: { x: this.x, y: this.y, d: 5 }, - special: 26, - from: this - }); - this.providedHalo.add(26); - break; - case 27: - square5.push(e => { - e.atkBuff += this.enemy.fireCore ?? 0; - }); - col.haloList.push({ - type: 'square', - data: { x: this.x, y: this.y, d: 5 }, - special: 27, - from: this - }); - this.providedHalo.add(27); - break; - } - } - - col.applyHalo('square', { x: this.x, y: this.y, d: 7 }, square7); - col.applyHalo('square', { x: this.x, y: this.y, d: 5 }, square5); - } + provideHalo() {} /** * 接受其他怪的光环 @@ -507,64 +465,6 @@ export class DamageEnemy { damage: Record = {}, hero: Partial = getHeroStatusOn(Damage.realStatus) ) { - if (!has(this.x) || !has(this.y) || !has(this.floorId)) return damage; - const enemy = this.enemy; - const floor = core.status.maps[this.floorId]; - const w = floor.width; - const h = floor.height; - - // 突刺 - if (this.info.special.includes(15)) { - const range = enemy.range ?? 1; - const startX = Math.max(0, this.x - range); - const startY = Math.max(0, this.y - range); - const endX = Math.min(floor.width - 1, this.x + range); - const endY = Math.min(floor.height - 1, this.y + range); - const dam = Math.max((enemy.value ?? 0) - hero.def!, 0); - - for (let x = startX; x <= endX; x++) { - for (let y = startY; y <= endY; y++) { - if ( - !enemy.zoneSquare && - manhattan(x, y, this.x, this.y) > range - ) { - continue; - } - const loc = `${x},${y}`; - this.setMapDamage(damage, loc, dam, '突刺'); - } - } - } - - // 射击 - if (this.info.special.includes(24)) { - // const dirs: Dir[] = ['left', 'down', 'up', 'right']; - // const dam = Math.max((enemy.atk ?? 0) - hero.def!, 0); - // const objs = core.getMapBlocksObj(this.floorId); - // for (const dir of dirs) { - // let x = this.x; - // let y = this.y; - // const { x: dx, y: dy } = core.utils.scan[dir]; - // while (x >= 0 && y >= 0 && x < w && y < h) { - // x += dx; - // y += dy; - // const loc = `${x},${y}` as LocString; - // const block = objs[loc]; - // if ( - // block && - // block.event.noPass && - // block.event.cls !== 'enemys' && - // block.event.cls !== 'enemy48' && - // block.id !== 141 && - // block.id !== 151 - // ) { - // break; - // } - // this.setMapDamage(damage, loc, dam, '射击'); - // } - // } - } - return damage; } @@ -572,11 +472,11 @@ export class DamageEnemy { damage: Record, loc: string, dam: number, - type: string + type?: string ) { damage[loc] ??= { damage: 0, type: new Set() }; damage[loc].damage += dam; - damage[loc].type.add(type); + if (type) damage[loc].type.add(type); } private calEnemyDamageOf(hero: Partial, enemy: EnemyInfo) { @@ -730,6 +630,12 @@ export namespace Damage { /** 光环属性 */ export const haloSpecials: Set = new Set(); + /** 会被第一类光环修改的怪物特殊属性数值 */ + export const changeableHaloValue: Map< + number, + SelectKey[] + > = new Map(); + /** * 计算伤害时会用到的勇士属性,攻击防御,其余的不会有buff加成,直接从core.status.hero取 */ @@ -744,55 +650,7 @@ export namespace Damage { info: EnemyInfo, hero: Partial ): number | null { - const { hp, hpmax, mana, mdef } = core.status.hero; - let { atk, def } = hero as HeroStatus; - let { hp: monHp, atk: monAtk, def: monDef, special, enemy } = info; - - let damage = 0; - - // 饥渴 - if (special.includes(7)) { - const delta = Math.floor((atk * enemy.hungry!) / 100); - atk -= delta; - monAtk += delta; - } - - let heroPerDamage: number; - - // 绝对防御 - if (special.includes(3)) { - // 由于坚固的特性,只能放到这来计算了 - if (atk > enemy.def) heroPerDamage = 1 + mana; - else return null; - } else { - heroPerDamage = atk - monDef; - if (heroPerDamage > 0) heroPerDamage += mana; - else return null; - } - - let enemyPerDamage: number; - - // 魔攻 - if (special.includes(2) || special.includes(13)) { - enemyPerDamage = monAtk; - } else { - enemyPerDamage = monAtk - def; - if (enemyPerDamage < 0) enemyPerDamage = 0; - } - - // 先攻 - if (special.includes(17)) { - damage += enemyPerDamage; - } - - // 连击 - if (special.includes(4)) enemyPerDamage *= 2; - if (special.includes(5)) enemyPerDamage *= 3; - if (special.includes(6)) enemyPerDamage *= enemy.n!; - - let turn = Math.ceil(monHp / heroPerDamage); - - return damage; + return null; } export function ensureFloorDamage(floorId: FloorIds) { diff --git a/src/game/system.ts b/src/game/system.ts index fcc4c18..228b289 100644 --- a/src/game/system.ts +++ b/src/game/system.ts @@ -164,7 +164,6 @@ interface PluginInterface { heroFourFrames_g: typeof import('../plugin/game/fx/heroFourFrames'); rewrite_g: typeof import('../plugin/game/fx/rewrite'); itemDetail_g: typeof import('../plugin/game/fx/itemDetail'); - checkBlock_g: typeof import('../plugin/game/enemy/checkblock'); } interface PackageInterface { diff --git a/src/plugin/fx/frag.ts b/src/plugin/fx/frag.ts index fa5046d..9ae9559 100644 --- a/src/plugin/fx/frag.ts +++ b/src/plugin/fx/frag.ts @@ -24,40 +24,7 @@ const MAX_ROTATE = 0.5; /** 碎裂动画的速率曲线函数 */ const FRAG_TIMING = linear(); -export function init() { - Mota.rewrite(core.events, 'afterBattle', 'add', (_, enemy, x, y) => { - // 打怪特效 - const setting = Mota.require('var', 'mainSetting'); - - if (setting.getValue('fx.frag') && has(x) && has(y)) { - const frame = core.status.globalAnimateStatus % 2; - const canvas = document.createElement('canvas'); - canvas.width = 32; - canvas.height = 32; - core.drawIcon(canvas, enemy.id, 0, 0, 32, 32, frame); - const manager = applyFragWith(canvas); - const frag = manager.canvas; - frag.style.imageRendering = 'pixelated'; - frag.style.width = `${frag.width * core.domStyle.scale}px`; - frag.style.height = `${frag.height * core.domStyle.scale}px`; - const left = - (x * 32 + 16 - frag.width / 2 - core.bigmap.offsetX) * - core.domStyle.scale; - const top = - (y * 32 + 16 - frag.height / 2 - core.bigmap.offsetY) * - core.domStyle.scale; - frag.style.left = `${left}px`; - frag.style.top = `${top}px`; - frag.style.zIndex = '45'; - frag.style.position = 'absolute'; - frag.style.filter = 'sepia(20%)brightness(120%)'; - core.dom.gameDraw.appendChild(frag); - manager.onEnd.then(() => { - frag.remove(); - }); - } - }); -} +export function init() {} export function applyFragWith( canvas: HTMLCanvasElement, diff --git a/src/plugin/game/enemy/checkblock.ts b/src/plugin/game/enemy/checkblock.ts deleted file mode 100644 index 607b4a1..0000000 --- a/src/plugin/game/enemy/checkblock.ts +++ /dev/null @@ -1,35 +0,0 @@ -export function init() { - // 伤害弹出 - // 复写阻激夹域检测 - control.prototype.checkBlock = function (forceMockery: boolean = false) { - const x = core.getHeroLoc('x'), - y = core.getHeroLoc('y'), - loc = x + ',' + y; - const info = core.status.thisMap.enemy.mapDamage[loc]; - const damage = info?.damage; - if (damage) { - Mota.r(() => { - Mota.Plugin.require('pop_r').addPop( - (x - core.bigmap.offsetX / 32) * 32 + 12, - (y - core.bigmap.offsetY / 32) * 32 + 20, - (-damage).toString() - ); - }); - core.status.hero.hp -= damage; - const type = [...info.type]; - const text = type.join(',') || '伤害'; - core.drawTip('受到' + text + damage + '点'); - core.drawHeroAnimate('zone'); - this._checkBlock_disableQuickShop(); - core.status.hero.statistics.extraDamage += damage; - if (core.status.hero.hp <= 0) { - core.status.hero.hp = 0; - core.updateStatusBar(); - core.events.lose(); - return; - } else { - core.updateStatusBar(); - } - } - }; -} diff --git a/src/plugin/game/index.ts b/src/plugin/game/index.ts index e718b4e..e20a7f0 100644 --- a/src/plugin/game/index.ts +++ b/src/plugin/game/index.ts @@ -6,7 +6,6 @@ import * as removeMap from './removeMap'; import * as shop from './shop'; import * as utils from './utils'; import * as remainEnemy from './enemy/remainEnemy'; -import * as checkBlock from './enemy/checkblock'; Mota.Plugin.register('utils_g', utils); Mota.Plugin.register('shop_g', shop); @@ -16,7 +15,6 @@ Mota.Plugin.register('heroFourFrames_g', heroFourFrames, heroFourFrames.init); Mota.Plugin.register('rewrite_g', rewrite, rewrite.init); Mota.Plugin.register('itemDetail_g', itemDetail, itemDetail.init); Mota.Plugin.register('remainEnemy_g', remainEnemy); -Mota.Plugin.register('checkBlock_g', checkBlock, checkBlock.init); // export { // halo, diff --git a/src/plugin/game/range.ts b/src/plugin/game/range.ts index 497d1f7..e66346f 100644 --- a/src/plugin/game/range.ts +++ b/src/plugin/game/range.ts @@ -96,3 +96,21 @@ Range.registerRangeType( ); } ); +Range.registerRangeType( + 'manhattan', + (col, { x, y, d }) => { + const list = col.collection.list; + return list.filter(v => { + if (!has(v.x) || !has(v.y)) return; + const dx = Math.abs(v.x - x); + const dy = Math.abs(v.y - y); + return dx + dy < d; + }); + }, + (col, { x, y, d }, item) => { + if (!has(item.x) || !has(item.y)) return false; + const dx = Math.abs(item.x - x); + const dy = Math.abs(item.y - y); + return dx + dy < d; + } +); diff --git a/src/plugin/game/utils.ts b/src/plugin/game/utils.ts index 6a0d4bd..bee586d 100644 --- a/src/plugin/game/utils.ts +++ b/src/plugin/game/utils.ts @@ -160,9 +160,10 @@ export function boundary(arr: any, key?: any) { export function findDir(from: Loc, to: Loc): Dir2 | 'none' { const dx = to.x - from.x; const dy = to.y - from.y; + return ( (Object.entries(core.utils.scan2).find(v => { - v[1].x === dx && v[1].y === dy; + return v[1].x === dx && v[1].y === dy; })?.[0] as Dir2) ?? 'none' ); } diff --git a/src/plugin/ui/fixed.ts b/src/plugin/ui/fixed.ts index f919c87..06ce1e5 100644 --- a/src/plugin/ui/fixed.ts +++ b/src/plugin/ui/fixed.ts @@ -28,19 +28,17 @@ export function getDetailedEnemy( ) => { return typeof func === 'string' ? func : func(enemy); }; - const special: [string, string, string][] = enemy.enemy.special.map(vv => { + const special: [string, string, string][] = enemy.info.special.map(vv => { const s = Mota.require('var', 'enemySpecials')[vv]; + const info = { ...enemy.enemy, ...enemy.info }; return [ - fromFunc(s.name, enemy.enemy), - fromFunc(s.desc, enemy.enemy), + fromFunc(s.name, info), + fromFunc(s.desc, info), s.color as string ]; }); const l = isMobile ? 1 : 2; - const showSpecial = - special.length > l - ? special.slice(0, l).concat([['...', '', '#fff']]) - : special.slice(); + const showSpecial = special; const damageColor = getDamageColor(dam) as string; diff --git a/src/types/enemy.d.ts b/src/types/enemy.d.ts index 5a61f7c..832b1fa 100644 --- a/src/types/enemy.d.ts +++ b/src/types/enemy.d.ts @@ -15,21 +15,7 @@ type PartialNumbericEnemyProperty = | 'purify' | 'atkValue' | 'defValue' - | 'damage' - | 'iceDecline' - | 'iceCore' - | 'fireCore' - | 'together' - | 'hungry' - | 'ice' - | 'crit' - | 'courage' - | 'charge' - | 'paleShield' - | 'iceHalo' - | 'day' - | 'night' - | 'melt'; + | 'damage'; type BooleanEnemyProperty = | 'zoneSquare'