mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-01-18 11:59:26 +08:00
伤害计算
This commit is contained in:
parent
b72bf33815
commit
16d8e35a81
12
idea.md
12
idea.md
@ -2,14 +2,11 @@
|
||||
|
||||
### 第二章 智慧
|
||||
|
||||
- 怪物拥有火、水等属性,在不同天气下属性不同
|
||||
|
||||
- 同化
|
||||
- 同化+阻击
|
||||
- 电摇嘲讽:到同行或同列直接怼过去,门和墙撞碎,不消耗钥匙,攻击怪物,捡道具,改变 bgm,可吃补给用
|
||||
- 抢夺:抢夺你的装备并使用(简单难度中,怪物使用时属性降低)
|
||||
- 抢夺 2.0:抢夺你的道具(怪物手册和楼传除外),并按照左上、右上、右下、左下的顺序依次放到地图的四角(简单无效)
|
||||
- 抢夺 3.0:抢夺装备,但每过 10 回合便按照 2.0 方法扔至地图四角(因为怪物觉得装备不好使),然后重新抢夺你的装备(简单无效)
|
||||
- 乾坤挪移:平移光环位置
|
||||
- 加光环的光环
|
||||
|
||||
#### Boss
|
||||
|
||||
@ -19,7 +16,6 @@
|
||||
|
||||
## 主角
|
||||
|
||||
- 反抢夺:1 级反 1.0,2 级反 2.0,3 级反 3.0,用智慧点点
|
||||
- 学习:学习选定怪物的选定技能(不能学光环),消耗智慧点,初始 400,但每次消耗点数+100,持续 3 场战斗
|
||||
- 铸剑为盾:主动技能,减少攻击,增加防御
|
||||
- 血之代偿:消耗一定血量,战前对怪物造成同等数值的伤害
|
||||
@ -48,13 +44,13 @@
|
||||
|
||||
### 第二章 智慧
|
||||
|
||||
- 按下一个开关,所有红门变黄门,黄门变蓝门,蓝门变红门
|
||||
- 苍蓝之殿 1: 利用点光源,照到的位置与没照到的位置内容不同,玩家可以选择是否装备手电筒
|
||||
- 苍蓝之殿 2:
|
||||
|
||||
## 成就
|
||||
|
||||
- 虚惊一场:打完山洞门口的怪只剩 1 滴血
|
||||
- 学坏了:学习敌人的电摇嘲讽技能
|
||||
- 我就是傻子:不学习反抢夺通过第二章
|
||||
- 真能刷:勇气之路的刷血怪刷到 15w 以上的血
|
||||
- 满腹经纶:把所有能学的怪物技能都学一遍
|
||||
- 冰与火之舞:通过第二章特殊战的困难难度
|
||||
|
@ -33,6 +33,17 @@ interface DamageInfo {
|
||||
skill?: number;
|
||||
}
|
||||
|
||||
interface MapDamage {
|
||||
damage: number;
|
||||
type: string[];
|
||||
}
|
||||
|
||||
interface HaloData<T extends keyof HaloType = keyof HaloType> {
|
||||
type: T;
|
||||
data: HaloType[T];
|
||||
from: DamageEnemy;
|
||||
}
|
||||
|
||||
type HaloFn = (info: EnemyInfo, enemy: Enemy) => void;
|
||||
|
||||
export const haloSpecials: number[] = [21, 25, 26, 27];
|
||||
@ -42,6 +53,8 @@ export class EnemyCollection implements RangeCollection<DamageEnemy> {
|
||||
list: DamageEnemy[] = [];
|
||||
|
||||
range: Range<DamageEnemy> = new Range(this);
|
||||
mapDamage: Record<string, MapDamage> = {};
|
||||
haloList: HaloData[] = [];
|
||||
|
||||
constructor(floorId: FloorIds) {
|
||||
this.floorId = floorId;
|
||||
@ -52,13 +65,36 @@ export class EnemyCollection implements RangeCollection<DamageEnemy> {
|
||||
core.status.maps[this.floorId].blocks.forEach(v => {
|
||||
if (v.event.cls !== 'enemy48' && v.event.cls !== 'enemys') return;
|
||||
const enemy = core.material.enemys[v.event.id as EnemyIds];
|
||||
this.list.push(new DamageEnemy(enemy));
|
||||
this.list.push(
|
||||
new DamageEnemy(enemy, v.x, v.y, this.floorId, this)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
calAttribute(noCache: boolean = false) {}
|
||||
/**
|
||||
* 计算怪物真实属性
|
||||
* @param noCache 是否不使用缓存
|
||||
*/
|
||||
calRealAttribute(noCache: boolean = false) {
|
||||
this.list.forEach(v => {
|
||||
if (noCache) v.reset();
|
||||
v.calRealAttribute();
|
||||
});
|
||||
}
|
||||
|
||||
calDamage(noCache: boolean = false) {}
|
||||
/**
|
||||
* 计算怪物伤害
|
||||
* @param noCache 是否不使用缓存
|
||||
*/
|
||||
calDamage(noCache: boolean = false) {
|
||||
this.list.forEach(v => {
|
||||
if (noCache || v.needCalculate) {
|
||||
v.reset();
|
||||
v.calRealAttribute();
|
||||
}
|
||||
v.calDamage();
|
||||
});
|
||||
}
|
||||
|
||||
calMapDamage(noCache: boolean = false) {}
|
||||
|
||||
@ -109,6 +145,7 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
|
||||
y?: number;
|
||||
floorId?: FloorIds;
|
||||
enemy: Enemy<T>;
|
||||
col?: EnemyCollection;
|
||||
|
||||
/**
|
||||
* 怪物属性。
|
||||
@ -126,12 +163,19 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
|
||||
/** 向其他怪提供过的光环 */
|
||||
providedHalo: number[] = [];
|
||||
|
||||
constructor(enemy: Enemy<T>, x?: number, y?: number, floorId?: FloorIds) {
|
||||
constructor(
|
||||
enemy: Enemy<T>,
|
||||
x?: number,
|
||||
y?: number,
|
||||
floorId?: FloorIds,
|
||||
col?: EnemyCollection
|
||||
) {
|
||||
this.id = enemy.id;
|
||||
this.enemy = enemy;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.floorId = floorId;
|
||||
this.col = col;
|
||||
this.reset();
|
||||
}
|
||||
|
||||
@ -221,6 +265,16 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
|
||||
return this.info;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算真实属性
|
||||
*/
|
||||
calRealAttribute() {
|
||||
this.preProvideHalo();
|
||||
this.calAttribute();
|
||||
this.provideHalo();
|
||||
this.getRealInfo();
|
||||
}
|
||||
|
||||
getHaloSpecials(): number[] {
|
||||
if (!this.floorId) return [];
|
||||
if (!core.has(this.x) || !core.has(this.y)) return [];
|
||||
@ -229,7 +283,7 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
|
||||
return haloSpecials.includes(v) && !this.providedHalo.includes(v);
|
||||
});
|
||||
if (filter.length === 0) return [];
|
||||
const collection = core.status.maps[this.floorId].enemy;
|
||||
const collection = this.col ?? core.status.maps[this.floorId].enemy;
|
||||
if (!collection) {
|
||||
throw new Error(
|
||||
`Unexpected undefined of enemy collection in floor ${this.floorId}.`
|
||||
@ -249,7 +303,8 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
|
||||
provideHalo() {
|
||||
if (!this.floorId) return;
|
||||
if (!core.has(this.x) || !core.has(this.y)) return;
|
||||
const collection = core.status.maps[this.floorId].enemy;
|
||||
const col = this.col ?? core.status.maps[this.floorId].enemy;
|
||||
if (!col) return;
|
||||
const speical = this.getHaloSpecials();
|
||||
|
||||
const square7: HaloFn[] = [];
|
||||
@ -286,8 +341,8 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
|
||||
this.providedHalo.push(27);
|
||||
}
|
||||
|
||||
collection.applyHalo('square', { x: this.x, y: this.y, d: 7 }, square7);
|
||||
collection.applyHalo('square', { x: this.x, y: this.y, d: 5 }, square5);
|
||||
col.applyHalo('square', { x: this.x, y: this.y, d: 7 }, square7);
|
||||
col.applyHalo('square', { x: this.x, y: this.y, d: 5 }, square5);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -306,12 +361,14 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
|
||||
const dirs = getNeedCalDir(this.x, this.y, this.floorId, hero);
|
||||
|
||||
const damageCache: Record<string, number> = {};
|
||||
this.needCalDamage = false;
|
||||
|
||||
return (this.damage = dirs.map(dir => {
|
||||
const status = getHeroStatusOf(hero, realStatus);
|
||||
let damage = calDamageWith(info, status) ?? Infinity;
|
||||
let skill = -1;
|
||||
|
||||
// 自动切换技能
|
||||
if (flags.autoSkill) {
|
||||
for (let i = 0; i < skills.length; i++) {
|
||||
const [unlock, condition] = skills[i];
|
||||
@ -332,11 +389,14 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
|
||||
}
|
||||
}
|
||||
|
||||
let x = this.x;
|
||||
let y = this.y;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -391,7 +451,7 @@ export function getNeedCalDir(
|
||||
const { width, height } = core.status.maps[floorId];
|
||||
const blocks = core.getMapBlocksObj(floorId);
|
||||
|
||||
return needMap.filter(v => {
|
||||
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;
|
||||
@ -401,6 +461,7 @@ export function getNeedCalDir(
|
||||
|
||||
return true;
|
||||
});
|
||||
return res.length === 0 ? ['none'] : res;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -477,7 +538,7 @@ export function calDamageWith(
|
||||
|
||||
damage += (turn - 1) * enemyPerDamage;
|
||||
// 无上之盾
|
||||
if (core.hasFlag('superSheild')) {
|
||||
if (flags.superSheild) {
|
||||
damage -= mdef / 10;
|
||||
}
|
||||
// 生命回复
|
||||
|
Loading…
Reference in New Issue
Block a user