mirror of
https://github.com/motajs/template.git
synced 2026-05-21 18:31:11 +08:00
refactor: 删除污染严重的 TEnemy 和 THero,仅在战斗系统中包含
This commit is contained in:
parent
13e8547a37
commit
370f285964
@ -12,16 +12,18 @@ import {
|
|||||||
} from './types';
|
} from './types';
|
||||||
import { SaveCompression } from '@user/data-common';
|
import { SaveCompression } from '@user/data-common';
|
||||||
|
|
||||||
export class EnemyManager<TAttr> implements IEnemyManager<TAttr> {
|
export class EnemyManager<TEnemy> implements IEnemyManager<TEnemy> {
|
||||||
/** 特殊属性注册表,code -> 创建函数 */
|
/** 特殊属性注册表,code -> 创建函数 */
|
||||||
private readonly specialRegistry: Map<number, SpecialCreation<any, TAttr>> =
|
private readonly specialRegistry: Map<
|
||||||
new Map();
|
number,
|
||||||
|
SpecialCreation<any, TEnemy>
|
||||||
|
> = new Map();
|
||||||
/** 自定义怪物属性注册表,name -> 默认值 */
|
/** 自定义怪物属性注册表,name -> 默认值 */
|
||||||
private readonly attributeRegistry: Map<keyof TAttr, any> = new Map();
|
private readonly attributeRegistry: Map<keyof TEnemy, any> = new Map();
|
||||||
/** 怪物模板表,code -> IEnemy */
|
/** 怪物模板表,code -> IEnemy */
|
||||||
private readonly prefabByCode: Map<number, IEnemy<TAttr>> = new Map();
|
private readonly prefabByCode: Map<number, IEnemy<TEnemy>> = new Map();
|
||||||
/** 怪物模板表,id -> IEnemy */
|
/** 怪物模板表,id -> IEnemy */
|
||||||
private readonly prefabById: Map<string, IEnemy<TAttr>> = new Map();
|
private readonly prefabById: Map<string, IEnemy<TEnemy>> = new Map();
|
||||||
/** 旧样板怪物 id 到 code 的映射,用于 fromLegacyEnemy 快速查找已有模板 */
|
/** 旧样板怪物 id 到 code 的映射,用于 fromLegacyEnemy 快速查找已有模板 */
|
||||||
private readonly legacyIdToCode: Map<string, number> = new Map();
|
private readonly legacyIdToCode: Map<string, number> = new Map();
|
||||||
/** 复用映射,reusedCode -> sourceCode */
|
/** 复用映射,reusedCode -> sourceCode */
|
||||||
@ -31,21 +33,21 @@ export class EnemyManager<TAttr> implements IEnemyManager<TAttr> {
|
|||||||
/** 脏模板集合,存储发生了变化的模板 code */
|
/** 脏模板集合,存储发生了变化的模板 code */
|
||||||
private readonly dirtySet: Set<number> = new Set();
|
private readonly dirtySet: Set<number> = new Set();
|
||||||
/** 参考快照,code -> IReadonlyEnemy,由 compareWith 提供 */
|
/** 参考快照,code -> IReadonlyEnemy,由 compareWith 提供 */
|
||||||
private referenceByCode: Map<number, IReadonlyEnemy<TAttr>> = new Map();
|
private referenceByCode: Map<number, IReadonlyEnemy<TEnemy>> = new Map();
|
||||||
/** 当前附加的怪物比较器 */
|
/** 当前附加的怪物比较器 */
|
||||||
private comparer: IEnemyComparer<TAttr> | null = null;
|
private comparer: IEnemyComparer<TEnemy> | null = null;
|
||||||
/** 是否已首次调用 compareWith */
|
/** 是否已首次调用 compareWith */
|
||||||
private hasReference: boolean = false;
|
private hasReference: boolean = false;
|
||||||
|
|
||||||
constructor(readonly bridge: IEnemyLegacyBridge<TAttr>) {}
|
constructor(readonly bridge: IEnemyLegacyBridge<TEnemy>) {}
|
||||||
|
|
||||||
registerSpecial(code: number, cons: SpecialCreation<any, TAttr>): void {
|
registerSpecial(code: number, cons: SpecialCreation<any, TEnemy>): void {
|
||||||
this.specialRegistry.set(code, cons);
|
this.specialRegistry.set(code, cons);
|
||||||
}
|
}
|
||||||
|
|
||||||
setAttributeDefaults<K extends keyof TAttr>(
|
setAttributeDefaults<K extends keyof TEnemy>(
|
||||||
name: K,
|
name: K,
|
||||||
defaultValue: TAttr[K]
|
defaultValue: TEnemy[K]
|
||||||
): void {
|
): void {
|
||||||
if (
|
if (
|
||||||
typeof defaultValue === 'function' ||
|
typeof defaultValue === 'function' ||
|
||||||
@ -59,7 +61,7 @@ export class EnemyManager<TAttr> implements IEnemyManager<TAttr> {
|
|||||||
this.attributeRegistry.set(name, defaultValue);
|
this.attributeRegistry.set(name, defaultValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
fromLegacyEnemy(code: number, enemy: Enemy): IEnemy<TAttr> {
|
fromLegacyEnemy(code: number, enemy: Enemy): IEnemy<TEnemy> {
|
||||||
// 如果该旧样板怪物已经通过 addPrefabFromLegacy 注册为模板,直接克隆模板
|
// 如果该旧样板怪物已经通过 addPrefabFromLegacy 注册为模板,直接克隆模板
|
||||||
const existingCode = this.legacyIdToCode.get(enemy.id);
|
const existingCode = this.legacyIdToCode.get(enemy.id);
|
||||||
if (existingCode) {
|
if (existingCode) {
|
||||||
@ -76,15 +78,15 @@ export class EnemyManager<TAttr> implements IEnemyManager<TAttr> {
|
|||||||
* 根据旧样板怪物与注册过的默认属性构造属性对象
|
* 根据旧样板怪物与注册过的默认属性构造属性对象
|
||||||
* @param enemy 旧样板怪物对象
|
* @param enemy 旧样板怪物对象
|
||||||
*/
|
*/
|
||||||
private createAttributes(enemy: Enemy): TAttr {
|
private createAttributes(enemy: Enemy): TEnemy {
|
||||||
const attrs: Partial<TAttr> = {};
|
const attrs: Partial<TEnemy> = {};
|
||||||
for (const [name, defaultValue] of this.attributeRegistry) {
|
for (const [name, defaultValue] of this.attributeRegistry) {
|
||||||
attrs[name] = structuredClone(defaultValue);
|
attrs[name] = structuredClone(defaultValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.assign(attrs, this.bridge.fromLegacyEnemy(enemy, attrs));
|
Object.assign(attrs, this.bridge.fromLegacyEnemy(enemy, attrs));
|
||||||
|
|
||||||
return attrs as TAttr;
|
return attrs as TEnemy;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -92,9 +94,9 @@ export class EnemyManager<TAttr> implements IEnemyManager<TAttr> {
|
|||||||
* @param code 怪物图块数字
|
* @param code 怪物图块数字
|
||||||
* @param enemy 旧样板怪物对象
|
* @param enemy 旧样板怪物对象
|
||||||
*/
|
*/
|
||||||
private convertLegacyEnemy(code: number, enemy: Enemy): IEnemy<TAttr> {
|
private convertLegacyEnemy(code: number, enemy: Enemy): IEnemy<TEnemy> {
|
||||||
const attrs = this.createAttributes(enemy);
|
const attrs = this.createAttributes(enemy);
|
||||||
const result = new EnemyImpl<TAttr>(
|
const result = new EnemyImpl<TEnemy>(
|
||||||
enemy.id,
|
enemy.id,
|
||||||
code,
|
code,
|
||||||
structuredClone(attrs)
|
structuredClone(attrs)
|
||||||
@ -114,13 +116,13 @@ export class EnemyManager<TAttr> implements IEnemyManager<TAttr> {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
createEnemy(code: number): IEnemy<TAttr> | null {
|
createEnemy(code: number): IEnemy<TEnemy> | null {
|
||||||
const prefab = this.prefabByCode.get(code);
|
const prefab = this.prefabByCode.get(code);
|
||||||
if (!prefab) return null;
|
if (!prefab) return null;
|
||||||
return prefab.clone();
|
return prefab.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
createEnemyById(id: string): IEnemy<TAttr> | null {
|
createEnemyById(id: string): IEnemy<TEnemy> | null {
|
||||||
const prefab = this.prefabById.get(id);
|
const prefab = this.prefabById.get(id);
|
||||||
if (!prefab) return null;
|
if (!prefab) return null;
|
||||||
return prefab.clone();
|
return prefab.clone();
|
||||||
@ -136,7 +138,7 @@ export class EnemyManager<TAttr> implements IEnemyManager<TAttr> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addPrefab(enemy: IEnemy<TAttr>): void {
|
addPrefab(enemy: IEnemy<TEnemy>): void {
|
||||||
if (
|
if (
|
||||||
this.prefabByCode.has(enemy.code) ||
|
this.prefabByCode.has(enemy.code) ||
|
||||||
this.prefabById.has(enemy.id)
|
this.prefabById.has(enemy.id)
|
||||||
@ -160,12 +162,12 @@ export class EnemyManager<TAttr> implements IEnemyManager<TAttr> {
|
|||||||
this.updateDirty(code, prefab);
|
this.updateDirty(code, prefab);
|
||||||
}
|
}
|
||||||
|
|
||||||
getPrefab(code: number): IReadonlyEnemy<TAttr> | null {
|
getPrefab(code: number): IReadonlyEnemy<TEnemy> | null {
|
||||||
const sourceCode = this.reuseByCode.get(code) ?? code;
|
const sourceCode = this.reuseByCode.get(code) ?? code;
|
||||||
return this.prefabByCode.get(sourceCode) ?? null;
|
return this.prefabByCode.get(sourceCode) ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
getPrefabById(id: string): IReadonlyEnemy<TAttr> | null {
|
getPrefabById(id: string): IReadonlyEnemy<TEnemy> | null {
|
||||||
const sourceId = this.reuseById.get(id) ?? id;
|
const sourceId = this.reuseById.get(id) ?? id;
|
||||||
return this.prefabById.get(sourceId) ?? null;
|
return this.prefabById.get(sourceId) ?? null;
|
||||||
}
|
}
|
||||||
@ -177,7 +179,7 @@ export class EnemyManager<TAttr> implements IEnemyManager<TAttr> {
|
|||||||
this.prefabById.delete(prefab.id);
|
this.prefabById.delete(prefab.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
changePrefab(code: number | string, enemy: IEnemy<TAttr>): void {
|
changePrefab(code: number | string, enemy: IEnemy<TEnemy>): void {
|
||||||
// 先删除旧的模板(如果存在)
|
// 先删除旧的模板(如果存在)
|
||||||
this.deletePrefab(code);
|
this.deletePrefab(code);
|
||||||
// 再添加新的模板
|
// 再添加新的模板
|
||||||
@ -193,7 +195,7 @@ export class EnemyManager<TAttr> implements IEnemyManager<TAttr> {
|
|||||||
this.reuseById.set(id, prefab.id);
|
this.reuseById.set(id, prefab.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
compareWith(reference: ReadonlyMap<number, IReadonlyEnemy<TAttr>>): void {
|
compareWith(reference: ReadonlyMap<number, IReadonlyEnemy<TEnemy>>): void {
|
||||||
const isSubsequentCall = this.hasReference;
|
const isSubsequentCall = this.hasReference;
|
||||||
if (isSubsequentCall) {
|
if (isSubsequentCall) {
|
||||||
logger.warn(117);
|
logger.warn(117);
|
||||||
@ -211,7 +213,7 @@ export class EnemyManager<TAttr> implements IEnemyManager<TAttr> {
|
|||||||
|
|
||||||
modifyPrefabAttribute(
|
modifyPrefabAttribute(
|
||||||
code: number | string,
|
code: number | string,
|
||||||
modify: (prefab: IEnemy<TAttr>) => IEnemy<TAttr>
|
modify: (prefab: IEnemy<TEnemy>) => IEnemy<TEnemy>
|
||||||
): void {
|
): void {
|
||||||
const prefab = this.internalGetPrefab(code);
|
const prefab = this.internalGetPrefab(code);
|
||||||
if (!prefab) return;
|
if (!prefab) return;
|
||||||
@ -230,16 +232,16 @@ export class EnemyManager<TAttr> implements IEnemyManager<TAttr> {
|
|||||||
this.updateDirty(result.code, result);
|
this.updateDirty(result.code, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
attachEnemyComparer(comparer: IEnemyComparer<TAttr>): void {
|
attachEnemyComparer(comparer: IEnemyComparer<TEnemy>): void {
|
||||||
this.comparer = comparer;
|
this.comparer = comparer;
|
||||||
}
|
}
|
||||||
|
|
||||||
getEnemyComparer(): IEnemyComparer<TAttr> | null {
|
getEnemyComparer(): IEnemyComparer<TEnemy> | null {
|
||||||
return this.comparer;
|
return this.comparer;
|
||||||
}
|
}
|
||||||
|
|
||||||
saveState(compression: SaveCompression): IEnemyManagerSaveState<TAttr> {
|
saveState(compression: SaveCompression): IEnemyManagerSaveState<TEnemy> {
|
||||||
const modified: Map<number, IEnemySaveState<TAttr>> = new Map();
|
const modified: Map<number, IEnemySaveState<TEnemy>> = new Map();
|
||||||
for (const code of this.dirtySet) {
|
for (const code of this.dirtySet) {
|
||||||
const prefab = this.prefabByCode.get(code);
|
const prefab = this.prefabByCode.get(code);
|
||||||
if (!prefab) continue;
|
if (!prefab) continue;
|
||||||
@ -249,7 +251,7 @@ export class EnemyManager<TAttr> implements IEnemyManager<TAttr> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
loadState(
|
loadState(
|
||||||
state: IEnemyManagerSaveState<TAttr>,
|
state: IEnemyManagerSaveState<TEnemy>,
|
||||||
compression: SaveCompression
|
compression: SaveCompression
|
||||||
): void {
|
): void {
|
||||||
for (const [code, enemyState] of state.modified) {
|
for (const [code, enemyState] of state.modified) {
|
||||||
@ -269,7 +271,7 @@ export class EnemyManager<TAttr> implements IEnemyManager<TAttr> {
|
|||||||
* @param code 怪物图块数字
|
* @param code 怪物图块数字
|
||||||
* @param current 当前模板对象
|
* @param current 当前模板对象
|
||||||
*/
|
*/
|
||||||
private updateDirty(code: number, current: IEnemy<TAttr>): void {
|
private updateDirty(code: number, current: IEnemy<TEnemy>): void {
|
||||||
if (!this.hasReference) return;
|
if (!this.hasReference) return;
|
||||||
if (!this.comparer) {
|
if (!this.comparer) {
|
||||||
logger.warn(118);
|
logger.warn(118);
|
||||||
|
|||||||
@ -2,21 +2,26 @@ import { IHeroFollower, IHeroState } from './hero';
|
|||||||
import { IEnemyManager } from './enemy';
|
import { IEnemyManager } from './enemy';
|
||||||
import { IFlagSystem } from './flag';
|
import { IFlagSystem } from './flag';
|
||||||
import { IMapStore } from './map';
|
import { IMapStore } from './map';
|
||||||
import { IDataCommon, ISaveableContent } from '@user/data-common';
|
import {
|
||||||
|
IDataCommon,
|
||||||
|
IEnemyAttr,
|
||||||
|
IHeroAttr,
|
||||||
|
ISaveableContent
|
||||||
|
} from '@user/data-common';
|
||||||
|
|
||||||
export interface IStateSaveData {
|
export interface IStateSaveData {
|
||||||
/** 跟随者列表 */
|
/** 跟随者列表 */
|
||||||
readonly followers: readonly IHeroFollower[];
|
readonly followers: readonly IHeroFollower[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IStateBase<TEnemy, THero> extends IDataCommon {
|
export interface IStateBase extends IDataCommon {
|
||||||
/** 地图状态 */
|
/** 地图状态 */
|
||||||
readonly maps: IMapStore;
|
readonly maps: IMapStore;
|
||||||
/** 勇士状态 */
|
/** 勇士状态 */
|
||||||
readonly hero: IHeroState<THero>;
|
readonly hero: IHeroState<IHeroAttr>;
|
||||||
|
|
||||||
/** 怪物管理器 */
|
/** 怪物管理器 */
|
||||||
readonly enemyManager: IEnemyManager<TEnemy>;
|
readonly enemyManager: IEnemyManager<IEnemyAttr>;
|
||||||
|
|
||||||
/** Flag 系统 */
|
/** Flag 系统 */
|
||||||
readonly flags: IFlagSystem;
|
readonly flags: IFlagSystem;
|
||||||
@ -35,7 +40,7 @@ export interface IStateBase<TEnemy, THero> extends IDataCommon {
|
|||||||
getSaveableContent<T>(id: string): ISaveableContent<T> | null;
|
getSaveableContent<T>(id: string): ISaveableContent<T> | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IStateBaseExtended<TEnemy = unknown, THero = unknown> {
|
export interface IStateBaseExtended {
|
||||||
/** 当前对象对应的数据层对象(Layer 1 对象) */
|
/** 当前对象对应的数据层对象(Layer 1 对象) */
|
||||||
readonly state: IStateBase<TEnemy, THero>;
|
readonly state: IStateBase;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,47 @@
|
|||||||
|
import { ITileLocator } from '@motajs/common';
|
||||||
import { IFaceManager, IRoleFaceBinder } from './common';
|
import { IFaceManager, IRoleFaceBinder } from './common';
|
||||||
import { ITileStore } from './store';
|
import { ITileStore } from './store';
|
||||||
|
|
||||||
|
export interface IEnemyAttr {
|
||||||
|
/** 怪物生命值 */
|
||||||
|
hp: number;
|
||||||
|
/** 怪物攻击力 */
|
||||||
|
atk: number;
|
||||||
|
/** 怪物防御力 */
|
||||||
|
def: number;
|
||||||
|
/** 怪物金币 */
|
||||||
|
money: number;
|
||||||
|
/** 怪物经验值 */
|
||||||
|
exp: number;
|
||||||
|
/** 怪物加点量 */
|
||||||
|
point: number;
|
||||||
|
/** 支援来源怪物坐标索引列表 */
|
||||||
|
guard: Set<ITileLocator>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IHeroAttr {
|
||||||
|
/** 勇士名称 */
|
||||||
|
name: string;
|
||||||
|
/** 勇士生命值 */
|
||||||
|
hp: number;
|
||||||
|
/** 勇士生命值上限 */
|
||||||
|
hpmax: number;
|
||||||
|
/** 勇士攻击力 */
|
||||||
|
atk: number;
|
||||||
|
/** 勇士防御力 */
|
||||||
|
def: number;
|
||||||
|
/** 勇士护盾 */
|
||||||
|
mdef: number;
|
||||||
|
/** 勇士魔法值 */
|
||||||
|
mana: number;
|
||||||
|
/** 勇士魔法上限 */
|
||||||
|
manamax: number;
|
||||||
|
/** 勇士拥有的金币 */
|
||||||
|
money: number;
|
||||||
|
/** 勇士拥有的经验 */
|
||||||
|
exp: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface IDataCommon {
|
export interface IDataCommon {
|
||||||
/** 图块定义存储 */
|
/** 图块定义存储 */
|
||||||
readonly tileStore: ITileStore<MapDataOf<keyof NumberToId>>;
|
readonly tileStore: ITileStore<MapDataOf<keyof NumberToId>>;
|
||||||
|
|||||||
@ -11,7 +11,9 @@ import {
|
|||||||
Dir4FaceHandler,
|
Dir4FaceHandler,
|
||||||
Dir8FaceHandler,
|
Dir8FaceHandler,
|
||||||
FaceGroup,
|
FaceGroup,
|
||||||
FaceDirection
|
FaceDirection,
|
||||||
|
IHeroAttr,
|
||||||
|
IEnemyAttr
|
||||||
} from '@user/data-common';
|
} from '@user/data-common';
|
||||||
import {
|
import {
|
||||||
EnemyManager,
|
EnemyManager,
|
||||||
@ -48,8 +50,7 @@ import {
|
|||||||
MainMapDamageConverter,
|
MainMapDamageConverter,
|
||||||
MainMapDamageReducer,
|
MainMapDamageReducer,
|
||||||
registerSpecials,
|
registerSpecials,
|
||||||
MainEnemyComparer,
|
MainEnemyComparer
|
||||||
IEnemyAttr
|
|
||||||
} from './enemy';
|
} from './enemy';
|
||||||
import {
|
import {
|
||||||
BG2_ZINDEX,
|
BG2_ZINDEX,
|
||||||
@ -61,7 +62,6 @@ import {
|
|||||||
TILE_HEIGHT,
|
TILE_HEIGHT,
|
||||||
TILE_WIDTH
|
TILE_WIDTH
|
||||||
} from './shared';
|
} from './shared';
|
||||||
import { IHeroAttr } from './hero';
|
|
||||||
import { LegacyTileData, TileLegacyBridge } from './legacy';
|
import { LegacyTileData, TileLegacyBridge } from './legacy';
|
||||||
import { ILoadProgressTotal, LoadProgressTotal } from '@motajs/loader';
|
import { ILoadProgressTotal, LoadProgressTotal } from '@motajs/loader';
|
||||||
import { isNil } from 'lodash-es';
|
import { isNil } from 'lodash-es';
|
||||||
@ -82,8 +82,8 @@ export class CoreState implements ICoreState {
|
|||||||
|
|
||||||
// Layer 2 执行层,游戏逻辑对象都在这
|
// Layer 2 执行层,游戏逻辑对象都在这
|
||||||
readonly enemyContext: IEnemyContext<IEnemyAttr, IHeroAttr>;
|
readonly enemyContext: IEnemyContext<IEnemyAttr, IHeroAttr>;
|
||||||
readonly triggerRegistry: ITriggerRegistry<IEnemyAttr, IHeroAttr>;
|
readonly triggerRegistry: ITriggerRegistry;
|
||||||
readonly triggerCollector: ITriggerCollector<IEnemyAttr, IHeroAttr>;
|
readonly triggerCollector: ITriggerCollector;
|
||||||
|
|
||||||
// 用户层内容,也就是最顶层的内容,一般仅用于初始化
|
// 用户层内容,也就是最顶层的内容,一般仅用于初始化
|
||||||
readonly loadProgress: ILoadProgressTotal;
|
readonly loadProgress: ILoadProgressTotal;
|
||||||
@ -171,10 +171,8 @@ export class CoreState implements ICoreState {
|
|||||||
this.enemyContext = enemyContext;
|
this.enemyContext = enemyContext;
|
||||||
|
|
||||||
// 触发器注册与收集器
|
// 触发器注册与收集器
|
||||||
const triggerRegistry = new TriggerRegistry<IEnemyAttr, IHeroAttr>(
|
const triggerRegistry = new TriggerRegistry(this);
|
||||||
this
|
const triggerCollector = new TriggerCollector();
|
||||||
);
|
|
||||||
const triggerCollector = new TriggerCollector<IEnemyAttr, IHeroAttr>();
|
|
||||||
triggerCollector.attachRegistry(triggerRegistry);
|
triggerCollector.attachRegistry(triggerRegistry);
|
||||||
this.triggerRegistry = triggerRegistry;
|
this.triggerRegistry = triggerRegistry;
|
||||||
this.triggerCollector = triggerCollector;
|
this.triggerCollector = triggerCollector;
|
||||||
|
|||||||
@ -18,8 +18,7 @@ import {
|
|||||||
} from '@user/data-system';
|
} from '@user/data-system';
|
||||||
import { IReadonlyEnemy, ISpecial } from '@user/data-base';
|
import { IReadonlyEnemy, ISpecial } from '@user/data-base';
|
||||||
import { IHaloValue } from './special';
|
import { IHaloValue } from './special';
|
||||||
import { IEnemyAttr } from './types';
|
import { IHeroAttr, IEnemyAttr } from '@user/data-common';
|
||||||
import { IHeroAttr } from '../hero';
|
|
||||||
|
|
||||||
const FULL_RANGE = new FullRange();
|
const FULL_RANGE = new FullRange();
|
||||||
const RECT_RANGE = new RectRange();
|
const RECT_RANGE = new RectRange();
|
||||||
@ -176,7 +175,7 @@ export class GuardAura implements IEnemyAuraView<
|
|||||||
if (locator.x === this.locator.x && locator.y === this.locator.y) {
|
if (locator.x === this.locator.x && locator.y === this.locator.y) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
enemy.getAttribute('guard').add(this.sourceView);
|
enemy.getAttribute('guard').add(this.locator);
|
||||||
}
|
}
|
||||||
|
|
||||||
applySpecial(): IEnemySpecialModifier<IEnemyAttr> | null {
|
applySpecial(): IEnemySpecialModifier<IEnemyAttr> | null {
|
||||||
|
|||||||
@ -4,10 +4,10 @@ import {
|
|||||||
IEnemyDamageInfo,
|
IEnemyDamageInfo,
|
||||||
IReadonlyEnemyHandler
|
IReadonlyEnemyHandler
|
||||||
} from '@user/data-system';
|
} from '@user/data-system';
|
||||||
import { IEnemyAttr } from './types';
|
import { IEnemyAttr, IHeroAttr } from '@user/data-common';
|
||||||
import { IVampireValue } from './special';
|
import { IVampireValue } from './special';
|
||||||
import { IHeroAttr } from '../hero';
|
|
||||||
import { state } from '../ins';
|
import { state } from '../ins';
|
||||||
|
import { logger } from '@motajs/common';
|
||||||
|
|
||||||
export class MainDamageCalculator implements IDamageCalculator<
|
export class MainDamageCalculator implements IDamageCalculator<
|
||||||
IEnemyAttr,
|
IEnemyAttr,
|
||||||
@ -87,8 +87,14 @@ export class MainDamageCalculator implements IDamageCalculator<
|
|||||||
// 因此回合数需要加上打支援怪的回合数
|
// 因此回合数需要加上打支援怪的回合数
|
||||||
for (const guard of guards) {
|
for (const guard of guards) {
|
||||||
// 直接把 enemy 传过去,因此支援的 enemy 会吃到其原本所在位置的光环加成
|
// 直接把 enemy 传过去,因此支援的 enemy 会吃到其原本所在位置的光环加成
|
||||||
|
const view = handler.context.getEnemyByLocator(guard);
|
||||||
|
if (!view) {
|
||||||
|
logger.warn(137, guard.x.toString(), guard.y.toString());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
const extraInfo = this.calculate({
|
const extraInfo = this.calculate({
|
||||||
enemy: guard.getComputedEnemy(),
|
enemy: view.getComputedEnemy(),
|
||||||
|
context: handler.context,
|
||||||
locator,
|
locator,
|
||||||
hero,
|
hero,
|
||||||
data: handler.data
|
data: handler.data
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { IEnemyComparer, IReadonlyEnemy } from '@user/data-base';
|
import { IEnemyComparer, IReadonlyEnemy } from '@user/data-base';
|
||||||
import { IEnemyAttr } from './types';
|
import { IEnemyAttr } from '@user/data-common';
|
||||||
|
|
||||||
export class MainEnemyComparer implements IEnemyComparer<IEnemyAttr> {
|
export class MainEnemyComparer implements IEnemyComparer<IEnemyAttr> {
|
||||||
compare(
|
compare(
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import { IEnemyFinalEffect, IEnemyHandler } from '@user/data-system';
|
import { IEnemyFinalEffect, IEnemyHandler } from '@user/data-system';
|
||||||
import { IEnemyAttr } from './types';
|
import { IEnemyAttr, IHeroAttr } from '@user/data-common';
|
||||||
import { IHeroAttr } from '../hero';
|
|
||||||
|
|
||||||
export class MainEnemyFinalEffect implements IEnemyFinalEffect<
|
export class MainEnemyFinalEffect implements IEnemyFinalEffect<
|
||||||
IEnemyAttr,
|
IEnemyAttr,
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { IEnemyLegacyBridge } from '@user/data-base';
|
import { IEnemyLegacyBridge } from '@user/data-base';
|
||||||
import { IEnemyAttr } from './types';
|
import { IEnemyAttr } from '@user/data-common';
|
||||||
|
|
||||||
export class EnemyLegacyBridge implements IEnemyLegacyBridge<IEnemyAttr> {
|
export class EnemyLegacyBridge implements IEnemyLegacyBridge<IEnemyAttr> {
|
||||||
fromLegacyEnemy(
|
fromLegacyEnemy(
|
||||||
|
|||||||
@ -24,8 +24,8 @@ import {
|
|||||||
IReadonlyEnemy
|
IReadonlyEnemy
|
||||||
} from '@user/data-base';
|
} from '@user/data-base';
|
||||||
import { IZoneValue } from './special';
|
import { IZoneValue } from './special';
|
||||||
import { IEnemyAttr, MapDamageType } from './types';
|
import { MapDamageType } from './types';
|
||||||
import { IHeroAttr } from '../hero';
|
import { IHeroAttr, IEnemyAttr } from '@user/data-common';
|
||||||
import { IFaceHandler, FaceGroup } from '@user/data-common';
|
import { IFaceHandler, FaceGroup } from '@user/data-common';
|
||||||
|
|
||||||
const RECT_RANGE = new RectRange();
|
const RECT_RANGE = new RectRange();
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import {
|
|||||||
IEnemyManager
|
IEnemyManager
|
||||||
} from '@user/data-base';
|
} from '@user/data-base';
|
||||||
import { getHeroStatusOn } from '../legacy/hero';
|
import { getHeroStatusOn } from '../legacy/hero';
|
||||||
import { IEnemyAttr } from './types';
|
import { IEnemyAttr } from '@user/data-common';
|
||||||
|
|
||||||
//#region 复合属性值类型
|
//#region 复合属性值类型
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
import { IEnemyView } from '@user/data-system';
|
|
||||||
|
|
||||||
export interface IEnemyAttr {
|
export interface IEnemyAttr {
|
||||||
/** 怪物生命值 */
|
/** 怪物生命值 */
|
||||||
hp: number;
|
hp: number;
|
||||||
@ -13,8 +11,8 @@ export interface IEnemyAttr {
|
|||||||
exp: number;
|
exp: number;
|
||||||
/** 怪物加点量 */
|
/** 怪物加点量 */
|
||||||
point: number;
|
point: number;
|
||||||
/** 支援来源怪物视图列表 */
|
/** 支援来源怪物坐标索引列表 */
|
||||||
guard: Set<IEnemyView<IEnemyAttr>>;
|
guard: Set<number>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum MapDamageType {
|
export const enum MapDamageType {
|
||||||
|
|||||||
@ -1,26 +1,5 @@
|
|||||||
//#region 勇士属性
|
//#region 勇士属性
|
||||||
|
|
||||||
export interface IHeroAttr {
|
export interface IHeroAttr {}
|
||||||
/** 勇士名称 */
|
|
||||||
name: string;
|
|
||||||
/** 勇士生命值 */
|
|
||||||
hp: number;
|
|
||||||
/** 勇士生命值上限 */
|
|
||||||
hpmax: number;
|
|
||||||
/** 勇士攻击力 */
|
|
||||||
atk: number;
|
|
||||||
/** 勇士防御力 */
|
|
||||||
def: number;
|
|
||||||
/** 勇士护盾 */
|
|
||||||
mdef: number;
|
|
||||||
/** 勇士魔法值 */
|
|
||||||
mana: number;
|
|
||||||
/** 勇士魔法上限 */
|
|
||||||
manamax: number;
|
|
||||||
/** 勇士拥有的金币 */
|
|
||||||
money: number;
|
|
||||||
/** 勇士拥有的经验 */
|
|
||||||
exp: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { IHeroAttr } from './hero';
|
import { IHeroAttr } from '@user/data-common';
|
||||||
|
|
||||||
//#region 地图相关
|
//#region 地图相关
|
||||||
|
|
||||||
|
|||||||
@ -1,21 +1,19 @@
|
|||||||
import { IMotaDataLoader, IStateBase } from '@user/data-base';
|
import { IMotaDataLoader, IStateBase } from '@user/data-base';
|
||||||
import { IEnemyAttr } from './enemy';
|
|
||||||
import { IHeroAttr } from './hero';
|
|
||||||
import { ILoadProgressTotal } from '@motajs/loader';
|
import { ILoadProgressTotal } from '@motajs/loader';
|
||||||
import { ISaveSystem } from './save';
|
import { ISaveSystem } from './save';
|
||||||
import { IStateSystem } from '@user/data-system';
|
import { IStateSystem } from '@user/data-system';
|
||||||
import { ISaveableContent } from '@user/data-common';
|
import { ISaveableContent } from '@user/data-common';
|
||||||
|
|
||||||
export interface ISaveableExecutor<T, TEnemy = IEnemyAttr, THero = IHeroAttr> {
|
export interface ISaveableExecutor<T> {
|
||||||
/**
|
/**
|
||||||
* 当数据读取后执行的函数,允许对其他存档对象进行读取
|
* 当数据读取后执行的函数,允许对其他存档对象进行读取
|
||||||
* @param data 对应可存档对象的存档数据
|
* @param data 对应可存档对象的存档数据
|
||||||
* @param state 当前的基础状态
|
* @param state 当前的基础状态
|
||||||
*/
|
*/
|
||||||
afterLoad(data: T, state: IStateBase<TEnemy, THero>): void;
|
afterLoad(data: T, state: IStateBase): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ICoreState extends IStateSystem<IEnemyAttr, IHeroAttr> {
|
export interface ICoreState extends IStateSystem {
|
||||||
/** 加载进度对象 */
|
/** 加载进度对象 */
|
||||||
readonly loadProgress: ILoadProgressTotal;
|
readonly loadProgress: ILoadProgressTotal;
|
||||||
/** 数据端加载对象 */
|
/** 数据端加载对象 */
|
||||||
|
|||||||
@ -100,7 +100,7 @@ export class EnemyContext<TEnemy, THero> implements IEnemyContext<
|
|||||||
width: number = 0;
|
width: number = 0;
|
||||||
height: number = 0;
|
height: number = 0;
|
||||||
|
|
||||||
constructor(readonly dataState: IStateBase<TEnemy, THero>) {}
|
constructor(readonly dataState: IStateBase) {}
|
||||||
|
|
||||||
resize(width: number, height: number): void {
|
resize(width: number, height: number): void {
|
||||||
this.clear();
|
this.clear();
|
||||||
@ -210,7 +210,13 @@ export class EnemyContext<TEnemy, THero> implements IEnemyContext<
|
|||||||
enemy: IEnemy<TEnemy>,
|
enemy: IEnemy<TEnemy>,
|
||||||
locator: ITileLocator
|
locator: ITileLocator
|
||||||
): IEnemyHandler<TEnemy, THero> {
|
): IEnemyHandler<TEnemy, THero> {
|
||||||
return { enemy, locator, hero: this.bindedHero!, data: this.dataState };
|
return {
|
||||||
|
enemy,
|
||||||
|
context: this,
|
||||||
|
locator,
|
||||||
|
hero: this.bindedHero!,
|
||||||
|
data: this.dataState
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
getEnemyLocator(enemy: IEnemy<TEnemy>): Readonly<ITileLocator> | null {
|
getEnemyLocator(enemy: IEnemy<TEnemy>): Readonly<ITileLocator> | null {
|
||||||
|
|||||||
@ -34,7 +34,7 @@ export class DamageContext<TEnemy, THero> implements IDamageContext<
|
|||||||
/** 当前勇士属性 */
|
/** 当前勇士属性 */
|
||||||
protected heroStatus: IReadonlyHeroAttribute<THero> | null;
|
protected heroStatus: IReadonlyHeroAttribute<THero> | null;
|
||||||
|
|
||||||
readonly dataState: IStateBase<TEnemy, THero>;
|
readonly dataState: IStateBase;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
readonly context: IEnemyContext<TEnemy, THero>,
|
readonly context: IEnemyContext<TEnemy, THero>,
|
||||||
@ -57,7 +57,13 @@ export class DamageContext<TEnemy, THero> implements IDamageContext<
|
|||||||
locator: ITileLocator,
|
locator: ITileLocator,
|
||||||
hero: IReadonlyHeroAttribute<THero>
|
hero: IReadonlyHeroAttribute<THero>
|
||||||
): IReadonlyEnemyHandler<TEnemy, THero> {
|
): IReadonlyEnemyHandler<TEnemy, THero> {
|
||||||
return { enemy, locator, hero, data: this.dataState };
|
return {
|
||||||
|
enemy,
|
||||||
|
context: this.context,
|
||||||
|
locator,
|
||||||
|
hero,
|
||||||
|
data: this.dataState
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
getDamageInfo(enemy: IEnemyView<TEnemy>): IEnemyDamageInfo | null {
|
getDamageInfo(enemy: IEnemyView<TEnemy>): IEnemyDamageInfo | null {
|
||||||
|
|||||||
@ -64,7 +64,7 @@ export class MapDamage<TEnemy, THero> implements IMapDamage<TEnemy, THero> {
|
|||||||
/** 坐标索引对象 */
|
/** 坐标索引对象 */
|
||||||
private readonly indexer: ILocationHelper;
|
private readonly indexer: ILocationHelper;
|
||||||
|
|
||||||
readonly dataState: IStateBase<TEnemy, THero>;
|
readonly dataState: IStateBase;
|
||||||
|
|
||||||
constructor(readonly context: IEnemyContext<TEnemy, THero>) {
|
constructor(readonly context: IEnemyContext<TEnemy, THero>) {
|
||||||
this.indexer = context.indexer;
|
this.indexer = context.indexer;
|
||||||
@ -89,6 +89,7 @@ export class MapDamage<TEnemy, THero> implements IMapDamage<TEnemy, THero> {
|
|||||||
if (!hero) return null;
|
if (!hero) return null;
|
||||||
return {
|
return {
|
||||||
enemy: view.getComputedEnemy(),
|
enemy: view.getComputedEnemy(),
|
||||||
|
context: this.context,
|
||||||
locator,
|
locator,
|
||||||
hero,
|
hero,
|
||||||
data: this.context.dataState
|
data: this.context.dataState
|
||||||
|
|||||||
@ -14,23 +14,27 @@ import { ILocationHelper } from '@user/data-common';
|
|||||||
export interface IEnemyHandler<TEnemy, THero> {
|
export interface IEnemyHandler<TEnemy, THero> {
|
||||||
/** 怪物属性信息 */
|
/** 怪物属性信息 */
|
||||||
readonly enemy: IEnemy<TEnemy>;
|
readonly enemy: IEnemy<TEnemy>;
|
||||||
|
/** 怪物上下文 */
|
||||||
|
readonly context: IEnemyContext<TEnemy, THero>;
|
||||||
/** 怪物定位符 */
|
/** 怪物定位符 */
|
||||||
readonly locator: ITileLocator;
|
readonly locator: ITileLocator;
|
||||||
/** 勇士属性信息 */
|
/** 勇士属性信息 */
|
||||||
readonly hero: IReadonlyHeroAttribute<THero>;
|
readonly hero: IReadonlyHeroAttribute<THero>;
|
||||||
/** 当前全局状态对象 */
|
/** 当前全局状态对象 */
|
||||||
readonly data: IStateBase<TEnemy, THero>;
|
readonly data: IStateBase;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IReadonlyEnemyHandler<TEnemy, THero> {
|
export interface IReadonlyEnemyHandler<TEnemy, THero> {
|
||||||
/** 怪物属性信息 */
|
/** 怪物属性信息 */
|
||||||
readonly enemy: IReadonlyEnemy<TEnemy>;
|
readonly enemy: IReadonlyEnemy<TEnemy>;
|
||||||
|
/** 怪物上下文 */
|
||||||
|
readonly context: IReadonlyEnemyContext<TEnemy, THero>;
|
||||||
/** 怪物定位符 */
|
/** 怪物定位符 */
|
||||||
readonly locator: ITileLocator;
|
readonly locator: ITileLocator;
|
||||||
/** 勇士属性信息 */
|
/** 勇士属性信息 */
|
||||||
readonly hero: IReadonlyHeroAttribute<THero>;
|
readonly hero: IReadonlyHeroAttribute<THero>;
|
||||||
/** 当前全局状态对象 */
|
/** 当前全局状态对象 */
|
||||||
readonly data: IStateBase<TEnemy, THero>;
|
readonly data: IStateBase;
|
||||||
}
|
}
|
||||||
|
|
||||||
//#endregion
|
//#endregion
|
||||||
@ -282,7 +286,7 @@ export interface IMapDamage<TEnemy, THero> {
|
|||||||
/** 当前绑定的怪物上下文 */
|
/** 当前绑定的怪物上下文 */
|
||||||
readonly context: IEnemyContext<TEnemy, THero>;
|
readonly context: IEnemyContext<TEnemy, THero>;
|
||||||
/** 地图伤害系统绑定的全局状态对象 */
|
/** 地图伤害系统绑定的全局状态对象 */
|
||||||
readonly dataState: IStateBase<TEnemy, THero>;
|
readonly dataState: IStateBase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置地图伤害转换器,并基于当前上下文重建所有地图伤害视图
|
* 设置地图伤害转换器,并基于当前上下文重建所有地图伤害视图
|
||||||
@ -398,7 +402,7 @@ export interface IDamageCalculator<TEnemy, THero> {
|
|||||||
|
|
||||||
export interface IDamageContext<TEnemy, THero> {
|
export interface IDamageContext<TEnemy, THero> {
|
||||||
/** 伤害上下文所属的全局状态对象 */
|
/** 伤害上下文所属的全局状态对象 */
|
||||||
readonly dataState: IStateBase<TEnemy, THero>;
|
readonly dataState: IStateBase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取战斗伤害信息
|
* 获取战斗伤害信息
|
||||||
@ -479,7 +483,7 @@ export interface IDamageSystem<TEnemy, THero> extends IDamageContext<
|
|||||||
|
|
||||||
//#region 上下文
|
//#region 上下文
|
||||||
|
|
||||||
export interface IEnemyContext<TEnemy, THero> {
|
export interface IReadonlyEnemyContext<TEnemy, THero> {
|
||||||
/** 怪物上下文宽度 */
|
/** 怪物上下文宽度 */
|
||||||
readonly width: number;
|
readonly width: number;
|
||||||
/** 怪物上下文高度 */
|
/** 怪物上下文高度 */
|
||||||
@ -487,7 +491,84 @@ export interface IEnemyContext<TEnemy, THero> {
|
|||||||
/** 此上下文使用的索引对象 */
|
/** 此上下文使用的索引对象 */
|
||||||
readonly indexer: ILocationHelper;
|
readonly indexer: ILocationHelper;
|
||||||
/** 当前怪物上下文绑定的全局状态对象 */
|
/** 当前怪物上下文绑定的全局状态对象 */
|
||||||
readonly dataState: IStateBase<TEnemy, THero>;
|
readonly dataState: IStateBase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前绑定的勇士属性对象
|
||||||
|
*/
|
||||||
|
getBindedHero(): IReadonlyHeroAttribute<THero> | null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定怪物对象当前所在位置
|
||||||
|
* @param enemy 怪物对象
|
||||||
|
*/
|
||||||
|
getEnemyLocator(enemy: IEnemy<TEnemy>): Readonly<ITileLocator> | null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定怪物视图当前所在位置
|
||||||
|
* @param view 怪物视图
|
||||||
|
*/
|
||||||
|
getEnemyLocatorByView(
|
||||||
|
view: IEnemyView<TEnemy>
|
||||||
|
): Readonly<ITileLocator> | null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据定位符获取怪物视图
|
||||||
|
* @param locator 地图定位符
|
||||||
|
*/
|
||||||
|
getEnemyByLocator(locator: ITileLocator): IEnemyView<TEnemy> | null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据坐标获取怪物视图
|
||||||
|
* @param x 横坐标
|
||||||
|
* @param y 纵坐标
|
||||||
|
*/
|
||||||
|
getEnemyByLoc(x: number, y: number): IEnemyView<TEnemy> | null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据计算后怪物对象反查怪物视图
|
||||||
|
* @param enemy 计算后怪物对象
|
||||||
|
*/
|
||||||
|
getViewByComputed(enemy: IReadonlyEnemy<TEnemy>): IEnemyView<TEnemy> | null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 扫描指定范围内的怪物视图
|
||||||
|
* @param range 范围对象
|
||||||
|
* @param param 范围参数
|
||||||
|
*/
|
||||||
|
scanRange<T>(
|
||||||
|
range: IRange<T>,
|
||||||
|
param: T
|
||||||
|
): Iterable<[ITileLocator, IEnemyView<TEnemy>]>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 迭代上下文中的全部怪物
|
||||||
|
*/
|
||||||
|
iterateEnemy(): Iterable<[ITileLocator, IEnemyView<TEnemy>]>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前绑定的地图伤害管理器
|
||||||
|
*/
|
||||||
|
getMapDamage(): IMapDamage<TEnemy, THero> | null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前绑定的伤害计算系统
|
||||||
|
*/
|
||||||
|
getDamageSystem(): IDamageSystem<TEnemy, THero> | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IEnemyContext<TEnemy, THero> extends IReadonlyEnemyContext<
|
||||||
|
TEnemy,
|
||||||
|
THero
|
||||||
|
> {
|
||||||
|
/** 怪物上下文宽度 */
|
||||||
|
readonly width: number;
|
||||||
|
/** 怪物上下文高度 */
|
||||||
|
readonly height: number;
|
||||||
|
/** 此上下文使用的索引对象 */
|
||||||
|
readonly indexer: ILocationHelper;
|
||||||
|
/** 当前怪物上下文绑定的全局状态对象 */
|
||||||
|
readonly dataState: IStateBase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 调整上下文尺寸,并清空当前上下文中的所有怪物与状态
|
* 调整上下文尺寸,并清空当前上下文中的所有怪物与状态
|
||||||
@ -572,44 +653,6 @@ export interface IEnemyContext<TEnemy, THero> {
|
|||||||
*/
|
*/
|
||||||
bindHero(hero: IReadonlyHeroAttribute<THero> | null): void;
|
bindHero(hero: IReadonlyHeroAttribute<THero> | null): void;
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取当前绑定的勇士属性对象
|
|
||||||
*/
|
|
||||||
getBindedHero(): IReadonlyHeroAttribute<THero> | null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取指定怪物对象当前所在位置
|
|
||||||
* @param enemy 怪物对象
|
|
||||||
*/
|
|
||||||
getEnemyLocator(enemy: IEnemy<TEnemy>): Readonly<ITileLocator> | null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取指定怪物视图当前所在位置
|
|
||||||
* @param view 怪物视图
|
|
||||||
*/
|
|
||||||
getEnemyLocatorByView(
|
|
||||||
view: IEnemyView<TEnemy>
|
|
||||||
): Readonly<ITileLocator> | null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据定位符获取怪物视图
|
|
||||||
* @param locator 地图定位符
|
|
||||||
*/
|
|
||||||
getEnemyByLocator(locator: ITileLocator): IEnemyView<TEnemy> | null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据坐标获取怪物视图
|
|
||||||
* @param x 横坐标
|
|
||||||
* @param y 纵坐标
|
|
||||||
*/
|
|
||||||
getEnemyByLoc(x: number, y: number): IEnemyView<TEnemy> | null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据计算后怪物对象反查怪物视图
|
|
||||||
* @param enemy 计算后怪物对象
|
|
||||||
*/
|
|
||||||
getViewByComputed(enemy: IReadonlyEnemy<TEnemy>): IEnemyView<TEnemy> | null;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 在指定位置放置一个怪物对象
|
* 在指定位置放置一个怪物对象
|
||||||
* @param locator 地图定位符
|
* @param locator 地图定位符
|
||||||
@ -623,21 +666,6 @@ export interface IEnemyContext<TEnemy, THero> {
|
|||||||
*/
|
*/
|
||||||
deleteEnemy(locator: ITileLocator): void;
|
deleteEnemy(locator: ITileLocator): void;
|
||||||
|
|
||||||
/**
|
|
||||||
* 扫描指定范围内的怪物视图
|
|
||||||
* @param range 范围对象
|
|
||||||
* @param param 范围参数
|
|
||||||
*/
|
|
||||||
scanRange<T>(
|
|
||||||
range: IRange<T>,
|
|
||||||
param: T
|
|
||||||
): Iterable<[ITileLocator, IEnemyView<TEnemy>]>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 迭代上下文中的全部怪物
|
|
||||||
*/
|
|
||||||
iterateEnemy(): Iterable<[ITileLocator, IEnemyView<TEnemy>]>;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加一个全局光环视图
|
* 添加一个全局光环视图
|
||||||
* @param aura 光环视图
|
* @param aura 光环视图
|
||||||
@ -656,22 +684,12 @@ export interface IEnemyContext<TEnemy, THero> {
|
|||||||
*/
|
*/
|
||||||
attachMapDamage(damage: IMapDamage<TEnemy, THero> | null): void;
|
attachMapDamage(damage: IMapDamage<TEnemy, THero> | null): void;
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取当前绑定的地图伤害管理器
|
|
||||||
*/
|
|
||||||
getMapDamage(): IMapDamage<TEnemy, THero> | null;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 绑定伤害计算系统
|
* 绑定伤害计算系统
|
||||||
* @param system 伤害系统
|
* @param system 伤害系统
|
||||||
*/
|
*/
|
||||||
attachDamageSystem(system: IDamageSystem<TEnemy, unknown> | null): void;
|
attachDamageSystem(system: IDamageSystem<TEnemy, unknown> | null): void;
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取当前绑定的伤害计算系统
|
|
||||||
*/
|
|
||||||
getDamageSystem(): IDamageSystem<TEnemy, THero> | null;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重建当前上下文中的全部怪物计算结果
|
* 重建当前上下文中的全部怪物计算结果
|
||||||
*
|
*
|
||||||
|
|||||||
@ -1,13 +1,10 @@
|
|||||||
import { ITrigger, ITriggerCollection, ITriggerHandler } from './types';
|
import { ITrigger, ITriggerCollection, ITriggerHandler } from './types';
|
||||||
|
|
||||||
export class TriggerCollection<
|
export class TriggerCollection implements ITriggerCollection {
|
||||||
TEnemy = unknown,
|
|
||||||
THero = unknown
|
|
||||||
> implements ITriggerCollection<TEnemy, THero> {
|
|
||||||
/** 当前集合内部维护的触发器列表 */
|
/** 当前集合内部维护的触发器列表 */
|
||||||
private readonly triggerList: ITrigger<TEnemy, THero>[];
|
private readonly triggerList: ITrigger[];
|
||||||
|
|
||||||
constructor(triggers: Iterable<ITrigger<TEnemy, THero>>) {
|
constructor(triggers: Iterable<ITrigger>) {
|
||||||
this.triggerList = [...triggers];
|
this.triggerList = [...triggers];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -15,19 +12,15 @@ export class TriggerCollection<
|
|||||||
return this.triggerList.length;
|
return this.triggerList.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
async trigger(handler: ITriggerHandler<TEnemy, THero>): Promise<void> {
|
async trigger(handler: ITriggerHandler): Promise<void> {
|
||||||
for (const trigger of this.triggerList) {
|
for (const trigger of this.triggerList) {
|
||||||
await trigger.trigger(handler);
|
await trigger.trigger(handler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async *triggerIter(
|
async *triggerIter(
|
||||||
handler: ITriggerHandler<TEnemy, THero>
|
handler: ITriggerHandler
|
||||||
): AsyncGenerator<
|
): AsyncGenerator<ITrigger, void, ITriggerHandler | null> {
|
||||||
ITrigger<TEnemy, THero>,
|
|
||||||
void,
|
|
||||||
ITriggerHandler<TEnemy, THero> | null
|
|
||||||
> {
|
|
||||||
let currentHandler = handler;
|
let currentHandler = handler;
|
||||||
for (const trigger of this.triggerList) {
|
for (const trigger of this.triggerList) {
|
||||||
await trigger.trigger(currentHandler);
|
await trigger.trigger(currentHandler);
|
||||||
@ -40,21 +33,19 @@ export class TriggerCollection<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
iterate(): Iterable<ITrigger<TEnemy, THero>> {
|
iterate(): Iterable<ITrigger> {
|
||||||
return this.triggerList.values();
|
return this.triggerList.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
push(trigger: ITrigger<TEnemy, THero>): void {
|
push(trigger: ITrigger): void {
|
||||||
this.triggerList.push(trigger);
|
this.triggerList.push(trigger);
|
||||||
}
|
}
|
||||||
|
|
||||||
unshift(trigger: ITrigger<TEnemy, THero>): void {
|
unshift(trigger: ITrigger): void {
|
||||||
this.triggerList.unshift(trigger);
|
this.triggerList.unshift(trigger);
|
||||||
}
|
}
|
||||||
|
|
||||||
concat(
|
concat(...others: ITriggerCollection[]): ITriggerCollection {
|
||||||
...others: ITriggerCollection<TEnemy, THero>[]
|
|
||||||
): ITriggerCollection<TEnemy, THero> {
|
|
||||||
const merged = [...this.triggerList];
|
const merged = [...this.triggerList];
|
||||||
for (const other of others) {
|
for (const other of others) {
|
||||||
merged.push(...other.iterate());
|
merged.push(...other.iterate());
|
||||||
|
|||||||
@ -8,18 +8,11 @@ import {
|
|||||||
import { logger } from '@motajs/common';
|
import { logger } from '@motajs/common';
|
||||||
import { TriggerCollection } from './collection';
|
import { TriggerCollection } from './collection';
|
||||||
|
|
||||||
export class TriggerCollector<
|
export class TriggerCollector implements ITriggerCollector {
|
||||||
TEnemy = unknown,
|
|
||||||
THero = unknown
|
|
||||||
> implements ITriggerCollector<TEnemy, THero> {
|
|
||||||
/** 当前收集器使用的注册对象 */
|
/** 当前收集器使用的注册对象 */
|
||||||
private registry: ITriggerRegistry<TEnemy, THero> | null = null;
|
private registry: ITriggerRegistry | null = null;
|
||||||
|
|
||||||
collect(
|
collect(x: number, y: number, layer: IMapLayer): ITriggerCollection {
|
||||||
x: number,
|
|
||||||
y: number,
|
|
||||||
layer: IMapLayer
|
|
||||||
): ITriggerCollection<TEnemy, THero> {
|
|
||||||
if (!this.registry) {
|
if (!this.registry) {
|
||||||
logger.warn(135);
|
logger.warn(135);
|
||||||
return new TriggerCollection([]);
|
return new TriggerCollection([]);
|
||||||
@ -62,8 +55,8 @@ export class TriggerCollector<
|
|||||||
const duplicate = new Set<number>();
|
const duplicate = new Set<number>();
|
||||||
if (staticTrigger) {
|
if (staticTrigger) {
|
||||||
// 有静态触发器
|
// 有静态触发器
|
||||||
const lessTriggers: ITrigger<TEnemy, THero>[] = [];
|
const lessTriggers: ITrigger[] = [];
|
||||||
const greaterTriggers: ITrigger<TEnemy, THero>[] = [];
|
const greaterTriggers: ITrigger[] = [];
|
||||||
// 先收集所有的触发器,并记录重复情况
|
// 先收集所有的触发器,并记录重复情况
|
||||||
for (const tile of layer.dynamicLayer.getDynamicTilesAt(x, y)) {
|
for (const tile of layer.dynamicLayer.getDynamicTilesAt(x, y)) {
|
||||||
const trigger = this.registry.create(tile.triggerType);
|
const trigger = this.registry.create(tile.triggerType);
|
||||||
@ -92,7 +85,7 @@ export class TriggerCollector<
|
|||||||
return new TriggerCollection(arr);
|
return new TriggerCollection(arr);
|
||||||
} else {
|
} else {
|
||||||
// 没有静态触发器
|
// 没有静态触发器
|
||||||
const triggers: ITrigger<TEnemy, THero>[] = [];
|
const triggers: ITrigger[] = [];
|
||||||
for (const tile of layer.dynamicLayer.getDynamicTilesAt(x, y)) {
|
for (const tile of layer.dynamicLayer.getDynamicTilesAt(x, y)) {
|
||||||
const trigger = this.registry.create(tile.triggerType);
|
const trigger = this.registry.create(tile.triggerType);
|
||||||
if (trigger) {
|
if (trigger) {
|
||||||
@ -113,7 +106,7 @@ export class TriggerCollector<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
attachRegistry(registry: ITriggerRegistry<TEnemy, THero> | null): void {
|
attachRegistry(registry: ITriggerRegistry | null): void {
|
||||||
this.registry = registry;
|
this.registry = registry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,28 +2,24 @@ import { logger } from '@motajs/common';
|
|||||||
import { ITrigger, ITriggerRegistry, TriggerFactory } from './types';
|
import { ITrigger, ITriggerRegistry, TriggerFactory } from './types';
|
||||||
import { IStateBase } from '@user/data-base';
|
import { IStateBase } from '@user/data-base';
|
||||||
|
|
||||||
export class TriggerRegistry<
|
export class TriggerRegistry implements ITriggerRegistry {
|
||||||
TEnemy = unknown,
|
|
||||||
THero = unknown
|
|
||||||
> implements ITriggerRegistry<TEnemy, THero> {
|
|
||||||
/** 数字类型到触发器工厂的映射 */
|
/** 数字类型到触发器工厂的映射 */
|
||||||
private readonly typeMap: Map<number, TriggerFactory<TEnemy, THero>> =
|
private readonly typeMap: Map<number, TriggerFactory> = new Map();
|
||||||
new Map();
|
|
||||||
|
|
||||||
constructor(public readonly state: IStateBase<TEnemy, THero>) {}
|
constructor(public readonly state: IStateBase) {}
|
||||||
|
|
||||||
register(type: number, factory: TriggerFactory<TEnemy, THero>): void {
|
register(type: number, factory: TriggerFactory): void {
|
||||||
if (this.typeMap.has(type)) {
|
if (this.typeMap.has(type)) {
|
||||||
logger.warn(132, 'type', type.toString());
|
logger.warn(132, 'type', type.toString());
|
||||||
}
|
}
|
||||||
this.typeMap.set(type, factory);
|
this.typeMap.set(type, factory);
|
||||||
}
|
}
|
||||||
|
|
||||||
get(type: number): TriggerFactory<TEnemy, THero> | null {
|
get(type: number): TriggerFactory | null {
|
||||||
return this.typeMap.get(type) ?? null;
|
return this.typeMap.get(type) ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
create(num: number): ITrigger<TEnemy, THero> | null {
|
create(num: number): ITrigger | null {
|
||||||
const factory = this.get(num);
|
const factory = this.get(num);
|
||||||
if (!factory) return null;
|
if (!factory) return null;
|
||||||
return factory(num, this.state);
|
return factory(num, this.state);
|
||||||
|
|||||||
@ -6,9 +6,9 @@ import {
|
|||||||
IStateBaseExtended
|
IStateBaseExtended
|
||||||
} from '@user/data-base';
|
} from '@user/data-base';
|
||||||
|
|
||||||
export interface ITriggerHandler<TEnemy = unknown, THero = unknown> {
|
export interface ITriggerHandler {
|
||||||
/** 当前全局状态对象 */
|
/** 当前全局状态对象 */
|
||||||
readonly state: IStateBase<TEnemy, THero>;
|
readonly state: IStateBase;
|
||||||
/** 当前楼层状态对象 */
|
/** 当前楼层状态对象 */
|
||||||
readonly layer?: ILayerState;
|
readonly layer?: ILayerState;
|
||||||
/** 当前参与触发的图层对象 */
|
/** 当前参与触发的图层对象 */
|
||||||
@ -17,15 +17,9 @@ export interface ITriggerHandler<TEnemy = unknown, THero = unknown> {
|
|||||||
readonly locator?: ITileLocator;
|
readonly locator?: ITileLocator;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TriggerFactory<TEnemy, THero> = (
|
export type TriggerFactory = (type: number, state: IStateBase) => ITrigger;
|
||||||
type: number,
|
|
||||||
state: IStateBase<TEnemy, THero>
|
|
||||||
) => ITrigger<TEnemy, THero>;
|
|
||||||
|
|
||||||
export interface ITrigger<
|
export interface ITrigger extends IStateBaseExtended {
|
||||||
TEnemy = unknown,
|
|
||||||
THero = unknown
|
|
||||||
> extends IStateBaseExtended<TEnemy, THero> {
|
|
||||||
/** 触发器类型标识 */
|
/** 触发器类型标识 */
|
||||||
readonly type: number;
|
readonly type: number;
|
||||||
/** 触发器优先级 */
|
/** 触发器优先级 */
|
||||||
@ -35,39 +29,36 @@ export interface ITrigger<
|
|||||||
* 使用给定上下文触发当前触发器
|
* 使用给定上下文触发当前触发器
|
||||||
* @param handler 触发上下文对象
|
* @param handler 触发上下文对象
|
||||||
*/
|
*/
|
||||||
trigger(handler: ITriggerHandler<TEnemy, THero>): Promise<void>;
|
trigger(handler: ITriggerHandler): Promise<void>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将当前触发器包装为单元素触发器集合
|
* 将当前触发器包装为单元素触发器集合
|
||||||
*/
|
*/
|
||||||
collection(): ITriggerCollection<TEnemy, THero>;
|
collection(): ITriggerCollection;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ITriggerRegistry<
|
export interface ITriggerRegistry extends IStateBaseExtended {
|
||||||
TEnemy = unknown,
|
|
||||||
THero = unknown
|
|
||||||
> extends IStateBaseExtended<TEnemy, THero> {
|
|
||||||
/**
|
/**
|
||||||
* 注册一个按类型创建的触发器工厂
|
* 注册一个按类型创建的触发器工厂
|
||||||
* @param type 触发器类型
|
* @param type 触发器类型
|
||||||
* @param factory 触发器工厂函数
|
* @param factory 触发器工厂函数
|
||||||
*/
|
*/
|
||||||
register(type: number, factory: TriggerFactory<TEnemy, THero>): void;
|
register(type: number, factory: TriggerFactory): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取指定类型的触发器工厂
|
* 获取指定类型的触发器工厂
|
||||||
* @param type 触发器类型
|
* @param type 触发器类型
|
||||||
*/
|
*/
|
||||||
get(type: number): TriggerFactory<TEnemy, THero> | null;
|
get(type: number): TriggerFactory | null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据触发器类型创建一个触发器实例,如果对应工厂不存在则返回 `null`
|
* 根据触发器类型创建一个触发器实例,如果对应工厂不存在则返回 `null`
|
||||||
* @param num 触发器类型
|
* @param num 触发器类型
|
||||||
*/
|
*/
|
||||||
create(num: number): ITrigger<TEnemy, THero> | null;
|
create(num: number): ITrigger | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ITriggerCollection<TEnemy, THero> {
|
export interface ITriggerCollection {
|
||||||
/**
|
/**
|
||||||
* 当前集合中的触发器数量
|
* 当前集合中的触发器数量
|
||||||
*/
|
*/
|
||||||
@ -77,62 +68,52 @@ export interface ITriggerCollection<TEnemy, THero> {
|
|||||||
* 顺序触发当前集合中的所有触发器
|
* 顺序触发当前集合中的所有触发器
|
||||||
* @param handler 初始触发上下文对象
|
* @param handler 初始触发上下文对象
|
||||||
*/
|
*/
|
||||||
trigger(handler: ITriggerHandler<TEnemy, THero>): Promise<void>;
|
trigger(handler: ITriggerHandler): Promise<void>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 逐个触发当前集合中的触发器,并允许为下一次推进提供新上下文
|
* 逐个触发当前集合中的触发器,并允许为下一次推进提供新上下文
|
||||||
* @param handler 初始触发上下文对象
|
* @param handler 初始触发上下文对象
|
||||||
*/
|
*/
|
||||||
triggerIter(
|
triggerIter(
|
||||||
handler: ITriggerHandler<TEnemy, THero>
|
handler: ITriggerHandler
|
||||||
): AsyncGenerator<
|
): AsyncGenerator<ITrigger, void, ITriggerHandler | null>;
|
||||||
ITrigger<TEnemy, THero>,
|
|
||||||
void,
|
|
||||||
ITriggerHandler<TEnemy, THero> | null
|
|
||||||
>;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 迭代当前集合中的所有触发器
|
* 迭代当前集合中的所有触发器
|
||||||
*/
|
*/
|
||||||
iterate(): Iterable<ITrigger<TEnemy, THero>>;
|
iterate(): Iterable<ITrigger>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 向集合末尾追加一个触发器
|
* 向集合末尾追加一个触发器
|
||||||
* @param trigger 要追加的触发器
|
* @param trigger 要追加的触发器
|
||||||
*/
|
*/
|
||||||
push(trigger: ITrigger<TEnemy, THero>): void;
|
push(trigger: ITrigger): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 向集合头部插入一个触发器
|
* 向集合头部插入一个触发器
|
||||||
* @param trigger 要插入的触发器
|
* @param trigger 要插入的触发器
|
||||||
*/
|
*/
|
||||||
unshift(trigger: ITrigger<TEnemy, THero>): void;
|
unshift(trigger: ITrigger): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将当前集合与其他集合顺序拼接为一个新集合
|
* 将当前集合与其他集合顺序拼接为一个新集合
|
||||||
* @param others 要拼接的其他集合
|
* @param others 要拼接的其他集合
|
||||||
*/
|
*/
|
||||||
concat(
|
concat(...others: ITriggerCollection[]): ITriggerCollection;
|
||||||
...others: ITriggerCollection<TEnemy, THero>[]
|
|
||||||
): ITriggerCollection<TEnemy, THero>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ITriggerCollector<TEnemy, THero> {
|
export interface ITriggerCollector {
|
||||||
/**
|
/**
|
||||||
* 收集指定图层中某一点的所有触发器
|
* 收集指定图层中某一点的所有触发器
|
||||||
* @param x 横坐标
|
* @param x 横坐标
|
||||||
* @param y 纵坐标
|
* @param y 纵坐标
|
||||||
* @param layer 目标图层
|
* @param layer 目标图层
|
||||||
*/
|
*/
|
||||||
collect(
|
collect(x: number, y: number, layer: IMapLayer): ITriggerCollection;
|
||||||
x: number,
|
|
||||||
y: number,
|
|
||||||
layer: IMapLayer
|
|
||||||
): ITriggerCollection<TEnemy, THero>;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 绑定或清除当前 collector 使用的注册表
|
* 绑定或清除当前 collector 使用的注册表
|
||||||
* @param registry 触发器注册表
|
* @param registry 触发器注册表
|
||||||
*/
|
*/
|
||||||
attachRegistry(registry: ITriggerRegistry<TEnemy, THero> | null): void;
|
attachRegistry(registry: ITriggerRegistry | null): void;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,17 +1,18 @@
|
|||||||
import { IStateBase } from '@user/data-base';
|
import { IStateBase } from '@user/data-base';
|
||||||
import { IEnemyContext } from './combat';
|
import { IEnemyContext } from './combat';
|
||||||
import { ITriggerCollector, ITriggerRegistry } from './trigger';
|
import { ITriggerCollector, ITriggerRegistry } from './trigger';
|
||||||
|
import { IEnemyAttr, IHeroAttr } from '@user/data-common';
|
||||||
|
|
||||||
export interface IStateSystem<TEnemy, THero> extends IStateBase<TEnemy, THero> {
|
export interface IStateSystem extends IStateBase {
|
||||||
/** 怪物上下文 */
|
/** 怪物上下文 */
|
||||||
readonly enemyContext: IEnemyContext<TEnemy, THero>;
|
readonly enemyContext: IEnemyContext<IEnemyAttr, IHeroAttr>;
|
||||||
/** 触发器注册 */
|
/** 触发器注册 */
|
||||||
readonly triggerRegistry: ITriggerRegistry<TEnemy, THero>;
|
readonly triggerRegistry: ITriggerRegistry;
|
||||||
/** 触发器收集器 */
|
/** 触发器收集器 */
|
||||||
readonly triggerCollector: ITriggerCollector<TEnemy, THero>;
|
readonly triggerCollector: ITriggerCollector;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IStateSystemExtended<TEnemy = unknown, THero = unknown> {
|
export interface IStateSystemExtended {
|
||||||
/** 当前对象对应的执行层对象(Layer 2 对象) */
|
/** 当前对象对应的执行层对象(Layer 2 对象) */
|
||||||
readonly state: IStateSystem<TEnemy, THero>;
|
readonly state: IStateSystem;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -193,6 +193,7 @@
|
|||||||
"133": "TileStore.addTile: tile number $1 already exists (id: '$2'), old tile data will be overridden.",
|
"133": "TileStore.addTile: tile number $1 already exists (id: '$2'), old tile data will be overridden.",
|
||||||
"134": "TileStore.addTile: tile id '$1' already maps to number $2, old tile data will be overridden.",
|
"134": "TileStore.addTile: tile id '$1' already maps to number $2, old tile data will be overridden.",
|
||||||
"135": "Expected a trigger registry attched before collect triggers.",
|
"135": "Expected a trigger registry attched before collect triggers.",
|
||||||
"136": "Unexpected duplicate trigger priority $1, which may cause trigger executed in an unexpected order."
|
"136": "Unexpected duplicate trigger priority $1, which may cause trigger executed in an unexpected order.",
|
||||||
|
"137": "Unknown guard enemy at locator '$1,$2'."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user