mirror of
https://github.com/motajs/template.git
synced 2026-10-15 01:30:17 +08:00
refactor: 怪物特殊属性适应新接口
This commit is contained in:
parent
80d3a21ba1
commit
c1ebd25892
@ -17,21 +17,21 @@ import {
|
||||
IReadonlyEnemyHandler
|
||||
} from '@user/data-system';
|
||||
import { IReadonlyEnemy, ISpecial } from '@user/data-base';
|
||||
import { ISpecial23Value } from './special';
|
||||
import { ISpecial23Value, ISpecial26Value } from './special';
|
||||
import { IHeroAttr, IEnemyAttr } from '@user/data-common';
|
||||
|
||||
const FULL_RANGE = new FullRange();
|
||||
const RECT_RANGE = new RectRange();
|
||||
const MANHATTAN_RANGE = new ManhattanRange();
|
||||
|
||||
//#region 25-光环
|
||||
//#region 23-光环
|
||||
|
||||
export class CommonAuraConverter implements IAuraConverter<
|
||||
IEnemyAttr,
|
||||
IHeroAttr
|
||||
> {
|
||||
shouldConvert(special: ISpecial<any>): boolean {
|
||||
return special.code === 25;
|
||||
return special.code === 23;
|
||||
}
|
||||
|
||||
convert(
|
||||
@ -47,7 +47,7 @@ export class CommonAura implements IEnemyAuraView<
|
||||
IRectRangeParam | IManhattanRangeParam | void,
|
||||
ISpecial23Value
|
||||
> {
|
||||
readonly priority: number = 25;
|
||||
readonly priority: number = 10;
|
||||
readonly couldApplyBase: boolean = true;
|
||||
readonly couldApplySpecial: boolean = false;
|
||||
readonly range: IRange<IRectRangeParam | IManhattanRangeParam | void>;
|
||||
@ -63,30 +63,30 @@ export class CommonAura implements IEnemyAuraView<
|
||||
private createRange(): IRange<
|
||||
IRectRangeParam | IManhattanRangeParam | void
|
||||
> {
|
||||
const { range: haloRange, square: haloSquare } = this.special.value;
|
||||
if (haloRange <= 0) {
|
||||
const { range, square } = this.special.value;
|
||||
if (range <= 0) {
|
||||
return FULL_RANGE;
|
||||
}
|
||||
return haloSquare ? RECT_RANGE : MANHATTAN_RANGE;
|
||||
return square ? RECT_RANGE : MANHATTAN_RANGE;
|
||||
}
|
||||
|
||||
getRangeParam(): IRectRangeParam | IManhattanRangeParam | void {
|
||||
const { range: haloRange, square: haloSquare } = this.special.value;
|
||||
if (haloRange <= 0) {
|
||||
const { range, square } = this.special.value;
|
||||
if (range <= 0) {
|
||||
return undefined;
|
||||
}
|
||||
if (haloSquare) {
|
||||
if (square) {
|
||||
return {
|
||||
x: this.locator.x - haloRange,
|
||||
y: this.locator.y - haloRange,
|
||||
w: haloRange * 2 + 1,
|
||||
h: haloRange * 2 + 1
|
||||
x: this.locator.x - range,
|
||||
y: this.locator.y - range,
|
||||
w: range * 2 + 1,
|
||||
h: range * 2 + 1
|
||||
};
|
||||
}
|
||||
return {
|
||||
cx: this.locator.x,
|
||||
cy: this.locator.y,
|
||||
radius: haloRange
|
||||
radius: range
|
||||
};
|
||||
}
|
||||
|
||||
@ -120,14 +120,14 @@ export class CommonAura implements IEnemyAuraView<
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region 26-支援
|
||||
//#region 24-支援
|
||||
|
||||
export class GuardAuraConverter implements IAuraConverter<
|
||||
IEnemyAttr,
|
||||
IHeroAttr
|
||||
> {
|
||||
shouldConvert(special: ISpecial<any>): boolean {
|
||||
return special.code === 26;
|
||||
return special.code === 24;
|
||||
}
|
||||
|
||||
convert(
|
||||
@ -144,7 +144,7 @@ export class GuardAura implements IEnemyAuraView<
|
||||
IRectRangeParam,
|
||||
void
|
||||
> {
|
||||
readonly priority: number = 26;
|
||||
readonly priority: number = 5;
|
||||
readonly couldApplyBase: boolean = true;
|
||||
readonly couldApplySpecial: boolean = false;
|
||||
readonly range: IRange<IRectRangeParam> = RECT_RANGE;
|
||||
@ -184,3 +184,118 @@ export class GuardAura implements IEnemyAuraView<
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region 26-特殊光环
|
||||
|
||||
export class SpecialAuraConverter implements IAuraConverter<
|
||||
IEnemyAttr,
|
||||
IHeroAttr
|
||||
> {
|
||||
shouldConvert(special: ISpecial<any>): boolean {
|
||||
return special.code === 26;
|
||||
}
|
||||
|
||||
convert(
|
||||
special: ISpecial<ISpecial26Value>,
|
||||
handler: IReadonlyEnemyHandler<IEnemyAttr, IHeroAttr>
|
||||
): SpecialAura {
|
||||
return new SpecialAura(handler.enemy, special, handler.locator);
|
||||
}
|
||||
}
|
||||
|
||||
export class SpecialAuraModifier implements IEnemySpecialModifier<IEnemyAttr> {
|
||||
constructor(readonly special: ISpecial<ISpecial26Value>) {}
|
||||
|
||||
add(handler: IReadonlyEnemyHandler<IEnemyAttr, any>): ISpecial<any>[] {
|
||||
const manager = handler.state.enemyManager;
|
||||
const list: ISpecial<any>[] = [];
|
||||
for (const [code, param] of this.special.value.specials) {
|
||||
if (handler.enemy.hasSpecial(code)) continue;
|
||||
const sp = manager.getSpecial(code)?.();
|
||||
if (!sp) continue;
|
||||
sp.setValue(param);
|
||||
list.push(sp);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
delete(): ISpecial<any>[] {
|
||||
// 特殊光环不删除特殊属性
|
||||
return [];
|
||||
}
|
||||
|
||||
modify(
|
||||
_handler: IEnemyHandler<IEnemyAttr, any>,
|
||||
special: ISpecial<any>
|
||||
): boolean {
|
||||
const sp = this.special.value.specials.find(v => v[0] === special.code);
|
||||
if (!sp) return false;
|
||||
const param = sp[1];
|
||||
if (typeof param !== 'number') return false;
|
||||
if (this.special.value.mulAdd) {
|
||||
special.setValue(special.value * param);
|
||||
} else {
|
||||
special.setValue(special.value + param);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export class SpecialAura implements IEnemyAuraView<
|
||||
IEnemyAttr,
|
||||
IRectRangeParam | IManhattanRangeParam | void,
|
||||
ISpecial26Value
|
||||
> {
|
||||
readonly priority: number = 20;
|
||||
readonly couldApplyBase: boolean = true;
|
||||
readonly couldApplySpecial: boolean = false;
|
||||
readonly range: IRange<IRectRangeParam | IManhattanRangeParam | void>;
|
||||
|
||||
constructor(
|
||||
readonly enemy: IReadonlyEnemy<IEnemyAttr>,
|
||||
readonly special: ISpecial<ISpecial26Value>,
|
||||
readonly locator: ITileLocator
|
||||
) {
|
||||
this.range = this.createRange();
|
||||
}
|
||||
|
||||
private createRange(): IRange<
|
||||
IRectRangeParam | IManhattanRangeParam | void
|
||||
> {
|
||||
const { range, square } = this.special.value;
|
||||
if (range <= 0) {
|
||||
return FULL_RANGE;
|
||||
}
|
||||
return square ? RECT_RANGE : MANHATTAN_RANGE;
|
||||
}
|
||||
|
||||
getRangeParam(): IRectRangeParam | IManhattanRangeParam | void {
|
||||
const { range, square } = this.special.value;
|
||||
if (range <= 0) {
|
||||
return undefined;
|
||||
}
|
||||
if (square) {
|
||||
return {
|
||||
x: this.locator.x - range,
|
||||
y: this.locator.y - range,
|
||||
w: range * 2 + 1,
|
||||
h: range * 2 + 1
|
||||
};
|
||||
}
|
||||
return {
|
||||
cx: this.locator.x,
|
||||
cy: this.locator.y,
|
||||
radius: range
|
||||
};
|
||||
}
|
||||
|
||||
apply(): void {
|
||||
// 特殊光环不修改基本属性
|
||||
}
|
||||
|
||||
applySpecial(): IEnemySpecialModifier<IEnemyAttr> | null {
|
||||
return new SpecialAuraModifier(this.special);
|
||||
}
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
@ -31,7 +31,7 @@ export class MainDamageCalculator implements IDamageCalculator<
|
||||
// 无敌
|
||||
if (
|
||||
enemy.hasSpecial(20) &&
|
||||
(handler.state.hero.items.getItemState('cross')?.count ?? 0) < 1
|
||||
handler.state.hero.items.itemCount('cross') < 1
|
||||
) {
|
||||
return { damage: Infinity, turn: 0 };
|
||||
}
|
||||
@ -51,7 +51,7 @@ export class MainDamageCalculator implements IDamageCalculator<
|
||||
}
|
||||
|
||||
// 吸血
|
||||
const vampire = enemy.getSpecial<ISpecial9Value>(11);
|
||||
const vampire = enemy.getSpecial<ISpecial9Value>(9);
|
||||
if (vampire) {
|
||||
const value = (vampire.value.vampire / 100) * hp;
|
||||
damage += value;
|
||||
@ -68,11 +68,7 @@ export class MainDamageCalculator implements IDamageCalculator<
|
||||
enemyPerDamage = monAtk - def;
|
||||
}
|
||||
|
||||
// 连击
|
||||
if (enemy.hasSpecial(4)) enemyPerDamage *= 2;
|
||||
if (enemy.hasSpecial(5)) enemyPerDamage *= 3;
|
||||
|
||||
const multiHit = enemy.getSpecial<number>(6);
|
||||
const multiHit = enemy.getSpecial<number>(4);
|
||||
if (multiHit) {
|
||||
enemyPerDamage *= multiHit.value;
|
||||
}
|
||||
@ -113,20 +109,20 @@ export class MainDamageCalculator implements IDamageCalculator<
|
||||
}
|
||||
|
||||
// 破甲
|
||||
const breakArmor = enemy.getSpecial<number>(7);
|
||||
const breakArmor = enemy.getSpecial<number>(5);
|
||||
if (breakArmor) {
|
||||
damage += (breakArmor.value / 100) * def;
|
||||
}
|
||||
|
||||
// 反击
|
||||
const counterAttack = enemy.getSpecial<number>(8);
|
||||
const counterAttack = enemy.getSpecial<number>(6);
|
||||
if (counterAttack) {
|
||||
// 反击是每回合生效,因此加到 enemyPerDamage 上
|
||||
enemyPerDamage += (counterAttack.value / 100) * atk;
|
||||
}
|
||||
|
||||
// 净化
|
||||
const purify = enemy.getSpecial<number>(9);
|
||||
const purify = enemy.getSpecial<number>(7);
|
||||
if (purify) {
|
||||
damage += purify.value * mdef;
|
||||
}
|
||||
@ -148,13 +144,13 @@ export class MainDamageCalculator implements IDamageCalculator<
|
||||
}
|
||||
|
||||
// 固伤,无法被魔防减伤
|
||||
const fixedDamage = enemy.getSpecial<number>(22);
|
||||
const fixedDamage = enemy.getSpecial<number>(20);
|
||||
if (fixedDamage) {
|
||||
damage += fixedDamage.value;
|
||||
}
|
||||
|
||||
// 仇恨,无法被魔防减伤
|
||||
if (enemy.hasSpecial(17)) {
|
||||
if (enemy.hasSpecial(15)) {
|
||||
damage += handler.state.flags.getFieldValueDefaults('hatred', 0);
|
||||
}
|
||||
|
||||
|
||||
@ -12,14 +12,14 @@ export class MainEnemyFinalEffect implements IEnemyFinalEffect<
|
||||
const heroAtk = handler.hero.getFinalAttribute('atk');
|
||||
const heroDef = handler.hero.getFinalAttribute('def');
|
||||
|
||||
// 3-坚固
|
||||
// 3 - 坚固
|
||||
if (enemy.hasSpecial(3)) {
|
||||
const target = Math.max(enemy.getAttribute('def'), heroAtk - 1);
|
||||
enemy.setAttribute('def', target);
|
||||
}
|
||||
|
||||
// 10-模仿
|
||||
if (enemy.hasSpecial(10)) {
|
||||
// 8 - 模仿
|
||||
if (enemy.hasSpecial(8)) {
|
||||
enemy.setAttribute('atk', heroAtk);
|
||||
enemy.setAttribute('def', heroDef);
|
||||
}
|
||||
|
||||
@ -1,19 +0,0 @@
|
||||
import { IEnemyLegacyBridge } from '@user/data-base';
|
||||
import { IEnemyAttr } from '@user/data-common';
|
||||
|
||||
export class EnemyLegacyBridge implements IEnemyLegacyBridge<IEnemyAttr> {
|
||||
fromLegacyEnemy(
|
||||
enemy: Enemy,
|
||||
defaultAttr: Partial<IEnemyAttr>
|
||||
): IEnemyAttr {
|
||||
return {
|
||||
hp: enemy.hp ?? defaultAttr.hp ?? 0,
|
||||
atk: enemy.atk ?? defaultAttr.atk ?? 0,
|
||||
def: enemy.def ?? defaultAttr.def ?? 0,
|
||||
money: enemy.money ?? defaultAttr.money ?? 0,
|
||||
exp: enemy.exp ?? defaultAttr.exp ?? 0,
|
||||
point: enemy.point ?? defaultAttr.point ?? 0,
|
||||
guard: defaultAttr.guard ?? new Set()
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -71,13 +71,14 @@ export interface ISpecial26Value {
|
||||
* 注册所有怪物特殊属性到 enemyManager
|
||||
*
|
||||
* 属性实现位置一览('./'表示当前文件夹 '../'表示上一级文件夹):
|
||||
* 1. 调参类属性 | 仅影响战斗过程的属性:./damage.ts calDamageWithTurn 函数
|
||||
* 2. 地图伤害:./damage.ts DamageEnemy.calMapDamage 方法
|
||||
* 3. 光环属性:./damage.ts DamageEnemy.provideHalo 方法
|
||||
* 4. 中毒的每步效果:../state/move.ts HeroMover.onStepEnd 方法
|
||||
* 5. 中毒的瞬移效果:还在脚本编辑的 moveDirectly
|
||||
* 6. 衰弱效果:../state/hero.ts getHeroStatusOf 方法
|
||||
* 7. 重生属性:还在脚本编辑的 changingFloor
|
||||
* 1. 调参类属性 | 仅影响战斗过程的属性:./calculator.ts, MainDamageCalculator.calculate 方法
|
||||
* 2. 坚固、模仿等仅影响自身基础属性的属性:./final.ts, MainEnemyFinalEffect.apply 方法
|
||||
* 3. 地图伤害:./mapDamage.ts,具体写法参考文档
|
||||
* 4. 光环属性:./aura.ts 具体写法参考文档
|
||||
* 5. 中毒的每步效果:在插件系统中,目前暂未实装
|
||||
* 6. 中毒的瞬移效果:在插件系统中,目前暂未实装
|
||||
* 7. 衰弱效果:在插件系统中,目前尚未实装
|
||||
* 8. 重生属性:在插件系统中,目前尚未实装
|
||||
*/
|
||||
export function createSpecials(
|
||||
state: IStateSystem
|
||||
|
||||
@ -99,19 +99,19 @@ export interface IComputingEnemyView<TEnemy> extends IEnemyView<TEnemy> {
|
||||
export interface IEnemySpecialModifier<TEnemy> {
|
||||
/**
|
||||
* 获取要添加到指定怪物身上的特殊属性
|
||||
* @param handler 信息对象
|
||||
* @param handler 目标怪物信息对象
|
||||
*/
|
||||
add(handler: IReadonlyEnemyHandler<TEnemy, any>): ISpecial<any>[];
|
||||
|
||||
/**
|
||||
* 获取制定怪物身上要删除的特殊属性
|
||||
* @param handler 信息对象
|
||||
* @param handler 目标怪物信息对象
|
||||
*/
|
||||
delete(handler: IReadonlyEnemyHandler<TEnemy, any>): ISpecial<any>[];
|
||||
|
||||
/**
|
||||
* 修改一个怪物的特殊属性,如果真正进行了修改则返回 true,否则返回 false
|
||||
* @param handler 信息对象
|
||||
* @param handler 目标怪物信息对象
|
||||
* @param special 要修改的怪物特殊属性
|
||||
*/
|
||||
modify(
|
||||
@ -138,7 +138,7 @@ export interface IAuraView<TEnemy, TRange = any> {
|
||||
|
||||
/**
|
||||
* 对指定怪物对象施加修饰器
|
||||
* @param handler 信息对象
|
||||
* @param handler 目标怪物信息对象
|
||||
* @param baseEnemy 原始怪物对象,即未进行任何修改的怪物对象
|
||||
*/
|
||||
apply(
|
||||
@ -148,7 +148,7 @@ export interface IAuraView<TEnemy, TRange = any> {
|
||||
|
||||
/**
|
||||
* 对指定怪物对象添加特殊属性修饰器
|
||||
* @param handler 信息对象
|
||||
* @param handler 目标怪物信息对象
|
||||
* @param baseEnemy 原始怪物对象,即未进行任何修改的怪物对象
|
||||
*/
|
||||
applySpecial(
|
||||
|
||||
Loading…
Reference in New Issue
Block a user