mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-01-19 20:59:37 +08:00
修正伤害计算
This commit is contained in:
parent
c25f0d7c15
commit
553a589236
@ -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
|
||||||
};
|
};
|
||||||
|
@ -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++;
|
||||||
}
|
}
|
@ -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;
|
||||||
|
3
src/types/enemy.d.ts
vendored
3
src/types/enemy.d.ts
vendored
@ -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
2
src/types/map.d.ts
vendored
@ -39,6 +39,8 @@ interface Block<N extends Exclude<AllNumbers, 0> = Exclude<AllNumbers, 0>> {
|
|||||||
*/
|
*/
|
||||||
id: N;
|
id: N;
|
||||||
|
|
||||||
|
disable: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 事件信息
|
* 事件信息
|
||||||
*/
|
*/
|
||||||
|
2
src/types/status.d.ts
vendored
2
src/types/status.d.ts
vendored
@ -608,7 +608,7 @@ interface InitGameStatus {
|
|||||||
/**
|
/**
|
||||||
* 伤害显示信息
|
* 伤害显示信息
|
||||||
*/
|
*/
|
||||||
damage: DeepReadonly<DamageStatus>;
|
damage: DamageStatus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否锁定了用户控制
|
* 是否锁定了用户控制
|
||||||
|
2
src/types/util.d.ts
vendored
2
src/types/util.d.ts
vendored
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user