From 44bd0cfad5f93ae2a9e29e1561ce9d9adea2a46a Mon Sep 17 00:00:00 2001 From: ShakeFlower Date: Thu, 13 Feb 2025 20:01:56 +0800 Subject: [PATCH] =?UTF-8?q?fix:=E5=8D=95=E7=82=B9=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E7=89=B9=E6=AE=8A=E5=B1=9E=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libs/enemys.js | 63 ++++++++++++++++++++++++++++++++------------------ libs/ui.js | 9 ++++---- libs/utils.js | 38 ++++++++++++++++++++++++++++++ runtime.d.ts | 6 +++++ 4 files changed, 89 insertions(+), 27 deletions(-) diff --git a/libs/enemys.js b/libs/enemys.js index 0d893085..0fe1eba6 100644 --- a/libs/enemys.js +++ b/libs/enemys.js @@ -437,6 +437,11 @@ enemys.prototype.getCurrentEnemys = function (floorId) { return this._getCurrentEnemys_sort(enemys); } +////// 获得哪些属性不相同时会在手册中显示为两种敌人 ////// +enemys.prototype.getStatusToCompare = function () { + return ['hp', 'atk', 'def', 'money', 'exp', 'special']; +} + enemys.prototype._getCurrentEnemys_getEnemy = function (enemyId) { var enemy = core.material.enemys[enemyId]; if (!enemy) return null; @@ -446,53 +451,65 @@ enemys.prototype._getCurrentEnemys_getEnemy = function (enemyId) { } enemys.prototype._getCurrentEnemys_addEnemy = function (enemyId, enemys, used, x, y, floorId) { - var enemy = this._getCurrentEnemys_getEnemy(enemyId); + // 获取原始的core.material.enemys数据 + const enemy = this._getCurrentEnemys_getEnemy(enemyId); if (enemy == null) return; - var id = enemy.id; + const id = enemy.id; - var enemyInfo = this.getEnemyInfo(enemy, null, null, null, floorId); - var locEnemyInfo = this.getEnemyInfo(enemy, null, x, y, floorId); + // 获取计算了光环等加成,未计算该点加成的enemyInfo,和也算了该点加成的locEnemyInfo。 + let enemyInfo = this.getEnemyInfo(enemy, null, null, null, floorId); + let locEnemyInfo = this.getEnemyInfo(enemy, null, x, y, floorId); - if (!core.flags.enableEnemyPoint || - (locEnemyInfo.atk == enemyInfo.atk && locEnemyInfo.def == enemyInfo.def && locEnemyInfo.hp == enemyInfo.hp)) { + function statusEqual(enemyInfo, locEnemyInfo) { + return core.enemys.getStatusToCompare().every((status) => { + if (status === 'special') { + enemyInfo[status]= core.utils.parseSpecial(enemyInfo[status]); + locEnemyInfo[status] = core.utils.parseSpecial(locEnemyInfo[status]); + } + return core.utils.deepEqual(enemyInfo[status],locEnemyInfo[status]); + }); + } + + if (!core.flags.enableEnemyPoint || statusEqual(enemyInfo, locEnemyInfo)) { x = null; y = null; } else { // 检查enemys里面是否使用了存在的内容 - for (var i = 0; i < enemys.length; ++i) { - var one = enemys[i]; - if (id == one.id && one.locs != null && - locEnemyInfo.atk == one.atk && locEnemyInfo.def == one.def && locEnemyInfo.hp == one.hp) { + for (let i = 0; i < enemys.length; ++i) { + const one = enemys[i]; + if (id === one.id && one.locs != null && statusEqual(one, locEnemyInfo)) { one.locs.push([x, y]); return; } } enemyInfo = locEnemyInfo; } - var id = enemy.id + ":" + x + ":" + y; - if (used[id]) return; - used[id] = true; + const uniqueId = enemy.id + ":" + x + ":" + y; + if (used[uniqueId]) return; + used[uniqueId] = true; - var specialText = core.enemys.getSpecialText(enemy); - var specialColor = core.enemys.getSpecialColor(enemy); + // 这里只用到了enemy.special属性,填写locEnemyInfo没有问题。 + const specialText = core.enemys.getSpecialText(locEnemyInfo); + const specialColor = core.enemys.getSpecialColor(locEnemyInfo); - var critical = this.nextCriticals(enemy, 1, x, y, floorId); - if (critical.length > 0) critical = critical[0]; + // 这里输入(x, y, floorId),在函数内部处理相关信息 + const critical = this.nextCriticals(enemy, 1, x, y, floorId); + let criticalInfo = critical.length > 0 ? critical[0] : null; - var e = core.clone(enemy); - for (var v in enemyInfo) { - e[v] = enemyInfo[v]; + const e = core.clone(enemy); + for (let key in enemyInfo) { + e[key] = enemyInfo[key]; } - if (x != null && y != null) { + if (x !== null && y !== null) { e.locs = [[x, y]]; } e.name = core.getEnemyValue(enemy, 'name', x, y, floorId); e.specialText = specialText; e.specialColor = specialColor; e.damage = this.getDamage(enemy, x, y, floorId); - e.critical = critical[0]; - e.criticalDamage = critical[1]; + e.critical = criticalInfo?.[0]; + e.criticalDamage = criticalInfo?.[1]; e.defDamage = this._getCurrentEnemys_addEnemy_defDamage(enemy, x, y, floorId); enemys.push(e); } diff --git a/libs/ui.js b/libs/ui.js index 38ed9806..2d5a942b 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -2387,8 +2387,9 @@ ui.prototype._drawBookDetail_getInfo = function (index) { var enemys = core.enemys.getCurrentEnemys(floorId); if (enemys.length == 0) return []; index = core.clamp(index, 0, enemys.length - 1); - var enemy = enemys[index], enemyId = enemy.id; - var texts = core.enemys.getSpecialHint(enemyId); + // enemys:手册需要显示的敌人合集数组,enemy:当前选中的敌人 + var enemy = enemys[index]; + var texts = core.enemys.getSpecialHint(enemy); if (texts.length == 0) texts.push("该怪物无特殊属性。"); if (enemy.description) texts.push(enemy.description + "\r"); texts.push(""); @@ -2416,8 +2417,8 @@ ui.prototype._drawBookDetail_origin = function (enemy, texts) { if (enemy.locs != null && enemy.locs.length >= 0) { texts.push("\r[#FF6A6A]\\d怪物坐标:\\d\r[]" + JSON.stringify(enemy.locs)); } - ["hp", "atk", "def", "point", "money", "exp"].forEach(function (one) { - if (enemy[one] == null || originEnemy[one] == null) return; + core.enemys.getStatusToCompare().forEach(function (one) { + // if (enemy[one] == null || originEnemy[one] == null) return; if (enemy[one] != originEnemy[one]) { content.push(core.getStatusLabel(one) + " " + originEnemy[one]); } diff --git a/libs/utils.js b/libs/utils.js index 51f6effe..2f2511c3 100644 --- a/libs/utils.js +++ b/libs/utils.js @@ -456,6 +456,44 @@ utils.prototype.cloneArray = function (data) { } } +////// 将怪物特殊属性转为升序数组并去零 ////// +utils.prototype.parseSpecial = function (special) { + if (special == null) special = []; + else if (typeof special === 'number') special = [special]; + return [...new Set(special.filter(num => num !== 0))].sort((a, b) => a - b); +} + + +////// 比较两个变量是否值相等 ////// +utils.prototype.deepEqual = function (x, y) { + // 是值类型,或引用相同 + if (x === y) return true; + + if (x == null && y == null) return true; + + if (typeof x != typeof y) return false; + + if (typeof x === 'object') { + let xKeys = Object.keys(x), yKeys = Object.keys(y); + + if (xKeys.length !== yKeys.length) return false; + + for (let key of xKeys) { + if (!yKeys.includes(key) || !this.deepEqual(x[key], y[key])) return false; + } + return true; + } + + if (Array.isArray(x) && Array.isArray(y)) { + if (x.length !== y.length) return false; + for (let i = 0; i < x.length; i++) { + if (!this.deepEqual(x[i], y[i])) return false; + } + return true; + } + return false; +} + ////// 裁剪图片 ////// utils.prototype.splitImage = function (image, width, height) { if (typeof image == "string") { diff --git a/runtime.d.ts b/runtime.d.ts index 5924ea2a..df1ab19e 100644 --- a/runtime.d.ts +++ b/runtime.d.ts @@ -2582,6 +2582,12 @@ interface utils { /** 深拷贝一个1D或2D的数组 */ cloneArray(data?: Array | Array>): Array | Array> + /** 将怪物特殊属性转为升序数组并去零 */ + parseSpecial(special: null | number | number[]): number[] + + /** 比较两个变量是否值相等 */ + deepEqual(x: unknown, y: unknown): boolean + /** * 等比例切分一张图片 * @example core.splitImage(core.material.images.images['npc48.png'], 32, 48); // 把npc48.png切分成若干32×48px的小人