fix: 杀戮光环 & feat: 注册新图块

This commit is contained in:
AncTe committed 2024-04-26 21:24:12 +08:00
1 parent 3b064b6322
commit 32f57cafec
21 files changed
+350 -58

No files matched your search

+110
View File
@@ -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
View File
@@ -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
View File
@@ -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 +=
'&nbsp;'.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'
}