修正伤害计算

This commit is contained in:
unanmed 2023-06-30 21:56:54 +08:00
parent c25f0d7c15
commit 553a589236
7 changed files with 64 additions and 27 deletions

View File

@ -1,6 +1,6 @@
import { getHeroStatusOf, getHeroStatusOn } from './hero'; import { getHeroStatusOf, getHeroStatusOn } from './hero';
import { Range, RangeCollection } from './range'; import { Range, RangeCollection } from './range';
import { backDir, ensureArray, has, manhattan, ofDir } from './utils'; import { backDir, checkV2, ensureArray, has, manhattan, ofDir } from './utils';
interface HaloType { interface HaloType {
square: { square: {
@ -90,13 +90,14 @@ export class EnemyCollection implements RangeCollection<DamageEnemy> {
* *
* @param noCache 使 * @param noCache 使
*/ */
calDamage(noCache: boolean = false) { calDamage(noCache: boolean = false, onMap: boolean = false) {
this.list.forEach(v => { this.list.forEach(v => {
if (noCache || v.needCalculate) { if (noCache || v.needCalculate) {
v.reset(); v.reset();
v.calRealAttribute(); v.calRealAttribute();
} }
v.calDamage(); v.calDamage(void 0, onMap);
console.log(v.damage);
}); });
} }
@ -377,7 +378,11 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
/** /**
* *
*/ */
calDamage(hero: Partial<HeroStatus> = core.status.hero) { calDamage(
hero: Partial<HeroStatus> = core.status.hero,
onMap: boolean = false
) {
if (onMap && !checkV2(this.x, this.y)) return this.damage!;
if (!this.needCalDamage) return this.damage!; if (!this.needCalDamage) return this.damage!;
const info = this.getRealInfo(); const info = this.getRealInfo();
const dirs = getNeedCalDir(this.x, this.y, this.floorId, hero); const dirs = getNeedCalDir(this.x, this.y, this.floorId, hero);
@ -580,7 +585,7 @@ export function getNeedCalDir(
if (tx < 0 || ty < 0 || tx >= width || ty >= height) return false; if (tx < 0 || ty < 0 || tx >= width || ty >= height) return false;
const index = `${tx},${ty}` as LocString; const index = `${tx},${ty}` as LocString;
const block = blocks[index]; const block = blocks[index];
if (block.event.noPass) return false; if (!block || block.event.noPass) return false;
if (!core.canMoveHero(tx, ty, backDir(v), floorId)) return false; if (!core.canMoveHero(tx, ty, backDir(v), floorId)) return false;
return true; return true;
@ -641,6 +646,11 @@ export function calDamageWith(
} }
heroPerDamage *= 1 - info.damageDecline; heroPerDamage *= 1 - info.damageDecline;
// 苍蓝刻
if (special.includes(28)) {
heroPerDamage *= 1 - enemy.paleShield! / 100;
}
let turn = Math.ceil(monHp / heroPerDamage); let turn = Math.ceil(monHp / heroPerDamage);
// 致命一击 // 致命一击
@ -672,9 +682,9 @@ export function calDamageWith(
return damage; return damage;
} }
export function initFloorDamage(floorId: FloorIds) { export function ensureFloorDamage(floorId: FloorIds) {
const floor = core.status.maps[floorId]; const floor = core.status.maps[floorId];
floor.enemy = new EnemyCollection(floorId); floor.enemy ??= new EnemyCollection(floorId);
} }
declare global { declare global {
@ -682,7 +692,7 @@ declare global {
damage: { damage: {
Enemy: typeof DamageEnemy; Enemy: typeof DamageEnemy;
Collection: typeof EnemyCollection; Collection: typeof EnemyCollection;
initFloorDamage: typeof initFloorDamage; ensureFloorDamage: typeof ensureFloorDamage;
}; };
} }
@ -694,5 +704,5 @@ declare global {
core.plugin.damage = { core.plugin.damage = {
Enemy: DamageEnemy, Enemy: DamageEnemy,
Collection: EnemyCollection, Collection: EnemyCollection,
initFloorDamage ensureFloorDamage
}; };

View File

@ -1,10 +1,9 @@
///<reference path="../../../src/types/core.d.ts" />
export {}; export {};
core.control.updateDamage = function (floorId, ctx) { core.control.updateDamage = function (floorId = core.status.floorId, ctx) {
floorId = floorId || core.status.floorId; if (!floorId || core.status.gameOver || main.mode !== 'play') return;
if (!floorId || core.status.gameOver || main.mode != 'play') return;
const onMap = ctx == null; const onMap = ctx == null;
const floor = core.status.maps[floorId];
// 没有怪物手册 // 没有怪物手册
if (!core.hasItem('book')) return; if (!core.hasItem('book')) return;
@ -16,20 +15,25 @@ core.control.updateDamage = function (floorId, ctx) {
// 地图过大的缩略图不绘制显伤 // 地图过大的缩略图不绘制显伤
if (width * height > core.bigmap.threshold) return; if (width * height > core.bigmap.threshold) return;
} }
this._updateDamage_damage(floorId, onMap); // 计算伤害
this._updateDamage_extraDamage(floorId, onMap); core.plugin.damage.ensureFloorDamage(floorId);
floor.enemy.calDamage(true, onMap);
core.status.damage.data = [];
// this._updateDamage_damage(floorId, onMap);
// this._updateDamage_extraDamage(floorId, onMap);
getItemDetail(floorId, onMap); // 宝石血瓶详细信息 getItemDetail(floorId, onMap); // 宝石血瓶详细信息
this.drawDamage(ctx); this.drawDamage(ctx);
}; };
// 获取宝石信息 并绘制 // 获取宝石信息 并绘制
function getItemDetail(floorId, onMap) { function getItemDetail(floorId: FloorIds, onMap: boolean) {
if (!core.getFlag('itemDetail')) return; if (!core.getFlag('itemDetail')) return;
floorId ??= core.status.thisMap.floorId; floorId ??= core.status.thisMap.floorId;
let diff = {}; let diff: Record<string | symbol, number | undefined> = {};
const before = core.status.hero; const before = core.status.hero;
const hero = core.clone(core.status.hero); const hero = core.clone(core.status.hero);
const handler = { const handler: ProxyHandler<any> = {
set(target, key, v) { set(target, key, v) {
diff[key] = v - (target[key] || 0); diff[key] = v - (target[key] || 0);
if (!diff[key]) diff[key] = void 0; if (!diff[key]) diff[key] = void 0;
@ -54,14 +58,17 @@ function getItemDetail(floorId, onMap) {
} }
} }
diff = {}; diff = {};
const id = block.event.id; const id = block.event.id as AllIdsOf<'items'>;
const item = core.material.items[id]; const item = core.material.items[id];
if (item.cls === 'equips') { if (item.cls === 'equips') {
// 装备也显示 // 装备也显示
const diff = core.clone(item.equip.value ?? {}); const diff: Record<string, any> = core.clone(
item.equip.value ?? {}
);
const per = item.equip.percentage ?? {}; const per = item.equip.percentage ?? {};
for (const name in per) { for (const name in per) {
diff[name + 'per'] = per[name].toString() + '%'; diff[name + 'per'] =
per[name as SelectKey<HeroStatus, number>].toString() + '%';
} }
drawItemDetail(diff, x, y); drawItemDetail(diff, x, y);
return; return;
@ -69,7 +76,7 @@ function getItemDetail(floorId, onMap) {
// 跟数据统计原理一样 执行效果 前后比较 // 跟数据统计原理一样 执行效果 前后比较
core.setFlag('__statistics__', true); core.setFlag('__statistics__', true);
try { try {
eval(item.itemEffect); eval(item.itemEffect!);
} catch (error) {} } catch (error) {}
drawItemDetail(diff, x, y); drawItemDetail(diff, x, y);
}); });
@ -79,7 +86,7 @@ function getItemDetail(floorId, onMap) {
} }
// 绘制 // 绘制
function drawItemDetail(diff, x, y) { function drawItemDetail(diff: any, x: number, y: number) {
const px = 32 * x + 2, const px = 32 * x + 2,
py = 32 * y + 31; py = 32 * y + 31;
let content = ''; let content = '';
@ -121,7 +128,7 @@ function drawItemDetail(diff, x, y) {
text: content, text: content,
px: px, px: px,
py: py - 10 * i, py: py - 10 * i,
color: color color: color as Color
}); });
i++; i++;
} }

View File

@ -62,6 +62,23 @@ export function manhattan(x1: number, y1: number, x2: number, y2: number) {
return Math.abs(x1 - x2) + Math.abs(y1 - y2); return Math.abs(x1 - x2) + Math.abs(y1 - y2);
} }
/**
* v2
*/
export function checkV2(x?: number, y?: number) {
return (
has(x) &&
has(y) &&
!(
core.bigmap.v2 &&
(x < core.bigmap.posX - core.bigmap.extend ||
x > core.bigmap.posX + core._WIDTH_ + core.bigmap.extend ||
y < core.bigmap.posY - core.bigmap.extend ||
y > core.bigmap.posY + core._HEIGHT_ + core.bigmap.extend)
)
);
}
declare global { declare global {
interface GamePluginUtils { interface GamePluginUtils {
ofDir: typeof ofDir; ofDir: typeof ofDir;

View File

@ -24,7 +24,8 @@ type PartialNumbericEnemyProperty =
| 'ice' | 'ice'
| 'crit' | 'crit'
| 'courage' | 'courage'
| 'charge'; | 'charge'
| 'paleShield';
type BooleanEnemyProperty = type BooleanEnemyProperty =
| 'zoneSquare' | 'zoneSquare'

2
src/types/map.d.ts vendored
View File

@ -39,6 +39,8 @@ interface Block<N extends Exclude<AllNumbers, 0> = Exclude<AllNumbers, 0>> {
*/ */
id: N; id: N;
disable: boolean;
/** /**
* *
*/ */

View File

@ -608,7 +608,7 @@ interface InitGameStatus {
/** /**
* *
*/ */
damage: DeepReadonly<DamageStatus>; damage: DamageStatus;
/** /**
* *

2
src/types/util.d.ts vendored
View File

@ -250,7 +250,7 @@ interface Utils {
* @returns * @returns
*/ */
formatBigNumber<T extends string>(x: T, onMap?: number): T; formatBigNumber<T extends string>(x: T, onMap?: number): T;
formatBigNumber(x: number | string, onMap?: number): string; formatBigNumber(x: number | string, onMap?: number | boolean): string;
/** /**
* @deprecated * @deprecated