mirror of
https://github.com/unanmed/HumanBreak.git
synced 2026-11-13 09:44:30 +08:00
fix: 杀戮光环 & feat: 注册新图块
This commit is contained in:
1 parent
3b064b6322
commit
32f57cafec
21 files changed
+350
-58
No files matched your search
@@ -156,6 +156,116 @@ function init() {
|
||||
core.battle(ex, ey, true, core.doAction);
|
||||
}
|
||||
};
|
||||
|
||||
core.events.afterBattle = function afterBattle(
|
||||
enemy: DamageEnemy,
|
||||
x?: number,
|
||||
y?: number
|
||||
) {
|
||||
const floorId = core.status.floorId;
|
||||
const special = enemy.info.special;
|
||||
|
||||
// 播放战斗动画
|
||||
let animate: AnimationIds = 'hand';
|
||||
// 检查当前装备是否存在攻击动画
|
||||
const equipId = core.getEquip(0);
|
||||
if (equipId && (core.material.items[equipId].equip || {}).animate)
|
||||
animate = core.material.items[equipId].equip.animate;
|
||||
|
||||
// 检查该动画是否存在SE,如果不存在则使用默认音效
|
||||
if (!core.material.animates[animate]?.se) core.playSound('attack.mp3');
|
||||
|
||||
// 战斗伤害
|
||||
const info = enemy.calDamage(core.status.hero);
|
||||
const damage = info.damage;
|
||||
// 判定是否致死
|
||||
if (damage >= core.status.hero.hp) {
|
||||
core.status.hero.hp = 0;
|
||||
core.updateStatusBar(false, true);
|
||||
core.events.lose('战斗失败');
|
||||
return;
|
||||
}
|
||||
|
||||
// 扣减体力值并记录统计数据
|
||||
core.status.hero.hp -= damage;
|
||||
core.status.hero.statistics.battleDamage += damage;
|
||||
core.status.hero.statistics.battle++;
|
||||
|
||||
// 智慧之源
|
||||
if (special.includes(14) && flags.hard === 2) {
|
||||
core.addFlag(
|
||||
'inte_' + floorId,
|
||||
Math.ceil((core.status.hero.mdef / 10) * 0.3) * 10
|
||||
);
|
||||
core.status.hero.mdef -=
|
||||
Math.ceil((core.status.hero.mdef / 10) * 0.3) * 10;
|
||||
}
|
||||
|
||||
// 极昼永夜
|
||||
if (special.includes(22)) {
|
||||
flags[`night_${floorId}`] ??= 0;
|
||||
flags[`night_${floorId}`] -= enemy.info.night!;
|
||||
}
|
||||
if (special.includes(23)) {
|
||||
flags[`night_${floorId}`] ??= 0;
|
||||
flags[`night_${floorId}`] += enemy.info.day;
|
||||
}
|
||||
|
||||
// if (core.plugin.skillTree.getSkillLevel(11) > 0) {
|
||||
// core.plugin.study.declineStudiedSkill();
|
||||
// }
|
||||
|
||||
// 如果是融化怪,需要特殊标记一下
|
||||
if (special.includes(25) && has(x) && has(y)) {
|
||||
flags[`melt_${floorId}`] ??= {};
|
||||
flags[`melt_${floorId}`][`${x},${y}`] = enemy.info.melt;
|
||||
}
|
||||
|
||||
// 获得金币
|
||||
const money = enemy.info.money!;
|
||||
core.status.hero.money += money;
|
||||
core.status.hero.statistics.money += money;
|
||||
|
||||
// 获得经验
|
||||
const exp = enemy.info.exp!;
|
||||
core.status.hero.exp += exp;
|
||||
core.status.hero.statistics.exp += exp;
|
||||
|
||||
const hint =
|
||||
'打败 ' + enemy.enemy.name + ',金币+' + money + ',经验+' + exp;
|
||||
core.drawTip(hint, enemy.id);
|
||||
|
||||
if (core.getFlag('bladeOn') && core.getFlag('blade')) {
|
||||
core.setFlag('blade', false);
|
||||
}
|
||||
if (core.getFlag('shieldOn') && core.getFlag('shield')) {
|
||||
core.setFlag('shield', false);
|
||||
}
|
||||
|
||||
// 事件的处理
|
||||
const todo: MotaEvent = [];
|
||||
|
||||
// 战后事件
|
||||
if (has(core.status.floorId)) {
|
||||
const loc = `${x},${y}` as LocString;
|
||||
todo.push(
|
||||
...(core.floors[core.status.floorId].afterBattle[loc] ?? [])
|
||||
);
|
||||
}
|
||||
todo.push(...(enemy.enemy.afterBattle ?? []));
|
||||
|
||||
// 如果事件不为空,将其插入
|
||||
if (todo.length > 0) core.insertAction(todo, x, y);
|
||||
|
||||
if (has(x) && has(y)) {
|
||||
core.drawAnimate(animate, x, y);
|
||||
core.removeBlock(x, y);
|
||||
} else core.drawHeroAnimate(animate);
|
||||
|
||||
// 如果已有事件正在处理中
|
||||
if (core.status.event.id == null) core.continueAutomaticRoute();
|
||||
else core.clearContinueAutomaticRoute();
|
||||
};
|
||||
}
|
||||
loading.once('coreInit', init);
|
||||
|
||||
|
||||
+101
-11
@@ -8,15 +8,22 @@ import {
|
||||
manhattan
|
||||
} from '@/plugin/game/utils';
|
||||
|
||||
// todo: 光环划分优先级,从而可以实现光环的多级运算
|
||||
|
||||
interface HaloType {
|
||||
square: {
|
||||
x: number;
|
||||
y: number;
|
||||
d: number;
|
||||
};
|
||||
manhattan: {
|
||||
x: number;
|
||||
y: number;
|
||||
d: number;
|
||||
};
|
||||
}
|
||||
|
||||
interface EnemyInfo extends Partial<Enemy> {
|
||||
export interface EnemyInfo extends Partial<Enemy> {
|
||||
atk: number;
|
||||
def: number;
|
||||
hp: number;
|
||||
@@ -62,10 +69,30 @@ interface CriticalDamageDelta extends Omit<DamageDelta, 'info'> {
|
||||
atkDelta: number;
|
||||
}
|
||||
|
||||
type HaloFn = (info: EnemyInfo, enemy: Enemy) => void;
|
||||
type HaloFn = (info: EnemyInfo, enemy: EnemyInfo) => void;
|
||||
|
||||
/** 光环属性 */
|
||||
export const haloSpecials: Set<number> = new Set([8, 21, 25, 26, 27]);
|
||||
export const haloSpecials: Set<number> = new Set([8, 21, 25, 26, 27, 29]);
|
||||
/** 特殊属性对应 */
|
||||
export const specialValue: Map<number, SelectKey<Enemy, number | undefined>[]> =
|
||||
new Map();
|
||||
specialValue
|
||||
.set(1, ['crit'])
|
||||
.set(6, ['n'])
|
||||
.set(7, ['hungry'])
|
||||
.set(8, ['together'])
|
||||
.set(10, ['courage'])
|
||||
.set(11, ['charge'])
|
||||
.set(15, ['value'])
|
||||
.set(18, ['value'])
|
||||
.set(20, ['ice'])
|
||||
.set(21, ['iceHalo'])
|
||||
.set(22, ['night'])
|
||||
.set(23, ['day'])
|
||||
.set(25, ['melt'])
|
||||
.set(26, ['iceCore'])
|
||||
.set(27, ['fireCore'])
|
||||
.set(28, ['paleShield']);
|
||||
|
||||
export class EnemyCollection implements RangeCollection<DamageEnemy> {
|
||||
floorId: FloorIds;
|
||||
@@ -107,6 +134,8 @@ export class EnemyCollection implements RangeCollection<DamageEnemy> {
|
||||
this.haloList = [];
|
||||
this.list.forEach(v => {
|
||||
v.reset();
|
||||
});
|
||||
this.list.forEach(v => {
|
||||
v.preProvideHalo();
|
||||
});
|
||||
this.list.forEach(v => {
|
||||
@@ -150,21 +179,22 @@ export class EnemyCollection implements RangeCollection<DamageEnemy> {
|
||||
applyHalo<K extends keyof HaloType>(
|
||||
type: K,
|
||||
data: HaloType[K],
|
||||
enemy: DamageEnemy,
|
||||
halo: HaloFn | HaloFn[],
|
||||
recursion: boolean = false
|
||||
) {
|
||||
const arr = ensureArray(halo);
|
||||
const enemy = this.range.scan(type, data);
|
||||
const enemys = this.range.scan(type, data);
|
||||
if (!recursion) {
|
||||
arr.forEach(v => {
|
||||
enemy.forEach(e => {
|
||||
e.injectHalo(v, e.enemy);
|
||||
enemys.forEach(e => {
|
||||
e.injectHalo(v, enemy.info);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
enemy.forEach(e => {
|
||||
enemys.forEach(e => {
|
||||
arr.forEach(v => {
|
||||
e.injectHalo(v, e.enemy);
|
||||
e.injectHalo(v, enemy.info);
|
||||
e.preProvideHalo();
|
||||
});
|
||||
});
|
||||
@@ -429,6 +459,66 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
|
||||
preProvideHalo() {
|
||||
if (this.progress !== 0) return;
|
||||
this.progress = 1;
|
||||
if (!this.floorId) return;
|
||||
if (!has(this.x) || !has(this.y)) return;
|
||||
const special = this.getHaloSpecials();
|
||||
const col = this.col ?? core.status.maps[this.floorId!].enemy;
|
||||
|
||||
for (const halo of special) {
|
||||
switch (halo) {
|
||||
case 29: {
|
||||
// 特殊光环
|
||||
const e = this.enemy;
|
||||
const type = 'square';
|
||||
const r = Math.floor(e.haloRange!);
|
||||
const d = r * 2 + 1;
|
||||
const range = { x: this.x, y: this.y, d };
|
||||
|
||||
// 这一句必须放到applyHalo之前
|
||||
this.providedHalo.add(29);
|
||||
|
||||
col.applyHalo(
|
||||
type,
|
||||
range,
|
||||
this,
|
||||
(e, enemy) => {
|
||||
const s = enemy.specialHalo!;
|
||||
|
||||
for (const spe of s) {
|
||||
// 防止重复
|
||||
if (!e.special.includes(spe))
|
||||
e.special.push(spe);
|
||||
}
|
||||
// 如果是自身,就不进行特殊属性数值处理了
|
||||
if (e === this.info) return;
|
||||
// 然后计算特殊属性数值
|
||||
for (const spec of s) {
|
||||
const toChange = specialValue.get(spec);
|
||||
if (!toChange) continue;
|
||||
for (const key of toChange) {
|
||||
// 这种光环应该获取怪物的原始数值,而不是真实数值
|
||||
if (enemy.enemy.specialMultiply) {
|
||||
e[key] ??= 1;
|
||||
e[key] *= enemy[key] ?? 1;
|
||||
} else {
|
||||
e[key] ??= 0;
|
||||
e[key] += enemy[key] ?? 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
// true表示递归计算,视为第一类光环
|
||||
true
|
||||
);
|
||||
col.haloList.push({
|
||||
type: 'square',
|
||||
data: { x: this.x, y: this.y, d },
|
||||
special: 29,
|
||||
from: this
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -504,14 +594,14 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
|
||||
});
|
||||
}
|
||||
|
||||
col.applyHalo('square', { x: this.x, y: this.y, d: 7 }, square7);
|
||||
col.applyHalo('square', { x: this.x, y: this.y, d: 5 }, square5);
|
||||
col.applyHalo('square', { x: this.x, y: this.y, d: 7 }, this, square7);
|
||||
col.applyHalo('square', { x: this.x, y: this.y, d: 5 }, this, square5);
|
||||
}
|
||||
|
||||
/**
|
||||
* 接受其他怪的光环
|
||||
*/
|
||||
injectHalo(halo: HaloFn, enemy: Enemy) {
|
||||
injectHalo(halo: HaloFn, enemy: EnemyInfo) {
|
||||
halo(this.info, enemy);
|
||||
}
|
||||
|
||||
|
||||
+24
-14
@@ -1,13 +1,17 @@
|
||||
import { getHeroStatusOn } from '@/game/hero';
|
||||
import { EnemyInfo } from './damage';
|
||||
|
||||
export interface SpecialDeclaration {
|
||||
code: number;
|
||||
name: string | ((enemy: Enemy) => string);
|
||||
desc: string | ((enemy: Enemy) => string);
|
||||
name: string | ((enemy: EnemyInfo) => string);
|
||||
desc: string | ((enemy: EnemyInfo) => string);
|
||||
color: string;
|
||||
}
|
||||
|
||||
const fromFunc = (func: string | ((enemy: Enemy) => string), enemy: Enemy) => {
|
||||
const fromFunc = (
|
||||
func: string | ((enemy: EnemyInfo) => string),
|
||||
enemy: EnemyInfo
|
||||
) => {
|
||||
return typeof func === 'string' ? func : func(enemy);
|
||||
};
|
||||
|
||||
@@ -209,18 +213,24 @@ export const specials: SpecialDeclaration[] = [
|
||||
code: 29,
|
||||
name: '杀戮光环',
|
||||
desc: enemy => {
|
||||
const special = enemy.special;
|
||||
let str = '<div style="margin-left: 10px">';
|
||||
|
||||
special.forEach(v => {
|
||||
const { name, desc, color } = specials[v];
|
||||
str += `<span style="color:${color}">${fromFunc(
|
||||
name,
|
||||
enemy
|
||||
)}</span><span>${fromFunc(desc, enemy)}</span>`;
|
||||
let content = '';
|
||||
enemy.specialHalo?.forEach((v, i) => {
|
||||
content +=
|
||||
' '.repeat(8) +
|
||||
`${i + 1}. <span style="color: ${
|
||||
specials[v].color
|
||||
}">${fromFunc(specials[v].name, enemy)}</span>: ${fromFunc(
|
||||
specials[v].desc,
|
||||
enemy
|
||||
)}<br />`;
|
||||
});
|
||||
|
||||
return str;
|
||||
return (
|
||||
`怪物周围九宫格${enemy.haloRange}格范围内所有怪物获得以下特殊属性(包括自身),` +
|
||||
`特殊属性数值间为${
|
||||
enemy.specialMultiply ? '相乘' : '相加'
|
||||
}关系:<br />` +
|
||||
content
|
||||
);
|
||||
},
|
||||
color: '#F721F7'
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user