删除不同位置攻击怪物伤害不同的机制

This commit is contained in:
unanmed 2023-08-02 10:43:00 +08:00
parent b14e4edcc7
commit 4999452cb6
11 changed files with 79 additions and 353 deletions

View File

@ -2822,6 +2822,7 @@ control.prototype.getRealStatus = function (name) {
////// 从status中获得实际属性增幅后的如果不存在则从勇士属性中获取 ////// ////// 从status中获得实际属性增幅后的如果不存在则从勇士属性中获取 //////
control.prototype.getRealStatusOrDefault = function (status, name) { control.prototype.getRealStatusOrDefault = function (status, name) {
// todo: 删除
return core.plugin.hero.getHeroStatusOf(status, name); return core.plugin.hero.getHeroStatusOf(status, name);
}; };

View File

@ -331,6 +331,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = {
}, },
enemys: { enemys: {
getSpecials: function () { getSpecials: function () {
// todo: 重写
// 获得怪物的特殊属性,每一行定义一个特殊属性。 // 获得怪物的特殊属性,每一行定义一个特殊属性。
// 分为五项,第一项为该特殊属性的数字,第二项为特殊属性的名字,第三项为特殊属性的描述 // 分为五项,第一项为该特殊属性的数字,第二项为特殊属性的名字,第三项为特殊属性的描述
// 第四项为该特殊属性的颜色,可以写十六进制 #RRGGBB 或者 [r,g,b,a] 四元数组 // 第四项为该特殊属性的颜色,可以写十六进制 #RRGGBB 或者 [r,g,b,a] 四元数组

View File

@ -1,10 +1,4 @@
import { import { DamageEnemy, ensureFloorDamage, getSingleEnemy } from './damage';
DamageDir,
DamageEnemy,
ensureFloorDamage,
getNeedCalDir,
getSingleEnemy
} from './damage';
import { findDir, has } from '../utils'; import { findDir, has } from '../utils';
export interface CurrentEnemy { export interface CurrentEnemy {
@ -31,32 +25,23 @@ export function getEnemy(
core.enemys.canBattle = function ( core.enemys.canBattle = function (
x: number, x: number,
y: number, y: number,
floorId: FloorIds = core.status.floorId, floorId: FloorIds = core.status.floorId
dir: DamageDir | DamageDir[] = getNeedCalDir(x, y, floorId)
) { ) {
const enemy = getEnemy(x, y, floorId); const enemy = getEnemy(x, y, floorId);
const damage = enemy.calEnemyDamage(core.status.hero, dir); const { damage } = enemy.calDamage();
return damage < core.status.hero.hp;
return damage.some(v => {
return v.damage < core.status.hero.hp;
});
}; };
core.events.battle = function ( core.events.battle = function (
x: number, x: number,
y: number, y: number,
dir: DamageDir,
force: boolean = false, force: boolean = false,
callback?: () => void callback?: () => void
) { ) {
core.saveAndStopAutomaticRoute(); core.saveAndStopAutomaticRoute();
const enemy = getEnemy(x, y); const enemy = getEnemy(x, y);
// 非强制战斗 // 非强制战斗
if ( if (!core.enemys.canBattle(x, y) && !force && !core.status.event.id) {
!core.enemys.canBattle(x, y, void 0, dir) &&
!force &&
!core.status.event.id
) {
core.stopSound(); core.stopSound();
core.playSound('操作失败'); core.playSound('操作失败');
core.drawTip('你打不过此怪物!', enemy.id); core.drawTip('你打不过此怪物!', enemy.id);
@ -65,10 +50,10 @@ core.events.battle = function (
// 自动存档 // 自动存档
if (!core.status.event.id) core.autosave(true); if (!core.status.event.id) core.autosave(true);
// 战前事件 // 战前事件
if (!this.beforeBattle(enemy, x, y, dir)) if (!this.beforeBattle(enemy, x, y))
return core.clearContinueAutomaticRoute(callback); return core.clearContinueAutomaticRoute(callback);
// 战后事件 // 战后事件
this.afterBattle(enemy, x, y, dir); this.afterBattle(enemy, x, y);
callback?.(); callback?.();
}; };
@ -79,8 +64,7 @@ core.events.beforeBattle = function () {
core.events.afterBattle = function ( core.events.afterBattle = function (
enemy: DamageEnemy, enemy: DamageEnemy,
x?: number, x?: number,
y?: number, y?: number
dir: DamageDir = 'none'
) { ) {
const floorId = core.status.floorId; const floorId = core.status.floorId;
const special = enemy.info.special; const special = enemy.info.special;
@ -96,7 +80,7 @@ core.events.afterBattle = function (
if (!core.material.animates[animate]?.se) core.playSound('attack.mp3'); if (!core.material.animates[animate]?.se) core.playSound('attack.mp3');
// 战斗伤害 // 战斗伤害
const info = enemy.calEnemyDamage(core.status.hero, dir)[0]; const info = enemy.calDamage(core.status.hero);
const damage = info.damage; const damage = info.damage;
// 判定是否致死 // 判定是否致死
if (damage >= core.status.hero.hp) { if (damage >= core.status.hero.hp) {
@ -238,8 +222,7 @@ core.events._sys_battle = function (data: Block, callback?: () => void) {
core.insertAction(beforeBattle, data.x, data.y, callback); core.insertAction(beforeBattle, data.x, data.y, callback);
} }
} else { } else {
const dir = findDir(data, core.status.hero.loc) as DamageDir; this.battle(data.x, data.y, false, callback);
this.battle(data.x, data.y, dir, false, callback);
} }
}; };
@ -253,11 +236,7 @@ core.events._action_battle = function (data, x, y, prefix) {
return; return;
} }
const [ex, ey] = this.__action_getLoc(data.loc, x, y, prefix) as LocArr; const [ex, ey] = this.__action_getLoc(data.loc, x, y, prefix) as LocArr;
const dir = findDir(core.status.hero.loc, { this.battle(ex, ey, true, core.doAction);
x: ex,
y: ey
}) as DamageDir;
this.battle(ex, ey, dir, true, core.doAction);
} }
}; };
@ -285,28 +264,16 @@ core.enemys.getCurrentEnemys = function (floorId = core.status.floorId) {
}); });
return enemys.sort((a, b) => { return enemys.sort((a, b) => {
return ( const ad = a.enemy.calDamage().damage;
(a.enemy.damage?.[0]?.damage ?? Infinity) - const bd = b.enemy.calDamage().damage;
(b.enemy.damage?.[0]?.damage ?? Infinity) return ad - bd;
);
}); });
}; };
declare global { declare global {
interface Events { interface Events {
beforeBattle( beforeBattle(enemy: DamageEnemy, x: number, y: number): boolean;
enemy: DamageEnemy, afterBattle(enemy: DamageEnemy, x: number, y: number): void;
x: number,
y: number,
dir: DamageDir
): boolean;
afterBattle(
enemy: DamageEnemy,
x: number,
y: number,
dir: DamageDir
): void;
} }
interface Enemys { interface Enemys {

View File

@ -17,7 +17,7 @@ control.prototype.checkBlock = function (forceMockery: boolean = false) {
); );
} }
core.status.hero.hp -= damage; core.status.hero.hp -= damage;
const type = Array.from(info.type.keys()); const type = [...info.type];
const text = type.join('') || '伤害'; const text = type.join('') || '伤害';
core.drawTip('受到' + text + damage + '点'); core.drawTip('受到' + text + damage + '点');
core.drawHeroAnimate('zone'); core.drawHeroAnimate('zone');

View File

@ -1,4 +1,3 @@
import { equal } from '../utils';
import { getHeroStatusOf, getHeroStatusOn } from '../hero'; import { getHeroStatusOf, getHeroStatusOn } from '../hero';
import { Range, RangeCollection } from '../range'; import { Range, RangeCollection } from '../range';
import { import {
@ -36,10 +35,6 @@ interface EnemyInfo {
interface DamageInfo { interface DamageInfo {
damage: number; damage: number;
/** 从怪物位置指向勇士的方向 */
dir: Dir | 'none';
x?: number;
y?: number;
/** 自动切换技能时使用的技能 */ /** 自动切换技能时使用的技能 */
skill?: number; skill?: number;
} }
@ -58,12 +53,9 @@ interface HaloData<T extends keyof HaloType = keyof HaloType> {
} }
interface DamageDelta { interface DamageDelta {
dir: DamageDir;
/** 跟最小伤害值的减伤 */ /** 跟最小伤害值的减伤 */
delta: number; delta: number;
damage: number; damage: number;
/** 跟当前方向的减伤 */
dirDelta: number;
info: DamageInfo; info: DamageInfo;
} }
@ -73,7 +65,6 @@ interface CriticalDamageDelta extends Omit<DamageDelta, 'info'> {
} }
type HaloFn = (info: EnemyInfo, enemy: Enemy) => void; type HaloFn = (info: EnemyInfo, enemy: Enemy) => void;
export type DamageDir = Dir | 'none';
/** 光环属性 */ /** 光环属性 */
export const haloSpecials: number[] = [8, 21, 25, 26, 27]; export const haloSpecials: number[] = [8, 21, 25, 26, 27];
@ -129,10 +120,10 @@ export class EnemyCollection implements RangeCollection<DamageEnemy> {
* *
* @param noCache 使 * @param noCache 使
*/ */
calDamage(noCache: boolean = false, onMap: boolean = false) { calDamage(noCache: boolean = false) {
if (noCache) this.calRealAttribute(); if (noCache) this.calRealAttribute();
this.list.forEach(v => { this.list.forEach(v => {
v.calDamage(void 0, onMap); v.calDamage(void 0);
}); });
} }
@ -141,12 +132,7 @@ export class EnemyCollection implements RangeCollection<DamageEnemy> {
*/ */
calMapDamage() { calMapDamage() {
this.mapDamage = {}; this.mapDamage = {};
const hero = getHeroStatusOn( const hero = getHeroStatusOn(realStatus, this.floorId);
realStatus,
core.status.hero.loc.x,
core.status.hero.loc.y,
this.floorId
);
this.list.forEach(v => { this.list.forEach(v => {
v.calMapDamage(this.mapDamage, hero); v.calMapDamage(this.mapDamage, hero);
}); });
@ -192,15 +178,8 @@ export class EnemyCollection implements RangeCollection<DamageEnemy> {
}); });
} }
render(onMap?: boolean): void; render(onMap: boolean = false, cal: boolean = false) {
render(onMap: boolean, cal: boolean, noCache: boolean): void;
render(
onMap: boolean = false,
cal: boolean = false,
noCache: boolean = false
) {
if (cal) { if (cal) {
this.calDamage(noCache, true);
this.calMapDamage(); this.calMapDamage();
} }
core.status.damage.data = []; core.status.damage.data = [];
@ -211,72 +190,23 @@ export class EnemyCollection implements RangeCollection<DamageEnemy> {
this.list.forEach(v => { this.list.forEach(v => {
if (onMap && !checkV2(v.x, v.y)) return; if (onMap && !checkV2(v.x, v.y)) return;
if (!v.damage) { const { damage } = v.calDamage();
throw new Error(
`Unexpected null of enemy's damage. Loc: '${v.x},${v.y}'. Floor: ${v.floorId}`
);
}
if (equal(v.damage, 'damage')) {
// 伤害全部相等,绘制在怪物本身所在位置
const { damage, color } = formatDamage(v.damage[0].damage);
const critical = v.calCritical(1)[0]?.[0];
core.status.damage.data.push({
text: damage,
px: 32 * v.x! + 1,
py: 32 * (v.y! + 1) - 1,
color: color
});
core.status.damage.data.push({
text: critical?.atkDelta.toString() ?? '?',
px: 32 * v.x! + 1,
py: 32 * (v.y! + 1) - 11,
color: '#fff'
});
} else {
let min = v.damage[0].damage;
let max = min;
let minI = 0;
for (let i = 1; i < v.damage.length; i++) {
const dam = v.damage[i].damage;
if (dam < min) {
min = dam;
minI = i;
}
if (dam > max) {
max = dam;
}
}
const delta = max - min;
const { damage, color } = formatDamage(min);
// 在怪物位置绘制最低的伤害
core.status.damage.data.push({
text: damage,
px: 32 * v.x! + 1,
py: 32 * (v.y! + 1) - 1,
color: color
});
// 绘制临界
const critical = v.calCritical(1, v.damage[minI].dir)[0]?.[0];
core.status.damage.data.push({
text: critical?.atkDelta.toString() ?? '?',
px: 32 * v.x! + 1,
py: 32 * (v.y! + 1) - 11,
color: '#fff'
});
// 然后根据位置依次绘制对应位置的伤害
for (const dam of v.damage) {
if (dam.dir === 'none') continue;
const d = ((dam.damage - min) / delta) * 255;
const color = core.arrayToRGB([d, 255 - d, 0]);
core.status.damage.dir.push({ // 伤害全部相等,绘制在怪物本身所在位置
x: v.x!, const { damage: dam, color } = formatDamage(damage);
y: v.y!, const critical = v.calCritical(1)[0];
dir: dam.dir, core.status.damage.data.push({
color: color text: dam,
}); px: 32 * v.x! + 1,
} py: 32 * (v.y! + 1) - 1,
} color: color
});
core.status.damage.data.push({
text: critical?.atkDelta.toString() ?? '?',
px: 32 * v.x! + 1,
py: 32 * (v.y! + 1) - 11,
color: '#fff'
});
}); });
// 地图伤害 // 地图伤害
@ -362,10 +292,6 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
* -> provide inject -> -> * -> provide inject -> ->
*/ */
info!: EnemyInfo; info!: EnemyInfo;
/** 怪物伤害 */
damage?: DamageInfo[];
/** 是否需要计算伤害 */
needCalDamage: boolean = true;
/** 向其他怪提供过的光环 */ /** 向其他怪提供过的光环 */
providedHalo: number[] = []; providedHalo: number[] = [];
@ -409,7 +335,6 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
floorId: this.floorId floorId: this.floorId
}; };
this.progress = 0; this.progress = 0;
this.needCalDamage = true;
this.providedHalo = []; this.providedHalo = [];
} }
@ -578,17 +503,9 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
/** /**
* *
*/ */
calDamage( calDamage(hero: Partial<HeroStatus> = core.status.hero) {
hero: Partial<HeroStatus> = core.status.hero, const enemy = this.getRealInfo();
onMap: boolean = false return this.calEnemyDamageOf(hero, enemy);
) {
if (onMap && !checkV2(this.x, this.y)) return this.damage!;
if (!this.needCalDamage) return this.damage!;
const dirs = getNeedCalDir(this.x, this.y, this.floorId, hero);
this.needCalDamage = false;
return (this.damage = this.calEnemyDamage(hero, dirs));
} }
/** /**
@ -695,44 +612,8 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
damage[loc].type.add(type); damage[loc].type.add(type);
} }
calEnemyDamage( private calEnemyDamageOf(hero: Partial<HeroStatus>, enemy: EnemyInfo) {
hero: Partial<HeroStatus> = core.status.hero, const status = getHeroStatusOf(hero, realStatus, this.floorId);
dir: DamageDir | DamageDir[]
): DamageInfo[] {
const dirs = ensureArray(dir);
const enemy = this.getRealInfo();
return dirs.map(dir => {
let x: number | undefined;
let y: number | undefined;
if (has(this.x) && has(this.y)) {
if (dir !== 'none') {
[x, y] = ofDir(this.x, this.y, dir);
} else {
x = hero.x ?? this.x;
y = hero.y ?? this.y;
}
}
const { damage, skill } = this.calEnemyDamageOf(hero, enemy, x, y);
return {
damage,
dir,
skill,
x,
y
};
});
}
private calEnemyDamageOf(
hero: Partial<HeroStatus>,
enemy: EnemyInfo,
x?: number,
y?: number
) {
const status = getHeroStatusOf(hero, realStatus, x, y, this.floorId);
let damage = calDamageWith(enemy, status) ?? Infinity; let damage = calDamageWith(enemy, status) ?? Infinity;
let skill = -1; let skill = -1;
@ -765,27 +646,11 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
*/ */
calCritical( calCritical(
num: number = 1, num: number = 1,
dir: DamageDir | DamageDir[] = 'none',
hero: Partial<HeroStatus> = core.status.hero hero: Partial<HeroStatus> = core.status.hero
): CriticalDamageDelta[][] { ): CriticalDamageDelta[] {
const origin = this.calEnemyDamage(hero, dir); const origin = this.calDamage(hero);
const min = Math.min(...origin.map(v => v.damage));
const seckill = this.getSeckillAtk(); const seckill = this.getSeckillAtk();
return this.calCriticalWith(num, seckill, origin, hero);
return origin.map(v => {
const dir = v.dir;
if (
dir === 'none' ||
!has(this.x) ||
!has(this.y) ||
!has(this.floorId)
) {
return this.calCriticalWith(num, min, seckill, v, hero);
} else {
const [x, y] = ofDir(this.x, this.y, dir);
return this.calCriticalWith(num, min, seckill, v, hero, x, y);
}
});
} }
/** /**
@ -797,12 +662,9 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
*/ */
private calCriticalWith( private calCriticalWith(
num: number, num: number,
min: number,
seckill: number, seckill: number,
origin: DamageInfo, origin: DamageInfo,
hero: Partial<HeroStatus>, hero: Partial<HeroStatus>
x?: number,
y?: number
): CriticalDamageDelta[] { ): CriticalDamageDelta[] {
// todo: 可以优化,根据之前的计算可以直接确定下一个临界的范围 // todo: 可以优化,根据之前的计算可以直接确定下一个临界的范围
if (!isFinite(seckill)) return []; if (!isFinite(seckill)) return [];
@ -819,8 +681,7 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
let ori = origin.damage; let ori = origin.damage;
const calDam = () => { const calDam = () => {
return this.calEnemyDamageOf({ atk: curr, def }, enemy, x, y) return this.calEnemyDamageOf({ atk: curr, def }, enemy).damage;
.damage;
}; };
let i = 0; let i = 0;
@ -835,9 +696,7 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
res.push({ res.push({
damage: dam, damage: dam,
atkDelta: Math.ceil(v - hero.atk!), atkDelta: Math.ceil(v - hero.atk!),
dir: origin.dir, delta: dam - ori
delta: dam - min,
dirDelta: dam - origin.damage
}); });
start = v; start = v;
@ -872,9 +731,7 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
res.push({ res.push({
damage: dam, damage: dam,
atkDelta: 0, atkDelta: 0,
dir: origin.dir, delta: 0
delta: dam - min,
dirDelta: 0
}); });
} }
@ -889,26 +746,19 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
*/ */
calDefDamage( calDefDamage(
num: number = 1, num: number = 1,
dir: DamageDir | DamageDir[] = 'none',
hero: Partial<HeroStatus> = core.status.hero hero: Partial<HeroStatus> = core.status.hero
): DamageDelta[] { ): DamageDelta {
const damage = this.calEnemyDamage( const damage = this.calDamage({
{ def: (hero.def ?? core.status.hero.def) + num }, def: (hero.def ?? core.status.hero.def) + num
dir
);
const origin = this.calEnemyDamage(hero, dir);
const min = Math.min(...origin.map(v => v.damage));
return damage.map((v, i) => {
const finite = isFinite(v.damage);
return {
dir: v.dir,
damage: v.damage,
info: v,
delta: finite ? v.damage - min : Infinity,
dirDelta: finite ? v.damage - origin[i].damage : Infinity
};
}); });
const origin = this.calDamage(hero);
const finite = isFinite(damage.damage);
return {
damage: damage.damage,
info: damage,
delta: finite ? damage.damage - origin.damage : Infinity
};
} }
/** /**
@ -923,7 +773,7 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
return Infinity; return Infinity;
} }
// 列方程求解 // 列方程求解,拿笔算一下就知道了
// 饥渴,会偷取勇士攻击 // 饥渴,会偷取勇士攻击
if (info.special.includes(7)) { if (info.special.includes(7)) {
if (info.damageDecline === 0) { if (info.damageDecline === 0) {
@ -971,47 +821,6 @@ const skills: [unlock: string, condition: string][] = [
['shieldOn', 'shield'] ['shieldOn', 'shield']
]; ];
/**
*
* @param x
* @param y
* @param floorId
* @returns
*/
export function getNeedCalDir(
x?: number,
y?: number,
floorId?: FloorIds,
hero: Partial<HeroStatus> = core.status.hero
): (Dir | 'none')[] {
// 第一章或序章,或者没有指定怪物位置,或者没开自动定位,用不到这个函数
if (flags.chapter < 2 || !has(x) || !has(y) || !floorId) {
return ['none'];
}
// 如果指定了勇士坐标
if (has(hero.x) && has(hero.y)) {
return ['none'];
}
const needMap: Dir[] = ['left', 'down', 'right', 'up'];
const { width, height } = core.status.maps[floorId];
const blocks = core.getMapBlocksObj(floorId);
const res = needMap.filter(v => {
const [tx, ty] = ofDir(x, y, v);
if (tx < 0 || ty < 0 || tx >= width || ty >= height) return false;
const index = `${tx},${ty}` as LocString;
if (!core.canMoveHero(tx, ty, backDir(v), floorId)) return false;
const block = blocks[index];
if (!block) return true;
if (block.event.noPass || block.event.cls === 'items') return false;
return true;
});
return res.length === 0 ? ['none'] : res;
}
/** /**
* *
* @param info * @param info
@ -1123,7 +932,7 @@ export function getSingleEnemy(id: EnemyIds) {
const enemy = new DamageEnemy(e); const enemy = new DamageEnemy(e);
enemy.calAttribute(); enemy.calAttribute();
enemy.getRealInfo(); enemy.getRealInfo();
enemy.calDamage(core.status.hero, false)[0]; enemy.calDamage(core.status.hero);
return enemy; return enemy;
} }

View File

@ -19,7 +19,7 @@ core.control.updateDamage = function (floorId = core.status.floorId, ctx) {
ensureFloorDamage(floorId); ensureFloorDamage(floorId);
floor.enemy.extract(); floor.enemy.extract();
floor.enemy.calDamage(true, onMap); floor.enemy.calDamage(true);
floor.enemy.calMapDamage(); floor.enemy.calMapDamage();
core.status.damage.data = []; core.status.damage.data = [];

View File

@ -1,5 +1,4 @@
import { getEnemy } from '../enemy/battle'; import { getEnemy } from '../enemy/battle';
import { DamageDir, getNeedCalDir } from '../enemy/damage';
import { formatDamage } from '../utils'; import { formatDamage } from '../utils';
core.maps._initDetachedBlock = function ( core.maps._initDetachedBlock = function (
@ -37,16 +36,8 @@ core.maps._initDetachedBlock = function (
displayDamage displayDamage
) { ) {
const enemy = getEnemy(x, y); const enemy = getEnemy(x, y);
const dam = enemy.calEnemyDamage(core.status.hero, getNeedCalDir(x, y)); const dam = enemy.calDamage();
let min = Infinity; const { damage, color } = formatDamage(dam.damage);
let minDir: DamageDir = 'none';
for (const d of dam) {
if (d.damage < min) {
min = d.damage;
minDir = d.dir;
}
}
const { damage, color } = formatDamage(min);
damageCanvas = '__damage_' + x + '_' + y; damageCanvas = '__damage_' + x + '_' + y;
const ctx = core.createCanvas(damageCanvas, 0, 0, 32, 32, 65); const ctx = core.createCanvas(damageCanvas, 0, 0, 32, 32, 65);
@ -54,8 +45,8 @@ core.maps._initDetachedBlock = function (
ctx.font = '14px normal'; ctx.font = '14px normal';
core.fillBoldText(ctx, damage, 1, 31, color as string); core.fillBoldText(ctx, damage, 1, 31, color as string);
if (core.flags.displayCritical) { if (core.flags.displayCritical) {
const critical = enemy.calCritical(1, minDir)[0]; const critical = enemy.calCritical(1);
const atk = core.formatBigNumber(critical[0].dirDelta, true); const atk = core.formatBigNumber(critical[0]?.delta, true);
const display = atk === '???' ? '?' : atk; const display = atk === '???' ? '?' : atk;
core.fillBoldText(ctx, display, 1, 21, '#FFFFFF'); core.fillBoldText(ctx, display, 1, 21, '#FFFFFF');
} }

View File

@ -5,32 +5,21 @@
* @param y * @param y
* @param floorId * @param floorId
*/ */
export function getHeroStatusOn( export function getHeroStatusOn(name: 'all', floorId?: FloorIds): HeroStatus;
name: 'all',
x?: number,
y?: number,
floorId?: FloorIds
): HeroStatus;
export function getHeroStatusOn( export function getHeroStatusOn(
name: (keyof HeroStatus)[], name: (keyof HeroStatus)[],
x?: number,
y?: number,
floorId?: FloorIds floorId?: FloorIds
): Partial<HeroStatus>; ): Partial<HeroStatus>;
export function getHeroStatusOn<K extends keyof HeroStatus>( export function getHeroStatusOn<K extends keyof HeroStatus>(
name: K, name: K,
x?: number,
y?: number,
floorId?: FloorIds floorId?: FloorIds
): HeroStatus[K]; ): HeroStatus[K];
export function getHeroStatusOn( export function getHeroStatusOn(
name: keyof HeroStatus | 'all' | (keyof HeroStatus)[], name: keyof HeroStatus | 'all' | (keyof HeroStatus)[],
x?: number,
y?: number,
floorId?: FloorIds floorId?: FloorIds
) { ) {
// @ts-ignore // @ts-ignore
return getHeroStatusOf(core.status.hero, name, x, y, floorId); return getHeroStatusOf(core.status.hero, name, floorId);
} }
/** /**
@ -44,44 +33,34 @@ export function getHeroStatusOn(
export function getHeroStatusOf( export function getHeroStatusOf(
status: Partial<HeroStatus>, status: Partial<HeroStatus>,
name: 'all', name: 'all',
x?: number,
y?: number,
floorId?: FloorIds floorId?: FloorIds
): HeroStatus; ): HeroStatus;
export function getHeroStatusOf( export function getHeroStatusOf(
status: Partial<HeroStatus>, status: Partial<HeroStatus>,
name: (keyof HeroStatus)[], name: (keyof HeroStatus)[],
x?: number,
y?: number,
floorId?: FloorIds floorId?: FloorIds
): Partial<HeroStatus>; ): Partial<HeroStatus>;
export function getHeroStatusOf<K extends keyof HeroStatus>( export function getHeroStatusOf<K extends keyof HeroStatus>(
status: Partial<HeroStatus>, status: Partial<HeroStatus>,
name: K, name: K,
x?: number,
y?: number,
floorId?: FloorIds floorId?: FloorIds
): HeroStatus[K]; ): HeroStatus[K];
export function getHeroStatusOf( export function getHeroStatusOf(
status: DeepPartial<HeroStatus>, status: DeepPartial<HeroStatus>,
name: keyof HeroStatus | 'all' | (keyof HeroStatus)[], name: keyof HeroStatus | 'all' | (keyof HeroStatus)[],
x?: number,
y?: number,
floorId?: FloorIds floorId?: FloorIds
) { ) {
return getRealStatus(status, name, x, y, floorId); return getRealStatus(status, name, floorId);
} }
function getRealStatus( function getRealStatus(
status: DeepPartial<HeroStatus>, status: DeepPartial<HeroStatus>,
name: keyof HeroStatus | 'all' | (keyof HeroStatus)[], name: keyof HeroStatus | 'all' | (keyof HeroStatus)[],
x?: number, floorId: FloorIds = core.status.floorId
y?: number,
floorId?: FloorIds
): any { ): any {
if (name instanceof Array) { if (name instanceof Array) {
return Object.fromEntries( return Object.fromEntries(
name.map(v => [v, getRealStatus(status, v, x, y, floorId)]) name.map(v => [v, getRealStatus(status, v, floorId)])
); );
} }
@ -90,7 +69,7 @@ function getRealStatus(
Object.keys(core.status.hero).map(v => [ Object.keys(core.status.hero).map(v => [
v, v,
v !== 'all' && v !== 'all' &&
getRealStatus(status, v as keyof HeroStatus, x, y, floorId) getRealStatus(status, v as keyof HeroStatus, floorId)
]) ])
); );
} }
@ -102,10 +81,6 @@ function getRealStatus(
); );
} }
x ??= core.status.hero.loc.x;
y ??= core.status.hero.loc.y;
floorId ??= core.status.floorId;
// 永夜、极昼 // 永夜、极昼
if (name === 'atk' || name === 'def') { if (name === 'atk' || name === 'def') {
s += window.flags?.[`night_${floorId}`] ?? 0; s += window.flags?.[`night_${floorId}`] ?? 0;

View File

@ -65,13 +65,11 @@ export function getDetailedEnemy(
const ratio = core.status.maps[floorId].ratio; const ratio = core.status.maps[floorId].ratio;
const dam = enemy.calEnemyDamage(core.status.hero, 'none')[0].damage; const dam = enemy.calDamage().damage;
const cri = enemy.calCritical(1, 'none')[0]?.[0]; const cri = enemy.calCritical(1)[0];
const critical = core.formatBigNumber(cri?.atkDelta); const critical = core.formatBigNumber(cri?.atkDelta);
const criticalDam = core.formatBigNumber(cri?.delta); const criticalDam = core.formatBigNumber(cri?.delta);
const defDam = core.formatBigNumber( const defDam = core.formatBigNumber(enemy.calDefDamage(ratio).damage);
enemy.calDefDamage(ratio, 'none')[0].damage
);
const damage = core.formatBigNumber(dam); const damage = core.formatBigNumber(dam);
const fromFunc = ( const fromFunc = (

View File

@ -111,7 +111,6 @@ interface Events extends EventData {
battle( battle(
x: number, x: number,
y: number, y: number,
dir: Dir | 'none',
force: boolean = false, force: boolean = false,
callback?: () => void callback?: () => void
): void; ): void;

17
src/types/plugin.d.ts vendored
View File

@ -363,22 +363,13 @@ interface GamePluginHeroRealStatus {
* @param y * @param y
* @param floorId * @param floorId
*/ */
getHeroStatusOn( getHeroStatusOn(name: 'all', floorId?: FloorIds): HeroStatus;
name: 'all',
x?: number,
y?: number,
floorId?: FloorIds
): HeroStatus;
getHeroStatusOn( getHeroStatusOn(
name: (keyof HeroStatus)[], name: (keyof HeroStatus)[],
x?: number,
y?: number,
floorId?: FloorIds floorId?: FloorIds
): Partial<HeroStatus>; ): Partial<HeroStatus>;
getHeroStatusOn<K extends keyof HeroStatus>( getHeroStatusOn<K extends keyof HeroStatus>(
name: K, name: K,
x?: number,
y?: number,
floorId?: FloorIds floorId?: FloorIds
): HeroStatus[K]; ): HeroStatus[K];
@ -393,22 +384,16 @@ interface GamePluginHeroRealStatus {
getHeroStatusOf( getHeroStatusOf(
status: Partial<HeroStatus>, status: Partial<HeroStatus>,
name: 'all', name: 'all',
x?: number,
y?: number,
floorId?: FloorIds floorId?: FloorIds
): HeroStatus; ): HeroStatus;
getHeroStatusOf( getHeroStatusOf(
status: Partial<HeroStatus>, status: Partial<HeroStatus>,
name: (keyof HeroStatus)[], name: (keyof HeroStatus)[],
x?: number,
y?: number,
floorId?: FloorIds floorId?: FloorIds
): Partial<HeroStatus>; ): Partial<HeroStatus>;
getHeroStatusOf<K extends keyof HeroStatus>( getHeroStatusOf<K extends keyof HeroStatus>(
status: Partial<HeroStatus>, status: Partial<HeroStatus>,
name: K, name: K,
x?: number,
y?: number,
floorId?: FloorIds floorId?: FloorIds
): HeroStatus[K]; ): HeroStatus[K];
} }