mirror of
https://github.com/motajs/template.git
synced 2026-07-17 01:11:09 +08:00
Compare commits
2 Commits
2d6f709201
...
c97ed868e7
| Author | SHA1 | Date | |
|---|---|---|---|
| c97ed868e7 | |||
| 74370bba3a |
@ -136,7 +136,7 @@ export const enum ItemCategory {
|
||||
Equipment
|
||||
}
|
||||
|
||||
export interface IItemEffect {
|
||||
export interface IItemEffect<THero> {
|
||||
/** 即捡即用事件内容(Pick 类型) */
|
||||
readonly pickEvent: unknown;
|
||||
/** 道具使用事件内容(Constant 和 Consumable 类型) */
|
||||
@ -146,22 +146,37 @@ export interface IItemEffect {
|
||||
* 即捡即用效果,拾取道具时调用
|
||||
* @param item 当前道具数据
|
||||
*/
|
||||
pickEffect(item: IItemRawData): void;
|
||||
pickEffect(item: IItemRawData<THero>): void;
|
||||
|
||||
/**
|
||||
* 道具使用效果,使用道具时调用
|
||||
* @param item 当前道具数据
|
||||
*/
|
||||
useEffect(item: IItemRawData): void;
|
||||
useEffect(item: IItemRawData<THero>): void;
|
||||
|
||||
/**
|
||||
* 能否使用道具
|
||||
* @param item 当前道具数据
|
||||
*/
|
||||
canUse(item: IItemRawData): boolean;
|
||||
canUse(item: IItemRawData<THero>): boolean;
|
||||
}
|
||||
|
||||
export interface IItemRawData {
|
||||
export interface IItemEquipData<THero> {
|
||||
/** 可以装备至的装备槽,`number` 表示指定索引装备槽,`string` 表示指定装备槽名称,每个装备槽之间为或的关系 */
|
||||
readonly slots: (number | string)[];
|
||||
/** 动画 id */
|
||||
readonly animate: AnimationIds;
|
||||
/** 数值加成 */
|
||||
readonly value: Map<SelectKey<THero, number>, number>;
|
||||
/** 百分比加成 */
|
||||
readonly percentage: Map<SelectKey<THero, number>, number>;
|
||||
/** 穿上装备事件 */
|
||||
readonly loadEvent: unknown;
|
||||
/** 脱下装备事件 */
|
||||
readonly unloadEvent: unknown;
|
||||
}
|
||||
|
||||
export interface IItemRawData<THero> {
|
||||
/** 道具在地图上的图块数字 */
|
||||
readonly num: number;
|
||||
/** 道具的字符串标识符 */
|
||||
@ -177,26 +192,26 @@ export interface IItemRawData {
|
||||
readonly hideInToolbox: boolean;
|
||||
|
||||
/** 道具效果对象(非 Equipment 类型) */
|
||||
readonly effect: IItemEffect;
|
||||
readonly effect: IItemEffect<THero>;
|
||||
/** 装备道具属性(Equipment 类型) */
|
||||
readonly equip: unknown;
|
||||
readonly equip: IItemEquipData<THero>;
|
||||
}
|
||||
|
||||
export interface IItemLegacyConverter<TLegacy> {
|
||||
export interface IItemLegacyConverter<THero, TLegacy> {
|
||||
/**
|
||||
* 将旧样板道具定义转换为新的道具原始数据
|
||||
* @param num 道具图块数字
|
||||
* @param legacy 旧样板道具定义
|
||||
*/
|
||||
fromLegacy(num: number, legacy: TLegacy): IItemRawData;
|
||||
fromLegacy(num: number, legacy: TLegacy): IItemRawData<THero>;
|
||||
}
|
||||
|
||||
export interface IItemStore<TLegacy> {
|
||||
export interface IItemStore<THero, TLegacy> {
|
||||
/**
|
||||
* 获取指定图块数字对应的道具原始数据
|
||||
* @param num 道具图块数字
|
||||
*/
|
||||
getData(num: number): IItemRawData | null;
|
||||
getData(num: number): IItemRawData<THero> | null;
|
||||
|
||||
/**
|
||||
* 获取指定图块数字对应的道具分类
|
||||
@ -208,20 +223,22 @@ export interface IItemStore<TLegacy> {
|
||||
* 添加一个道具原始数据定义
|
||||
* @param data 道具原始数据
|
||||
*/
|
||||
addItem(data: IItemRawData): void;
|
||||
addItem(data: IItemRawData<THero>): void;
|
||||
|
||||
/**
|
||||
* 挂载一个旧样板转换器
|
||||
* @param converter 旧样板转换器
|
||||
*/
|
||||
attachLegacyConverter(converter: IItemLegacyConverter<TLegacy>): void;
|
||||
attachLegacyConverter(
|
||||
converter: IItemLegacyConverter<THero, TLegacy>
|
||||
): void;
|
||||
|
||||
/**
|
||||
* 使用当前转换器转换并写入一个旧样板道具定义
|
||||
* @param num 道具图块数字
|
||||
* @param legacy 旧样板道具定义
|
||||
*/
|
||||
fromLegacy(num: number, legacy: TLegacy): IItemRawData;
|
||||
fromLegacy(num: number, legacy: TLegacy): IItemRawData<THero>;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
@ -47,7 +47,7 @@ export interface IDataCommon {
|
||||
/** 图块定义存储 */
|
||||
readonly tileStore: ITileStore<MapDataOf<keyof NumberToId>>;
|
||||
/** 道具定义存储 */
|
||||
readonly itemStore: IItemStore<Item<AllIdsOf<'items'>>>;
|
||||
readonly itemStore: IItemStore<IHeroAttr, Item<AllIdsOf<'items'>>>;
|
||||
/** 朝向绑定 */
|
||||
readonly roleFace: IRoleFaceBinder;
|
||||
/** 朝向管理 */
|
||||
|
||||
@ -82,7 +82,7 @@ export class CoreState implements ICoreState {
|
||||
readonly roleFace: IRoleFaceBinder;
|
||||
readonly faceManager: IFaceManager;
|
||||
readonly tileStore: ITileStore<LegacyTileData>;
|
||||
readonly itemStore: IItemStore<LegacyItemData>;
|
||||
readonly itemStore: IItemStore<IHeroAttr, LegacyItemData>;
|
||||
|
||||
// Layer 1 数据层,所有可存档内容都在这,一般用于数据存储
|
||||
readonly maps: IMapStore;
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import {
|
||||
IHeroAttr,
|
||||
IItemEffect,
|
||||
IItemEquipData,
|
||||
IItemLegacyConverter,
|
||||
IItemRawData,
|
||||
ItemCategory
|
||||
@ -8,16 +10,26 @@ import { IStateSystem } from '@user/data-system';
|
||||
|
||||
export type LegacyItemData = Item<AllIdsOf<'items'>>;
|
||||
|
||||
type LegacyItemEffectFn = (state: IStateSystem, item: IItemRawData) => void;
|
||||
type LegacyItemCanUseFn = (state: IStateSystem, item: IItemRawData) => boolean;
|
||||
type LegacyItemEffectFn = (
|
||||
state: IStateSystem,
|
||||
item: IItemRawData<IHeroAttr>
|
||||
) => void;
|
||||
type LegacyItemCanUseFn = (
|
||||
state: IStateSystem,
|
||||
item: IItemRawData<IHeroAttr>
|
||||
) => boolean;
|
||||
|
||||
class LegacyItemEffect implements IItemEffect {
|
||||
class LegacyItemEffect implements IItemEffect<IHeroAttr> {
|
||||
pickEvent: unknown;
|
||||
useEvent: unknown;
|
||||
|
||||
/** 即捡即用效果 */
|
||||
private readonly pickFn: LegacyItemEffectFn | null = null;
|
||||
/** 道具使用效果 */
|
||||
private readonly useFn: LegacyItemEffectFn | null = null;
|
||||
/** 是否能够使用道具 */
|
||||
private readonly canUseFn: LegacyItemCanUseFn | null = null;
|
||||
/** 全局状态对象 */
|
||||
private readonly state: IStateSystem;
|
||||
|
||||
constructor(legacy: LegacyItemData, state: IStateSystem) {
|
||||
@ -50,24 +62,27 @@ class LegacyItemEffect implements IItemEffect {
|
||||
}
|
||||
}
|
||||
|
||||
pickEffect(item: IItemRawData): void {
|
||||
pickEffect(item: IItemRawData<IHeroAttr>): void {
|
||||
this.pickFn?.(this.state, item);
|
||||
}
|
||||
|
||||
useEffect(item: IItemRawData): void {
|
||||
useEffect(item: IItemRawData<IHeroAttr>): void {
|
||||
this.useFn?.(this.state, item);
|
||||
}
|
||||
|
||||
canUse(item: IItemRawData): boolean {
|
||||
canUse(item: IItemRawData<IHeroAttr>): boolean {
|
||||
if (!this.canUseFn) return true;
|
||||
else return this.canUseFn(this.state, item);
|
||||
}
|
||||
}
|
||||
|
||||
export class ItemLegacyBridge implements IItemLegacyConverter<LegacyItemData> {
|
||||
export class ItemLegacyBridge implements IItemLegacyConverter<
|
||||
IHeroAttr,
|
||||
LegacyItemData
|
||||
> {
|
||||
constructor(private readonly state: IStateSystem) {}
|
||||
|
||||
fromLegacy(num: number, legacy: LegacyItemData): IItemRawData {
|
||||
fromLegacy(num: number, legacy: LegacyItemData): IItemRawData<IHeroAttr> {
|
||||
const effect = new LegacyItemEffect(legacy, this.state);
|
||||
return {
|
||||
num,
|
||||
@ -77,10 +92,35 @@ export class ItemLegacyBridge implements IItemLegacyConverter<LegacyItemData> {
|
||||
text: legacy.text ?? '',
|
||||
hideInToolbox: legacy.hideInToolBox,
|
||||
effect,
|
||||
equip: legacy.equip
|
||||
equip: this.convertEquip(legacy.equip)
|
||||
};
|
||||
}
|
||||
|
||||
private convertEquip(legacy: Equip): IItemEquipData<IHeroAttr> {
|
||||
const valueMap = new Map<SelectKey<IHeroAttr, number>, number>();
|
||||
const perMap = new Map<SelectKey<IHeroAttr, number>, number>();
|
||||
|
||||
for (const [key, value] of Object.entries(legacy.value)) {
|
||||
valueMap.set(key as SelectKey<IHeroAttr, number>, value);
|
||||
}
|
||||
for (const [key, value] of Object.entries(legacy.percentage)) {
|
||||
perMap.set(key as SelectKey<IHeroAttr, number>, value);
|
||||
}
|
||||
|
||||
return {
|
||||
slots: [legacy.type],
|
||||
animate: legacy.animate,
|
||||
value: valueMap,
|
||||
percentage: perMap,
|
||||
loadEvent: legacy.equipEvent,
|
||||
unloadEvent: legacy.unequipEvent
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 从旧样板道具类型获取新接口对应的类型
|
||||
* @param cls 旧样板道具类型
|
||||
*/
|
||||
private mapCategory(cls: ItemCls): ItemCategory {
|
||||
switch (cls) {
|
||||
case 'constants':
|
||||
|
||||
@ -5,6 +5,8 @@ packages:
|
||||
ignore:
|
||||
- packages/**/dist
|
||||
- packages/**/node_modules
|
||||
- packages-user/**/dist
|
||||
- packages-user/**/node_modules
|
||||
onlyBuiltDependencies:
|
||||
- core-js
|
||||
- esbuild
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
2. **不恢复我的修改**:我做的任何代码修改都是有原因的。若我在两次对话期间新增、删除或修改了部分代码,不要将其恢复。
|
||||
3. **遇到歧义立即提问**:若思考或实现时遇到任何问题——例如描述模糊、接口不清晰、某些地方存在歧义等——应立即向我提问,而不是按自己的想法去写。若完成需求所需的接口尚不存在,也应当立即停止实现,向我提出疑问,而不是擅自新增接口来推进。
|
||||
4. **修改文件前重读文件,修改后说明内容**:修改文件前务必重新阅读以确保内容是最新版。修改后必须在对话中说明所有改动的文件及具体改动内容。在修改文件时,**不得修改**文档的 `涉及文件` 节未提及的文件。
|
||||
5. **关于 `dev.md` 的强度升级**:`dev.md` 中"一般不建议/尽量避免"的条目在此处视为**绝对禁止**;"建议/最好"的条目在此处视为**必须遵守**。
|
||||
5. **关于 `dev.md` 的强度升级**:`dev.md` 中"一般不建议/尽量避免"的条目在此处视为**绝对禁止**;"建议/最好"的条目在此处视为**必须遵守**。所有私有方法与成员必须添加 jsDoc 注释,在构造函数的参数中定义的成员除外。
|
||||
6. **渲染端永远处于被动**:任何情况下都不可能会出现数据端主动通知渲染端进行更新的场景,渲染端仅通过钩子与数据端通信,通过钩子被动获取信息,并在某些情况下影响数据端行为。
|
||||
7. **关于非空判断**:对于对象,直接使用 `if (!object)` 的方式进行判断,对于字面量,使用 `lodash` 接口 `isNil` 判断 `if (isNil(value))`,不要使用 `if (value === undefined)` 这种方式。
|
||||
8. **方法顺序**:对于类的方法,根据功能进行排序,而不是按照修饰词进行排序。对于较长或功能较多的类,使用 `#region` 进行分区,分区按照方法功能进行划分。所有类的成员必须写到类的开头,并按照功能排序。
|
||||
|
||||
Loading…
Reference in New Issue
Block a user