mirror of
https://github.com/motajs/template.git
synced 2026-11-02 15:04:30 +08:00
refactor: 怪物接口拓展自 IStateBaseExtended
This commit is contained in:
1 parent
d6275c0ea7
commit
604c77f7c7
7 files changed
+170
-45
No files matched your search
@@ -100,7 +100,7 @@ export class EnemyContext<TEnemy, THero> implements IEnemyContext<
|
||||
width: number = 0;
|
||||
height: number = 0;
|
||||
|
||||
constructor(readonly dataState: IStateBase) {}
|
||||
constructor(readonly state: IStateBase) {}
|
||||
|
||||
resize(width: number, height: number): void {
|
||||
this.clear();
|
||||
@@ -215,7 +215,7 @@ export class EnemyContext<TEnemy, THero> implements IEnemyContext<
|
||||
context: this,
|
||||
locator,
|
||||
hero: this.bindedHero!,
|
||||
data: this.dataState
|
||||
state: this.state
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,8 @@ import {
|
||||
IEnemyCritical,
|
||||
IEnemyDamageInfo,
|
||||
IReadonlyEnemyHandler,
|
||||
IEnemyView
|
||||
IEnemyView,
|
||||
IEnemyDamageInfoBase
|
||||
} from './types';
|
||||
import {
|
||||
IHeroAttribute,
|
||||
@@ -22,7 +23,7 @@ interface ICriticalSearchResult {
|
||||
/** 此临界点的属性值 */
|
||||
readonly value: number;
|
||||
/** 此临界点的伤害信息 */
|
||||
readonly info: IEnemyDamageInfo;
|
||||
readonly info: IEnemyDamageInfoBase;
|
||||
}
|
||||
|
||||
export class DamageContext<TEnemy, THero> implements IDamageContext<
|
||||
@@ -34,14 +35,14 @@ export class DamageContext<TEnemy, THero> implements IDamageContext<
|
||||
/** 当前勇士属性 */
|
||||
protected heroStatus: IReadonlyHeroAttribute<THero> | null;
|
||||
|
||||
readonly dataState: IStateBase;
|
||||
readonly state: IStateBase;
|
||||
|
||||
constructor(
|
||||
readonly context: IEnemyContext<TEnemy, THero>,
|
||||
calculator: IDamageCalculator<TEnemy, THero> | null = null,
|
||||
heroStatus: IReadonlyHeroAttribute<THero> | null = null
|
||||
) {
|
||||
this.dataState = context.dataState;
|
||||
this.state = context.state;
|
||||
this.calculator = calculator;
|
||||
this.heroStatus = heroStatus;
|
||||
}
|
||||
@@ -62,11 +63,13 @@ export class DamageContext<TEnemy, THero> implements IDamageContext<
|
||||
context: this.context,
|
||||
locator,
|
||||
hero,
|
||||
data: this.dataState
|
||||
state: this.state
|
||||
};
|
||||
}
|
||||
|
||||
getDamageInfo(enemy: IEnemyView<TEnemy>): IEnemyDamageInfo | null {
|
||||
getDamageInfo(
|
||||
enemy: IEnemyView<TEnemy>
|
||||
): IEnemyDamageInfo<TEnemy, THero> | null {
|
||||
if (!this.heroStatus) {
|
||||
logger.warn(107);
|
||||
return null;
|
||||
@@ -82,12 +85,15 @@ export class DamageContext<TEnemy, THero> implements IDamageContext<
|
||||
const computed = enemy.getComputedEnemy();
|
||||
const handler = this.createReadonlyHandler(computed, locator, hero);
|
||||
|
||||
return this.calculator.calculate(handler);
|
||||
return {
|
||||
handler,
|
||||
...this.calculator.calculate(handler)
|
||||
};
|
||||
}
|
||||
|
||||
getDamageInfoByComputed(
|
||||
enemy: IReadonlyEnemy<TEnemy>
|
||||
): IEnemyDamageInfo | null {
|
||||
): IEnemyDamageInfo<TEnemy, THero> | null {
|
||||
if (!this.heroStatus) {
|
||||
logger.warn(107);
|
||||
return null;
|
||||
@@ -105,7 +111,10 @@ export class DamageContext<TEnemy, THero> implements IDamageContext<
|
||||
|
||||
const handler = this.createReadonlyHandler(enemy, locator, hero);
|
||||
|
||||
return this.calculator.calculate(handler);
|
||||
return {
|
||||
handler,
|
||||
...this.calculator.calculate(handler)
|
||||
};
|
||||
}
|
||||
|
||||
*calculateCritical(
|
||||
@@ -224,8 +233,10 @@ export class DamageSystem<TEnemy, THero>
|
||||
implements IDamageSystem<TEnemy, THero>
|
||||
{
|
||||
/** 怪物伤害缓存 */
|
||||
private readonly cache: Map<IEnemyView<TEnemy>, IEnemyDamageInfo> =
|
||||
new Map();
|
||||
private readonly cache: Map<
|
||||
IEnemyView<TEnemy>,
|
||||
IEnemyDamageInfo<TEnemy, THero>
|
||||
> = new Map();
|
||||
|
||||
constructor(context: IEnemyContext<TEnemy, THero>) {
|
||||
super(context);
|
||||
@@ -245,7 +256,9 @@ export class DamageSystem<TEnemy, THero>
|
||||
this.markAllDirty();
|
||||
}
|
||||
|
||||
getDamageInfo(enemy: IEnemyView<TEnemy>): IEnemyDamageInfo | null {
|
||||
getDamageInfo(
|
||||
enemy: IEnemyView<TEnemy>
|
||||
): IEnemyDamageInfo<TEnemy, THero> | null {
|
||||
const cached = this.cache.get(enemy);
|
||||
if (cached) {
|
||||
return cached;
|
||||
@@ -260,7 +273,7 @@ export class DamageSystem<TEnemy, THero>
|
||||
|
||||
getDamageInfoByComputed(
|
||||
enemy: IReadonlyEnemy<TEnemy>
|
||||
): IEnemyDamageInfo | null {
|
||||
): IEnemyDamageInfo<TEnemy, THero> | null {
|
||||
const view = this.context.getViewByComputed(enemy);
|
||||
if (view) {
|
||||
const cached = this.cache.get(view);
|
||||
|
||||
@@ -64,11 +64,11 @@ export class MapDamage<TEnemy, THero> implements IMapDamage<TEnemy, THero> {
|
||||
/** 坐标索引对象 */
|
||||
private readonly indexer: ILocationHelper;
|
||||
|
||||
readonly dataState: IStateBase;
|
||||
readonly state: IStateBase;
|
||||
|
||||
constructor(readonly context: IEnemyContext<TEnemy, THero>) {
|
||||
this.indexer = context.indexer;
|
||||
this.dataState = context.dataState;
|
||||
this.state = context.state;
|
||||
}
|
||||
|
||||
useConverter(converter: IMapDamageConverter<TEnemy, THero>): void {
|
||||
@@ -92,7 +92,7 @@ export class MapDamage<TEnemy, THero> implements IMapDamage<TEnemy, THero> {
|
||||
context: this.context,
|
||||
locator,
|
||||
hero,
|
||||
data: this.context.dataState
|
||||
state: this.state
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { ITileLocator, IRange } from '@motajs/common';
|
||||
import { ITileLocator, IRange, IHookable, IHookBase } from '@motajs/common';
|
||||
import {
|
||||
IEnemy,
|
||||
IReadonlyEnemy,
|
||||
ISpecial,
|
||||
IReadonlyHeroAttribute,
|
||||
IHeroAttribute,
|
||||
IStateBase
|
||||
IStateBase,
|
||||
IStateBaseExtended
|
||||
} from '@user/data-base';
|
||||
import { ILocationHelper } from '@user/data-common';
|
||||
|
||||
@@ -21,7 +22,7 @@ export interface IEnemyHandler<TEnemy, THero> {
|
||||
/** 勇士属性信息 */
|
||||
readonly hero: IReadonlyHeroAttribute<THero>;
|
||||
/** 当前全局状态对象 */
|
||||
readonly data: IStateBase;
|
||||
readonly state: IStateBase;
|
||||
}
|
||||
|
||||
export interface IReadonlyEnemyHandler<TEnemy, THero> {
|
||||
@@ -34,7 +35,7 @@ export interface IReadonlyEnemyHandler<TEnemy, THero> {
|
||||
/** 勇士属性信息 */
|
||||
readonly hero: IReadonlyHeroAttribute<THero>;
|
||||
/** 当前全局状态对象 */
|
||||
readonly data: IStateBase;
|
||||
readonly state: IStateBase;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
@@ -282,11 +283,9 @@ export interface IMapDamageReducer {
|
||||
): Readonly<IMapDamageInfo>;
|
||||
}
|
||||
|
||||
export interface IMapDamage<TEnemy, THero> {
|
||||
export interface IMapDamage<TEnemy, THero> extends IStateBaseExtended {
|
||||
/** 当前绑定的怪物上下文 */
|
||||
readonly context: IEnemyContext<TEnemy, THero>;
|
||||
/** 地图伤害系统绑定的全局状态对象 */
|
||||
readonly dataState: IStateBase;
|
||||
|
||||
/**
|
||||
* 设置地图伤害转换器,并基于当前上下文重建所有地图伤害视图
|
||||
@@ -356,13 +355,18 @@ export interface IMapDamage<TEnemy, THero> {
|
||||
|
||||
//#region 伤害系统
|
||||
|
||||
export interface IEnemyDamageInfo {
|
||||
export interface IEnemyDamageInfoBase {
|
||||
/** 战斗伤害值 */
|
||||
readonly damage: number;
|
||||
/** 战斗回合数 */
|
||||
readonly turn: number;
|
||||
}
|
||||
|
||||
export interface IEnemyDamageInfo<TEnemy, THero> extends IEnemyDamageInfoBase {
|
||||
/** 信息对象 */
|
||||
readonly handler: IReadonlyEnemyHandler<TEnemy, THero>;
|
||||
}
|
||||
|
||||
export interface IEnemyCritical {
|
||||
/** 此临界点中指定勇士属性的值 */
|
||||
readonly nextValue: number;
|
||||
@@ -371,9 +375,9 @@ export interface IEnemyCritical {
|
||||
/** 此临界点中指定勇士数值的值与当前值的差,即 `nextValue - baseValue` */
|
||||
readonly nextDiff: number;
|
||||
/** 当前状态下怪物的伤害信息 */
|
||||
readonly baseInfo: IEnemyDamageInfo;
|
||||
readonly baseInfo: IEnemyDamageInfoBase;
|
||||
/** 此临界点下怪物的伤害信息 */
|
||||
readonly info: IEnemyDamageInfo;
|
||||
readonly info: IEnemyDamageInfoBase;
|
||||
/** 此临界点的伤害值与当前伤害值的差 */
|
||||
readonly damageDiff: number;
|
||||
}
|
||||
@@ -387,7 +391,9 @@ export interface IDamageCalculator<TEnemy, THero> {
|
||||
* 计算战斗伤害信息
|
||||
* @param handler 信息对象
|
||||
*/
|
||||
calculate(handler: IReadonlyEnemyHandler<TEnemy, THero>): IEnemyDamageInfo;
|
||||
calculate(
|
||||
handler: IReadonlyEnemyHandler<TEnemy, THero>
|
||||
): IEnemyDamageInfoBase;
|
||||
|
||||
/**
|
||||
* 获取临界计算的上界
|
||||
@@ -400,15 +406,14 @@ export interface IDamageCalculator<TEnemy, THero> {
|
||||
): number;
|
||||
}
|
||||
|
||||
export interface IDamageContext<TEnemy, THero> {
|
||||
/** 伤害上下文所属的全局状态对象 */
|
||||
readonly dataState: IStateBase;
|
||||
|
||||
export interface IDamageContext<TEnemy, THero> extends IStateBaseExtended {
|
||||
/**
|
||||
* 获取战斗伤害信息
|
||||
* @param enemy 怪物视图
|
||||
*/
|
||||
getDamageInfo(enemy: IEnemyView<TEnemy>): IEnemyDamageInfo | null;
|
||||
getDamageInfo(
|
||||
enemy: IEnemyView<TEnemy>
|
||||
): IEnemyDamageInfo<TEnemy, THero> | null;
|
||||
|
||||
/**
|
||||
* 根据怪物对象获取战斗伤害信息
|
||||
@@ -416,7 +421,7 @@ export interface IDamageContext<TEnemy, THero> {
|
||||
*/
|
||||
getDamageInfoByComputed(
|
||||
enemy: IReadonlyEnemy<TEnemy>
|
||||
): IEnemyDamageInfo | null;
|
||||
): IEnemyDamageInfo<TEnemy, THero> | null;
|
||||
|
||||
/**
|
||||
* 计算怪物在指定勇士属性下的临界
|
||||
@@ -483,15 +488,16 @@ export interface IDamageSystem<TEnemy, THero> extends IDamageContext<
|
||||
|
||||
//#region 上下文
|
||||
|
||||
export interface IReadonlyEnemyContext<TEnemy, THero> {
|
||||
export interface IReadonlyEnemyContext<
|
||||
TEnemy,
|
||||
THero
|
||||
> extends IStateBaseExtended {
|
||||
/** 怪物上下文宽度 */
|
||||
readonly width: number;
|
||||
/** 怪物上下文高度 */
|
||||
readonly height: number;
|
||||
/** 此上下文使用的索引对象 */
|
||||
readonly indexer: ILocationHelper;
|
||||
/** 当前怪物上下文绑定的全局状态对象 */
|
||||
readonly dataState: IStateBase;
|
||||
|
||||
/**
|
||||
* 获取当前绑定的勇士属性对象
|
||||
@@ -567,8 +573,6 @@ export interface IEnemyContext<TEnemy, THero> extends IReadonlyEnemyContext<
|
||||
readonly height: number;
|
||||
/** 此上下文使用的索引对象 */
|
||||
readonly indexer: ILocationHelper;
|
||||
/** 当前怪物上下文绑定的全局状态对象 */
|
||||
readonly dataState: IStateBase;
|
||||
|
||||
/**
|
||||
* 调整上下文尺寸,并清空当前上下文中的所有怪物与状态
|
||||
@@ -724,3 +728,111 @@ export interface IEnemyContext<TEnemy, THero> extends IReadonlyEnemyContext<
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region 战斗流程
|
||||
|
||||
export interface ICombatFlowHandler<TEnemy, THero> {
|
||||
/** 战斗的怪物是否在地图上 */
|
||||
readonly onMap: boolean;
|
||||
/** 可修改勇士对象 */
|
||||
readonly hero: IHeroAttribute<THero>;
|
||||
/** 可修改怪物对象 */
|
||||
readonly enemy: IEnemy<TEnemy>;
|
||||
/** 怪物上下文 */
|
||||
readonly context: IEnemyContext<TEnemy, THero>;
|
||||
/** 怪物位置 */
|
||||
readonly locator: ITileLocator;
|
||||
/** 全局状态对象 */
|
||||
readonly state: IStateBase;
|
||||
}
|
||||
|
||||
export interface ICombatFlowHook<TEnemy, THero> extends IHookBase {
|
||||
/**
|
||||
* 战前脚本
|
||||
* @param info 战斗伤害信息
|
||||
*/
|
||||
onBeforeCombat?(info: IEnemyDamageInfo<TEnemy, THero>): Promise<void>;
|
||||
|
||||
/**
|
||||
* 战后脚本
|
||||
* @param info 战斗伤害信息
|
||||
*/
|
||||
onAfterCombat?(info: IEnemyDamageInfo<TEnemy, THero>): Promise<void>;
|
||||
}
|
||||
|
||||
export interface ICombatScript<TEnemy, THero> {
|
||||
/** 此脚本的优先级 */
|
||||
readonly priority: number;
|
||||
|
||||
/**
|
||||
* 战前执行的内容,返回 `false` 会立刻停止后续战前内容的执行,并放弃此次战斗
|
||||
* @param info 战斗伤害信息
|
||||
* @param handler 信息对象
|
||||
*/
|
||||
before(
|
||||
info: IEnemyDamageInfo<TEnemy, THero>,
|
||||
handler: ICombatFlowHandler<TEnemy, THero>
|
||||
): Promise<boolean>;
|
||||
|
||||
/**
|
||||
* 战后执行的内容
|
||||
* @param info 战斗伤害信息
|
||||
* @param handler 信息对象
|
||||
*/
|
||||
after(
|
||||
info: IEnemyDamageInfo<TEnemy, THero>,
|
||||
handler: ICombatFlowHandler<TEnemy, THero>
|
||||
): Promise<void>;
|
||||
}
|
||||
|
||||
export interface ICombatFlow<TEnemy, THero>
|
||||
extends IHookable<ICombatFlowHook<TEnemy, THero>>, IStateBaseExtended {
|
||||
/** 勇士属性对象 */
|
||||
readonly hero: IReadonlyHeroAttribute<THero> | null;
|
||||
/** 怪物上下文对象 */
|
||||
readonly context: IReadonlyEnemyContext<TEnemy, THero> | null;
|
||||
/** 伤害上下文 */
|
||||
readonly damage: IDamageContext<TEnemy, THero> | null;
|
||||
|
||||
/**
|
||||
* 绑定勇士属性对象
|
||||
* @param hero 勇士属性对象
|
||||
*/
|
||||
bindHero(hero: IHeroAttribute<THero> | null): void;
|
||||
|
||||
/**
|
||||
* 绑定怪物上下文
|
||||
* @param context 怪物上下文
|
||||
*/
|
||||
bindContext(context: IReadonlyEnemyContext<TEnemy, THero> | null): void;
|
||||
|
||||
/**
|
||||
* 绑定伤害上下文
|
||||
* @param damage 伤害上下文
|
||||
*/
|
||||
bindDamage(damage: IDamageContext<TEnemy, THero> | null): void;
|
||||
|
||||
/**
|
||||
* 与指定怪物战斗
|
||||
* @param enemy 怪物视图对象
|
||||
*/
|
||||
battle(
|
||||
enemy: IEnemyView<TEnemy>
|
||||
): Promise<IEnemyDamageInfo<TEnemy, THero> | null>;
|
||||
|
||||
/**
|
||||
* 与指定怪物战斗
|
||||
* @param enemy 怪物对象
|
||||
*/
|
||||
battleComputed(
|
||||
enemy: IReadonlyEnemy<TEnemy>
|
||||
): Promise<IEnemyDamageInfo<TEnemy, THero> | null>;
|
||||
|
||||
/**
|
||||
* 添加战前战后脚本
|
||||
* @param script 战前战后脚本
|
||||
*/
|
||||
addCombatScript(script: ICombatScript<TEnemy, THero>): void;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
Reference in new issue
Block a user