refactor: src/game 全部移入 monorepo

This commit is contained in:
unanmed 2025-03-09 15:49:11 +08:00
parent f7c6434aba
commit ef8d3e9e2e
54 changed files with 722 additions and 254 deletions

View File

@ -11,7 +11,12 @@
"update": "tsx script/update.ts",
"declare": "tsx script/declare.ts",
"type": "vue-tsc --noEmit",
"lines": "tsx script/lines.ts"
"lines": "tsx script/lines.ts",
"build:packages": "vue-tsx --noEmit && tsx script/build-packages.ts",
"build:game": "vue-tsx --noEmit && tsx script/build-game.ts",
"docs:dev": "vitepress dev docs",
"docs:build": "vitepress build docs",
"docs:preview": "vitepress preview docs"
},
"dependencies": {
"@ant-design/icons-vue": "^6.1.0",
@ -71,7 +76,7 @@
"typescript": "^5.5.4",
"typescript-eslint": "^8.18.2",
"unplugin-vue-components": "^0.22.12",
"vite": "^4.5.3",
"vite": "^4.5.9",
"vite-plugin-dts": "^4.4.0",
"vitepress": "^1.5.0",
"vue-tsc": "^2.1.6",

View File

@ -0,0 +1,6 @@
{
"name": "@user/data-base",
"dependencies": {
"@motajs/types": "workspace:*"
}
}

View File

@ -1,5 +1,5 @@
import { EventEmitter } from 'eventemitter3';
import type { DamageEnemy, EnemyCollection } from './enemy/damage';
import { IDamageEnemy, IEnemyCollection } from '@motajs/types';
// ----- 加载事件
interface GameLoadEvent {
@ -82,7 +82,7 @@ export interface GameEvent {
/** Emitted in project/functions.js moveOneStep */
moveOneStep: [x: number, y: number, floorId: FloorIds];
/** Emitted in src/game/enemy/battle.ts afterBattle */
afterBattle: [enemy: DamageEnemy, x?: number, y?: number];
afterBattle: [enemy: IDamageEnemy, x?: number, y?: number];
/** Emitted in libs/events.js changingFloor */
changingFloor: [floorId: FloorIds, heroLoc: Loc];
/** Emitted in libs/maps.js setBlock */
@ -94,7 +94,7 @@ export interface GameEvent {
oldBlock: AllNumbers
];
/** Emitted in game/enemy/damage.ts */
enemyExtract: [col: EnemyCollection];
enemyExtract: [col: IEnemyCollection];
/** Emitted in lib/events.js restart */
restart: [];
/** Emitted in lib/maps.js setBgFgBlock */

View File

@ -0,0 +1 @@
export * from './game';

View File

@ -0,0 +1,8 @@
{
"name": "@user/data-fallback",
"dependencies": {
"@motajs/legacy-common": "workspace:*",
"@user/data-state": "workspace:*",
"@user/data-base": "workspace:*"
}
}

View File

@ -1,7 +1,14 @@
import { DamageEnemy, ensureFloorDamage, getSingleEnemy } from './damage';
import { findDir, has } from '../../plugin/game/utils';
import { hook, loading } from '../game';
import { HeroSkill, NightSpecial } from '../mechanism/misc';
import {
DamageEnemy,
ensureFloorDamage,
getSingleEnemy,
getEnemy,
HeroSkill,
NightSpecial
} from '@user/data-state';
import { hook, loading } from '@user/data-base';
import { Patch, PatchClass } from '@motajs/legacy-common';
import { isNil } from 'lodash-es';
export interface CurrentEnemy {
enemy: DamageEnemy;
@ -9,22 +16,11 @@ export interface CurrentEnemy {
onMapEnemy: DamageEnemy[];
}
export function getEnemy(
x: number,
y: number,
floorId: FloorIds = core.status.floorId
) {
const enemy = core.status.maps[floorId].enemy.get(x, y);
return enemy;
}
function init() {
core.enemys.canBattle = function canBattle(
x: number | DamageEnemy,
y: number,
floorId: FloorIds = core.status.floorId
) {
const enemy = typeof x === 'number' ? getEnemy(x, y, floorId) : x;
const patch = new Patch(PatchClass.Enemys);
patch.add('canBattle', function (x, y, floorId) {
const enemy = typeof x === 'number' ? getEnemy(x, y!, floorId) : x;
if (!enemy) {
throw new Error(
`Cannot get enemy on x:${x}, y:${y}, floor: ${floorId}`
@ -33,7 +29,7 @@ function init() {
const { damage } = enemy.calDamage();
return damage < core.status.hero.hp;
};
});
core.events.battle = function battle(
x: number | DamageEnemy,
@ -206,7 +202,7 @@ function init() {
}
// 如果是融化怪,需要特殊标记一下
if (special.has(25) && has(x) && has(y)) {
if (special.has(25) && !isNil(x) && !isNil(y)) {
flags[`melt_${floorId}`] ??= {};
flags[`melt_${floorId}`][`${x},${y}`] = enemy.info.melt;
}
@ -231,7 +227,7 @@ function init() {
const todo: MotaEvent = [];
// 战后事件
if (has(core.status.floorId)) {
if (!isNil(core.status.floorId)) {
const loc = `${x},${y}` as LocString;
todo.push(
...(core.floors[core.status.floorId].afterBattle[loc] ?? [])
@ -242,7 +238,7 @@ function init() {
// 如果事件不为空,将其插入
if (todo.length > 0) core.insertAction(todo, x, y);
if (has(x) && has(y)) {
if (!isNil(x) && !isNil(y)) {
core.drawAnimate(animate, x, y);
core.removeBlock(x, y);
} else core.drawHeroAnimate(animate);

View File

View File

@ -0,0 +1,9 @@
{
"name": "@user/data-state",
"dependencies": {
"@motajs/types": "workspace:*",
"@motajs/common": "workspace:*",
"@user/data-base": "workspace:*",
"@user/data-utils": "workspace:*"
}
}

View File

@ -1,75 +1,28 @@
import { getHeroStatusOf, getHeroStatusOn } from '@/game/state/hero';
import { Range } from '../util/range';
import { getHeroStatusOf, getHeroStatusOn } from '../state/hero';
import { Range } from '@user/data-utils';
import { ensureArray, has, manhattan } from '@/plugin/game/utils';
import EventEmitter from 'eventemitter3';
import { hook } from '../game';
import { hook } from '@user/data-base';
import { HeroSkill, NightSpecial } from '../mechanism/misc';
import {
EnemyInfo,
DamageInfo,
DamageDelta,
HaloData,
CriticalDamageDelta,
MapDamage,
HaloFn,
IEnemyCollection,
IDamageEnemy,
HaloType
} from '@motajs/types';
// todo: 光环划分优先级,从而可以实现光环的多级运算
interface HaloType {
square: {
x: number;
y: number;
d: number;
};
manhattan: {
x: number;
y: number;
d: number;
};
}
export interface EnemyInfo extends Partial<Omit<Enemy, 'special'>> {
atk: number;
def: number;
hp: number;
special: Set<number>;
damageDecline: number;
atkBuff_: number;
defBuff_: number;
hpBuff_: number;
enemy: Enemy;
x?: number;
y?: number;
floorId?: FloorIds;
export interface UserEnemyInfo extends EnemyInfo {
togetherNum?: number;
}
interface DamageInfo {
damage: number;
/** 自动切换技能时使用的技能 */
skill?: number;
}
export interface MapDamage {
damage: number;
type: Set<string>;
mockery?: LocArr[];
hunt?: [x: number, y: number, dir: Dir][];
}
interface HaloData<T extends keyof HaloType = keyof HaloType> {
type: T;
data: HaloType[T];
special: number;
from?: DamageEnemy;
}
interface DamageDelta {
/** 跟最小伤害值的减伤 */
delta: number;
damage: number;
info: DamageInfo;
}
interface CriticalDamageDelta extends Omit<DamageDelta, 'info'> {
/** 勇士的攻击增量 */
atkDelta: number;
}
type HaloFn = (info: EnemyInfo, enemy: EnemyInfo) => void;
/** 光环属性 */
export const haloSpecials: Set<number> = new Set([
8, 21, 25, 26, 27, 29, 31, 32
@ -105,7 +58,10 @@ interface EnemyCollectionEvent {
calculated: [];
}
export class EnemyCollection extends EventEmitter<EnemyCollectionEvent> {
export class EnemyCollection
extends EventEmitter<EnemyCollectionEvent>
implements IEnemyCollection
{
floorId: FloorIds;
list: Map<number, DamageEnemy> = new Map();
@ -130,7 +86,7 @@ export class EnemyCollection extends EventEmitter<EnemyCollectionEvent> {
get(x: number, y: number) {
const index = x + y * this.width;
return this.list.get(index);
return this.list.get(index) ?? null;
}
/**
@ -242,12 +198,12 @@ export class EnemyCollection extends EventEmitter<EnemyCollectionEvent> {
}
}
export class DamageEnemy<T extends EnemyIds = EnemyIds> {
id: T;
export class DamageEnemy implements IDamageEnemy {
id: EnemyIds;
x?: number;
y?: number;
floorId?: FloorIds;
enemy: Enemy<T>;
enemy: Enemy;
col?: EnemyCollection;
/**
@ -255,7 +211,7 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
* () ->
* -> provide inject -> ->
*/
info!: EnemyInfo;
info!: UserEnemyInfo;
/** 向其他怪提供过的光环 */
providedHalo: Set<number> = new Set();
@ -267,7 +223,7 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
progress: number = 0;
constructor(
enemy: Enemy<T>,
enemy: Enemy,
x?: number,
y?: number,
floorId?: FloorIds,
@ -426,7 +382,7 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
// 这一句必须放到applyHalo之前
this.providedHalo.add(29);
const halo = (e: EnemyInfo, enemy: EnemyInfo) => {
const halo = (e: UserEnemyInfo, enemy: UserEnemyInfo) => {
const s = enemy.specialHalo!;
for (const spe of s) {
@ -489,7 +445,7 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
'square',
{ x: this.x, y: this.y, d: 5 },
this,
(e, enemy) => {
(e: UserEnemyInfo, enemy) => {
if (
e.special.has(8) &&
(e.x !== this.x || this.y !== e.y)
@ -620,7 +576,7 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
/**
*
*/
injectHalo(halo: HaloFn, enemy: EnemyInfo) {
injectHalo(halo: HaloFn, enemy: UserEnemyInfo) {
halo(this.info, enemy);
}
@ -769,7 +725,7 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
if (type) damage[loc].type.add(type);
}
private calEnemyDamageOf(hero: Partial<HeroStatus>, enemy: EnemyInfo) {
private calEnemyDamageOf(hero: Partial<HeroStatus>, enemy: UserEnemyInfo) {
const status = getHeroStatusOf(hero, realStatus, this.floorId);
let damage = calDamageWith(enemy, status) ?? Infinity;
let bestSkill = -1;
@ -991,7 +947,7 @@ const skills: HeroSkill.Skill[] = [HeroSkill.Blade, HeroSkill.Shield];
* @param hero
*/
export function calDamageWith(
info: EnemyInfo,
info: UserEnemyInfo,
hero: Partial<HeroStatus>
): number | null {
const { hp, mdef } = core.status.hero;
@ -1112,6 +1068,15 @@ export function getSingleEnemy(id: EnemyIds) {
return enemy;
}
export function getEnemy(
x: number,
y: number,
floorId: FloorIds = core.status.floorId
) {
const enemy = core.status.maps[floorId].enemy.get(x, y);
return enemy;
}
declare global {
interface Floor {
enemy: EnemyCollection;

View File

@ -0,0 +1,2 @@
export * from './damage';
export * from './special';

View File

@ -1,16 +1,16 @@
import { getHeroStatusOn } from '@/game/state/hero';
import { EnemyInfo } from './damage';
import { getHeroStatusOn } from '../state/hero';
import { UserEnemyInfo } from './damage';
export interface SpecialDeclaration {
code: number;
name: string | ((enemy: EnemyInfo) => string);
desc: string | ((enemy: EnemyInfo) => string);
name: string | ((enemy: UserEnemyInfo) => string);
desc: string | ((enemy: UserEnemyInfo) => string);
color: string;
}
const fromFunc = (
func: string | ((enemy: EnemyInfo) => string),
enemy: EnemyInfo
func: string | ((enemy: UserEnemyInfo) => string),
enemy: UserEnemyInfo
) => {
return typeof func === 'string' ? func : func(enemy);
};

View File

@ -0,0 +1,3 @@
export * from './enemy';
export * from './mechanism';
export * from './state';

View File

@ -0,0 +1 @@
export * from './misc';

View File

@ -1,5 +1,5 @@
import { backDir, has } from '@/plugin/game/utils';
import { loading } from '../game';
import { loading } from '@user/data-base';
import type { LayerDoorAnimate } from '@motajs/render';
import { getSkillLevel } from '@/plugin/game/skillTree';
@ -210,9 +210,9 @@ export namespace BluePalace {
core.lockControl();
core.playSound('door.opus');
const Adapter = Mota.require('module', 'Render').RenderAdapter;
const Adapter = Mota.require('@motajs/render').RenderAdapter;
const adapter = Adapter.get<LayerDoorAnimate>('door-animate');
const texture = Mota.require('module', 'Render').texture;
const texture = Mota.require('@motajs/render').texture;
if (adapter) {
Promise.all(
toConvert.map(v => {

View File

@ -0,0 +1,5 @@
export * from './hero';
export * from './interface';
export * from './item';
export * from './move';
export * from './utils';

View File

@ -1,5 +1,5 @@
import EventEmitter from 'eventemitter3';
import { loading } from '../game';
import { loading } from '@user/data-base';
type EffectFn = () => void;
type CanUseEffectFn = () => boolean;

View File

@ -1,6 +1,6 @@
import EventEmitter from 'eventemitter3';
import { backDir, checkCanMoveExtended, toDir } from './utils';
import { loading } from '../game';
import { loading } from '@user/data-base';
import type {
RenderAdapter,
HeroRenderer,
@ -13,7 +13,7 @@ import type {
} from '@motajs/render';
import type { HeroKeyMover } from '@/module/action/move';
import { BluePalace, MiscData } from '../mechanism/misc';
import { sleep } from 'mutate-animate';
import { sleep } from '@motajs/common';
interface MoveStepDir {
type: 'dir';
@ -316,7 +316,7 @@ export class BlockMover extends ObjectMoverBase {
this.blockNum = blockNum;
Mota.r(() => {
const { Layer } = Mota.require('module', 'Render');
const { Layer } = Mota.require('@motajs/render');
const r = Layer.getMovingRenderable(blockNum, this.x, this.y);
if (r) {
@ -877,7 +877,7 @@ export class HeroMover extends ObjectMoverBase {
const adapter = HeroMover.adapter;
const viewport = HeroMover.viewport;
if (!adapter || !viewport) return;
const MotaRenderer = Mota.require('module', 'Render').MotaRenderer;
const MotaRenderer = Mota.require('@motajs/render').MotaRenderer;
const render = MotaRenderer.get('render-main');
const group = render?.getElementById('layer-loop') as LayerGroup;
const layer = group?.getLayer('event');
@ -939,8 +939,8 @@ export const heroMoveCollection: HeroMoveCollection = {
loading.once('coreInit', () => {
// 注册按键操作
Mota.r(() => {
const { HeroKeyMover } = Mota.require('module', 'Action');
const gameKey = Mota.require('var', 'gameKey');
const { HeroKeyMover } = Mota.require('@motajs/system-action');
const { gameKey } = Mota.require('@motajs/system-action');
const keyMover = new HeroKeyMover(gameKey, heroMover);
heroMoveCollection.keyMover = keyMover;
});
@ -949,7 +949,7 @@ loading.once('coreInit', () => {
// Adapter初始化
loading.once('coreInit', () => {
if (main.replayChecking || main.mode === 'editor') return;
const Adapter = Mota.require('module', 'Render').RenderAdapter;
const Adapter = Mota.require('@motajs/render').RenderAdapter;
const adapter = Adapter.get<HeroRenderer>('hero-adapter');
const viewport = Adapter.get<FloorViewport>('viewport');
const layerAdapter = Adapter.get<Layer>('layer');

View File

@ -0,0 +1,6 @@
{
"name": "@user/data-utils",
"dependencies": {
"@user/data-base": "workspace:*"
}
}

View File

@ -0,0 +1 @@
export * from './range';

View File

@ -0,0 +1,21 @@
{
"name": "@motajs/entry-client",
"dependencies": {
"@motajs/client": "workspace:*",
"@motajs/client-base": "workspace:*",
"@motajs/common": "workspace:*",
"@motajs/render": "workspace:*",
"@motajs/render-core": "workspace:*",
"@motajs/render-elements": "workspace:*",
"@motajs/render-style": "workspace:*",
"@motajs/render-vue": "workspace:*",
"@motajs/system": "workspace:*",
"@motajs/system-ui": "workspace:*",
"@motajs/system-action": "workspace:*",
"@motajs/legacy-common": "workspace:*",
"@motajs/legacy-client": "workspace:*",
"@motajs/legacy-data": "workspace:*",
"@motajs/legacy-ui": "workspace:*",
"@motajs/legacy-system": "workspace:*"
}
}

View File

@ -0,0 +1,34 @@
import { Mota } from '@user/entry-data';
import * as Client from '@motajs/client';
import * as ClientBase from '@motajs/client-base';
import * as Common from '@motajs/common';
import * as LegacyClient from '@motajs/legacy-client';
import * as LegacyCommon from '@motajs/legacy-common';
import * as LegacySystem from '@motajs/legacy-system';
import * as LegacyUI from '@motajs/legacy-ui';
import * as Render from '@motajs/render';
import * as RenderCore from '@motajs/render-core';
import * as RenderElements from '@motajs/render-elements';
import * as RenderStyle from '@motajs/render-style';
import * as RenderVue from '@motajs/render-vue';
import * as System from '@motajs/system';
import * as SystemAction from '@motajs/system-action';
import * as SystemUI from '@motajs/system-ui';
export function create() {
Mota.register('@motajs/client', Client);
Mota.register('@motajs/client-base', ClientBase);
Mota.register('@motajs/common', Common);
Mota.register('@motajs/legacy-client', LegacyClient);
Mota.register('@motajs/legacy-common', LegacyCommon);
Mota.register('@motajs/legacy-system', LegacySystem);
Mota.register('@motajs/legacy-ui', LegacyUI);
Mota.register('@motajs/render', Render);
Mota.register('@motajs/render-core', RenderCore);
Mota.register('@motajs/render-elements', RenderElements);
Mota.register('@motajs/render-style', RenderStyle);
Mota.register('@motajs/render-vue', RenderVue);
Mota.register('@motajs/system', System);
Mota.register('@motajs/system-action', SystemAction);
Mota.register('@motajs/system-ui', SystemUI);
}

View File

@ -0,0 +1 @@
export * from './create';

View File

@ -0,0 +1,3 @@
{
"name": "@user/entry-data"
}

View File

@ -0,0 +1,5 @@
import { createMota } from './mota';
createMota();
export * from './mota';

View File

@ -67,7 +67,7 @@ export interface IMota {
/**
* Mota
*/
class Mota implements IMota {
class MotaSystem implements IMota {
private modules: Record<string, any> = {};
r = r;
@ -137,4 +137,8 @@ declare global {
}
}
window.Mota = new Mota();
export const Mota = new MotaSystem();
export function createMota() {
window.Mota = Mota;
}

View File

@ -1,8 +1,6 @@
{
"name": "@motajs/client",
"dependencies": {
"@motajs/render": "workspace:*",
"@motajs/client-base": "workspace:*",
"@motajs/system": "workspace:*"
"@motajs/client-base": "workspace:*"
}
}

View File

@ -1,3 +1 @@
export * as Base from '@motajs/client-base';
export * as Render from '@motajs/render';
export * as System from '@motajs/system';

View File

@ -1 +1,2 @@
export * from './logger';
export * from './utils';

View File

@ -0,0 +1,3 @@
export function sleep(time: number) {
return new Promise(res => setTimeout(res, time));
}

View File

@ -0,0 +1,62 @@
{
"screen": {
"fullscreen": [
"是否全屏进行游戏全屏后按ESC退出全屏开启后将不能通过按ESC开启系统设置菜单",
"请按下方的按钮打开。进入或退出全屏后请存读档一下,以解决一部分绘制问题。"
],
"halo": ["开启后,会在地图上显示范围光环。"],
"itemDetail": ["是否在地图上显示宝石血瓶装备等增加的属性值"],
"transition": [
"是否展示当一个ui界面如怪物手册等的打开与关闭时的动画。当此项开启时",
"所有界面被打开或关闭时都会展示动画,否则会直接展示出来"
],
"fontSize": [
"在各种 ui 界面中显示的文字大小,范围为 2 - 48。注意字体过大可能会引起 ui 布局发生错误"
],
"criticalGem": ["临界是否显示为在当前地图要吃的宝石数"]
},
"action": {
"autoSkill": [
"开启后,打怪物的时候会自动选择伤害最低的技能。同时显伤也会显示此状态下的伤害,",
"临界也会考虑技能在内"
],
"fixed": [
"开启后,当鼠标移动到怪物上时,会以盒子的形式展示该点的怪物信息。手机端此功能无效。",
"<br>",
"<br>",
"注当鼠标移动到怪物上时经过200毫秒才会显示信息防止误操作。"
],
"hotkey": ["设置游戏中会用到的一些快捷键"],
"toolbar": [
"允许你在工具栏上自定义按钮,包括使用道具、开关技能、按下某个按键等。",
"推荐手机进行一些设置"
]
},
"utils": {
"betterLoad": [
"<span style=\"color: yellow; font-weight: 700\">试验性功能</span>",
"<br>",
"开启后游戏将对加载进行优化,缩短进入游戏时的加载时长,而在游戏中对资源进行部分性按需加载,从而对加载进行优化。",
"该设置不会影响你的正常游戏,但如果网络环境较差,可能会导致部分楼层转换时间明显变长。",
"<br>",
"<br>",
"注:修改后刷新页面起效。"
],
"autoScale": [
"开启后,每次进入游戏时会自动缩放游戏画面至合适值。该项只对电脑端有效。",
"<br>",
"<br>",
"缩放原则如下:",
"<br>",
"1. 首先尝试缩放至最大缩放比例",
"<br>",
"2. 如果缩放后游戏画面高度高于页面高度的95%,那么缩小一个缩放比例,否则保持最大比例"
]
},
"fx": {
"paraLight": [
"是否开启野外的平行光阴影,在野外将会显示平行光阴影,模拟太阳光,拥有不错的视觉效果"
],
"frag": ["开启后,在打败怪物后会触发怪物碎裂特效。"]
}
}

View File

@ -1,11 +1,11 @@
import { IDamageEnemy } from '@motajs/types';
import { fixedUi } from './preset/ui';
import type { DamageEnemy } from '@/game/enemy/damage';
import { tip } from './utils';
import { ref, Ref } from 'vue';
export interface MarkInfo<T extends EnemyIds> {
id: T;
enemy: DamageEnemy<T>;
enemy: IDamageEnemy;
/**
*
* 1.

View File

@ -21,10 +21,8 @@
</template>
<script lang="ts" setup>
import { checkAssist } from '@/core/main/custom/hotkey';
import { Keyboard } from '@/core/main/custom/keyboard';
import { KeyboardEmits } from '@/core/main/custom/keyboard';
import { KeyCodeUtils } from '@motajs/client';
import { checkAssist, Keyboard, KeyboardEmits } from '@motajs/system-action';
import { KeyCodeUtils } from '@motajs/client-base';
import { nextTick, onUnmounted, ref } from 'vue';
const props = defineProps<{

View File

@ -9,7 +9,7 @@ import {
UiController
} from '@motajs/legacy-ui';
import { bgmController, soundPlayer } from '@/module';
import settingsText from '@/data/settings.json';
import settingsText from '../data/settings.json';
//#region legacy-ui
export const mainUi = new UiController();

View File

@ -1,6 +1,7 @@
import list from '../data/achievement.json';
import { achiDict, checkCompletionAchievement } from './completion';
import { changeLocalStorage, has } from '../utils';
import { fixedUi } from '../preset';
type AchievementList = typeof list;
export type AchievementType = keyof AchievementList;
@ -50,7 +51,7 @@ export function completeAchievement(type: AchievementType, index: number) {
if (type === 'explore' && !Object.values(achiDict).includes(index)) {
checkCompletionAchievement();
}
Mota.require('var', 'fixedUi').open('completeAchi', {
fixedUi.open('completeAchi', {
complete: `${type},${index}`
});
}

View File

@ -1,5 +1,11 @@
import type { CurrentEnemy } from '@/game/enemy/battle';
import { has } from '../utils';
import { IDamageEnemy } from '@motajs/types';
export interface CurrentEnemy {
enemy: IDamageEnemy;
// 这个是干啥的?
onMapEnemy: IDamageEnemy[];
}
export interface ToShowEnemy extends CurrentEnemy {
critical: string;

View File

@ -1,7 +1,7 @@
import { getDamageColor } from '../utils';
import { ToShowEnemy } from './book';
import type { DamageEnemy, EnemyInfo } from '@/game/enemy/damage';
import { isMobile } from '../use';
import { EnemyInfo, IDamageEnemy } from '@motajs/types';
export function getLocFromMouseLoc(x: number, y: number): LocArr {
const mx = Math.round(x + core.bigmap.offsetX / 32);
@ -10,7 +10,7 @@ export function getLocFromMouseLoc(x: number, y: number): LocArr {
}
export function getDetailedEnemy(
enemy: DamageEnemy,
enemy: IDamageEnemy,
floorId: FloorIds = core.status.floorId
): ToShowEnemy {
const ratio = core.status.maps[floorId].ratio;

View File

@ -16,12 +16,7 @@ import {
LayerGroup
} from './layer';
import { BlockCacher, CanvasCacheItem, ICanvasCacheItem } from './block';
// todo: 改成接口形式
import type {
DamageEnemy,
EnemyCollection,
MapDamage
} from '@/game/enemy/damage';
import { IDamageEnemy, IEnemyCollection, MapDamage } from '@motajs/types';
const ensureFloorDamage = Mota.require('fn', 'ensureFloorDamage');
@ -151,9 +146,9 @@ export class Damage extends RenderItem<EDamageEvent> {
renderable: Map<number, Set<DamageRenderable>> = new Map();
/** 当前渲染怪物列表 */
enemy?: EnemyCollection;
enemy?: IEnemyCollection;
/** 每个分块中包含的怪物集合 */
blockData: Map<number, Map<number, DamageEnemy>> = new Map();
blockData: Map<number, Map<number, IDamageEnemy>> = new Map();
/** 单元格大小 */
cellSize: number = 32;
@ -224,7 +219,7 @@ export class Damage extends RenderItem<EDamageEvent> {
* {@link Damage.enemy}
* @param enemy
*/
updateCollection(enemy: EnemyCollection) {
updateCollection(enemy: IEnemyCollection) {
if (this.enemy !== enemy) {
this.enemy?.off('calculated', this.onExtract);
enemy.on('calculated', this.onExtract);
@ -322,7 +317,7 @@ export class Damage extends RenderItem<EDamageEvent> {
* @param enemy
* @param block
*/
private extract(enemy: DamageEnemy, block: Set<DamageRenderable>) {
private extract(enemy: IDamageEnemy, block: Set<DamageRenderable>) {
if (enemy.progress !== 4) return;
const x = enemy.x!;
const y = enemy.y!;

View File

@ -22,8 +22,7 @@ import {
RectREllipseParams
} from '@motajs/render-elements';
import { Font } from '@motajs/render-style';
// todo: 改成接口
import type { EnemyCollection } from '@/game/enemy/damage';
import { IEnemyCollection } from '@motajs/types';
export interface CustomProps {
_item: (props: BaseProps) => RenderItem;
@ -144,7 +143,7 @@ export interface DamageProps extends BaseProps {
mapWidth?: number;
mapHeight?: number;
cellSize?: number;
enemy?: EnemyCollection;
enemy?: IEnemyCollection;
font?: string;
strokeStyle?: CanvasStyle;
strokeWidth?: number;

View File

@ -0,0 +1,3 @@
{
"name": "@motajs/types"
}

189
packages/types/src/enemy.ts Normal file
View File

@ -0,0 +1,189 @@
export interface EnemyInfo extends Partial<Omit<Enemy, 'special'>> {
atk: number;
def: number;
hp: number;
special: Set<number>;
damageDecline: number;
atkBuff_: number;
defBuff_: number;
hpBuff_: number;
enemy: Enemy;
x?: number;
y?: number;
floorId?: FloorIds;
}
export interface MapDamage {
damage: number;
type: Set<string>;
mockery?: LocArr[];
hunt?: [x: number, y: number, dir: Dir][];
}
export interface DamageDelta {
/** 跟最小伤害值的减伤 */
delta: number;
damage: number;
info: DamageInfo;
}
export interface CriticalDamageDelta extends Omit<DamageDelta, 'info'> {
/** 勇士的攻击增量 */
atkDelta: number;
}
export interface DamageInfo {
damage: number;
}
export interface HaloType {
square: {
x: number;
y: number;
d: number;
};
manhattan: {
x: number;
y: number;
d: number;
};
}
export interface HaloData<T extends keyof HaloType = keyof HaloType> {
type: T;
data: HaloType[T];
special: number;
from?: IDamageEnemy;
}
export type HaloFn = (info: EnemyInfo, enemy: EnemyInfo) => void;
export interface IDamageEnemy {
/** 怪物 id */
readonly id: EnemyIds;
/** 怪物横坐标,不在地图上的话就是 undefined */
readonly x?: number;
/** 怪物纵坐标,不在地图上的话就是 undefined */
readonly y?: number;
/** 怪物所在地图,不在地图上的话就是 undefined */
readonly floorId?: FloorIds;
/** 怪物原始属性 */
readonly enemy: Enemy;
/** 怪物属性计算进度 */
readonly progress: number;
/** 该怪物伤害信息所属的怪物集 */
readonly col?: IEnemyCollection;
/**
*
* () ->
* -> provide inject -> ->
*/
info: EnemyInfo;
/**
*
*/
reset(): void;
/**
*
*/
getRealInfo(): EnemyInfo;
/**
*
*/
getHaloSpecials(): Set<number>;
/**
*
*/
calDamage(hero?: Partial<HeroStatus>): DamageInfo;
/**
*
* @param damage
*/
calMapDamage(
damage?: Record<string, MapDamage>,
hero?: Partial<HeroStatus>
): Record<string, MapDamage>;
/**
*
* @param num
* @param hero
*/
calCritical(
num?: number,
hero?: Partial<HeroStatus>
): CriticalDamageDelta[];
/**
* n防减伤
* @param num
* @param hero
*/
calDefDamage(num?: number, hero?: Partial<HeroStatus>): DamageDelta;
/**
*
*/
getSeckillAtk(): number;
}
export interface IEnemyCollection {
/** 这个怪物集的地图 id */
readonly floorId: FloorIds;
/** 地图宽度 */
readonly width: number;
/** 地图高度 */
readonly height: number;
/** 每个点的怪物,键是 (x + y * width),值是怪物伤害实例 */
readonly list: Map<number, IDamageEnemy>;
/** 地图伤害 */
readonly mapDamage: Record<string, MapDamage>;
/**
*
* @param x
* @param y
*/
get(x: number, y: number): IDamageEnemy | null;
/**
*
*/
extract(): void;
/**
*
*/
calRealAttribute(): void;
/**
*
*/
calMapDamage(): void;
/**
*
* @param type
* @param data
* @param halo
* @param recursion 使
*/
applyHalo<K extends keyof HaloType>(
type: K,
data: HaloType[K],
enemy: IDamageEnemy,
halo: HaloFn | HaloFn[],
recursion?: boolean
): void;
/**
*
*/
preBalanceHalo(): void;
}

View File

@ -0,0 +1 @@
export * from './enemy';

View File

@ -110,13 +110,13 @@ importers:
version: 8.5.12
'@vitejs/plugin-legacy':
specifier: ^4.1.1
version: 4.1.1(terser@5.31.6)(vite@4.5.3(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6))
version: 4.1.1(terser@5.31.6)(vite@4.5.9(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6))
'@vitejs/plugin-vue':
specifier: ^4.6.2
version: 4.6.2(vite@4.5.3(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6))(vue@3.5.13(typescript@5.5.4))
version: 4.6.2(vite@4.5.9(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6))(vue@3.5.13(typescript@5.5.4))
'@vitejs/plugin-vue-jsx':
specifier: ^3.1.0
version: 3.1.0(vite@4.5.3(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6))(vue@3.5.13(typescript@5.5.4))
version: 3.1.0(vite@4.5.9(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6))(vue@3.5.13(typescript@5.5.4))
chokidar:
specifier: ^3.6.0
version: 3.6.0
@ -175,11 +175,11 @@ importers:
specifier: ^0.22.12
version: 0.22.12(@babel/parser@7.26.9)(rollup@3.29.4)(vue@3.5.13(typescript@5.5.4))
vite:
specifier: ^4.5.3
version: 4.5.3(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6)
specifier: ^4.5.9
version: 4.5.9(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6)
vite-plugin-dts:
specifier: ^4.4.0
version: 4.4.0(@types/node@18.19.44)(rollup@3.29.4)(typescript@5.5.4)(vite@4.5.3(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6))
version: 4.4.0(@types/node@18.19.44)(rollup@3.29.4)(typescript@5.5.4)(vite@4.5.9(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6))
vitepress:
specifier: ^1.5.0
version: 1.5.0(@algolia/client-search@5.18.0)(@types/node@18.19.44)(async-validator@4.2.5)(axios@1.7.4)(less@4.2.0)(postcss@8.5.3)(search-insights@2.17.3)(terser@5.31.6)(typescript@5.5.4)
@ -190,17 +190,64 @@ importers:
specifier: ^8.18.0
version: 8.18.0
packages-user/entry-client:
dependencies:
'@motajs/client':
specifier: workspace:*
version: link:../../packages/client
'@motajs/client-base':
specifier: workspace:*
version: link:../../packages/client-base
'@motajs/common':
specifier: workspace:*
version: link:../../packages/common
'@motajs/legacy-client':
specifier: workspace:*
version: link:../../packages/legacy-client
'@motajs/legacy-common':
specifier: workspace:*
version: link:../../packages/legacy-common
'@motajs/legacy-data':
specifier: workspace:*
version: link:../../packages/legacy-data
'@motajs/legacy-system':
specifier: workspace:*
version: link:../../packages/legacy-system
'@motajs/legacy-ui':
specifier: workspace:*
version: link:../../packages/legacy-ui
'@motajs/render':
specifier: workspace:*
version: link:../../packages/render
'@motajs/render-core':
specifier: workspace:*
version: link:../../packages/render-core
'@motajs/render-elements':
specifier: workspace:*
version: link:../../packages/render-elements
'@motajs/render-style':
specifier: workspace:*
version: link:../../packages/render-style
'@motajs/render-vue':
specifier: workspace:*
version: link:../../packages/render-vue
'@motajs/system':
specifier: workspace:*
version: link:../../packages/system
'@motajs/system-action':
specifier: workspace:*
version: link:../../packages/system-action
'@motajs/system-ui':
specifier: workspace:*
version: link:../../packages/system-ui
packages-user/entry-data: {}
packages/client:
dependencies:
'@motajs/client-base':
specifier: workspace:*
version: link:../client-base
'@motajs/render':
specifier: workspace:*
version: link:../render
'@motajs/system':
specifier: workspace:*
version: link:../system
packages/client-base: {}
@ -208,9 +255,12 @@ importers:
packages/legacy-client:
dependencies:
'@motajs/common':
'@motajs/legacy-system':
specifier: workspace:*
version: link:../common
version: link:../legacy-system
'@motajs/legacy-ui':
specifier: workspace:*
version: link:../legacy-ui
packages/legacy-common:
dependencies:
@ -224,6 +274,12 @@ importers:
specifier: workspace:*
version: link:../common
packages/legacy-system:
dependencies:
'@motajs/system-action':
specifier: workspace:*
version: link:../system-action
packages/legacy-ui:
dependencies:
'@motajs/client':
@ -235,9 +291,15 @@ importers:
'@motajs/common':
specifier: workspace:*
version: link:../common
'@motajs/legacy-system':
specifier: workspace:*
version: link:../legacy-system
'@motajs/render':
specifier: workspace:*
version: link:../render
'@motajs/system-action':
specifier: workspace:*
version: link:../system-action
packages/render:
dependencies:
@ -292,13 +354,25 @@ importers:
'@motajs/render-style':
specifier: workspace:*
version: link:../render-style
'@motajs/system-action':
specifier: workspace:*
version: link:../system-action
packages/system:
dependencies:
'@motajs/system-action':
specifier: workspace:*
version: link:../system-action
'@motajs/system-ui':
specifier: workspace:*
version: link:../system-ui
packages/system-action:
dependencies:
'@motajs/common':
specifier: workspace:*
version: link:../common
packages/system-ui:
dependencies:
'@motajs/common':
@ -328,15 +402,33 @@ importers:
'@motajs/legacy-data':
specifier: workspace:*
version: link:../packages/legacy-data
'@motajs/legacy-system':
specifier: workspace:*
version: link:../packages/legacy-system
'@motajs/legacy-ui':
specifier: workspace:*
version: link:../packages/legacy-ui
'@motajs/render':
specifier: workspace:*
version: link:../packages/render
'@motajs/render-core':
specifier: workspace:*
version: link:../packages/render-core
'@motajs/render-elements':
specifier: workspace:*
version: link:../packages/render-elements
'@motajs/render-style':
specifier: workspace:*
version: link:../packages/render-style
'@motajs/render-vue':
specifier: workspace:*
version: link:../packages/render-vue
'@motajs/system':
specifier: workspace:*
version: link:../packages/system
'@motajs/system-action':
specifier: workspace:*
version: link:../packages/system-action
'@motajs/system-ui':
specifier: workspace:*
version: link:../packages/system-ui
@ -5160,8 +5252,8 @@ packages:
vite:
optional: true
vite@4.5.3:
resolution: {integrity: sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==}
vite@4.5.9:
resolution: {integrity: sha512-qK9W4xjgD3gXbC0NmdNFFnVFLMWSNiR3swj957yutwzzN16xF/E7nmtAyp1rT9hviDroQANjE4HK3H4WqWdFtw==}
engines: {node: ^14.18.0 || >=16.0.0}
hasBin: true
peerDependencies:
@ -5188,8 +5280,8 @@ packages:
terser:
optional: true
vite@5.4.11:
resolution: {integrity: sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==}
vite@5.4.14:
resolution: {integrity: sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==}
engines: {node: ^18.0.0 || >=20.0.0}
hasBin: true
peerDependencies:
@ -7358,7 +7450,7 @@ snapshots:
'@ungap/structured-clone@1.2.1': {}
'@vitejs/plugin-legacy@4.1.1(terser@5.31.6)(vite@4.5.3(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6))':
'@vitejs/plugin-legacy@4.1.1(terser@5.31.6)(vite@4.5.9(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6))':
dependencies:
'@babel/core': 7.25.2
'@babel/preset-env': 7.25.3(@babel/core@7.25.2)
@ -7368,28 +7460,28 @@ snapshots:
regenerator-runtime: 0.13.11
systemjs: 6.15.1
terser: 5.31.6
vite: 4.5.3(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6)
vite: 4.5.9(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6)
transitivePeerDependencies:
- supports-color
'@vitejs/plugin-vue-jsx@3.1.0(vite@4.5.3(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6))(vue@3.5.13(typescript@5.5.4))':
'@vitejs/plugin-vue-jsx@3.1.0(vite@4.5.9(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6))(vue@3.5.13(typescript@5.5.4))':
dependencies:
'@babel/core': 7.25.2
'@babel/plugin-transform-typescript': 7.25.2(@babel/core@7.25.2)
'@vue/babel-plugin-jsx': 1.2.2(@babel/core@7.25.2)
vite: 4.5.3(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6)
vite: 4.5.9(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6)
vue: 3.5.13(typescript@5.5.4)
transitivePeerDependencies:
- supports-color
'@vitejs/plugin-vue@4.6.2(vite@4.5.3(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6))(vue@3.5.13(typescript@5.5.4))':
'@vitejs/plugin-vue@4.6.2(vite@4.5.9(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6))(vue@3.5.13(typescript@5.5.4))':
dependencies:
vite: 4.5.3(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6)
vite: 4.5.9(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6)
vue: 3.5.13(typescript@5.5.4)
'@vitejs/plugin-vue@5.2.1(vite@5.4.11(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6))(vue@3.5.13(typescript@5.5.4))':
'@vitejs/plugin-vue@5.2.1(vite@5.4.14(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6))(vue@3.5.13(typescript@5.5.4))':
dependencies:
vite: 5.4.11(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6)
vite: 5.4.14(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6)
vue: 3.5.13(typescript@5.5.4)
'@volar/language-core@2.4.11':
@ -10548,7 +10640,7 @@ snapshots:
remove-trailing-separator: 1.1.0
replace-ext: 1.0.1
vite-plugin-dts@4.4.0(@types/node@18.19.44)(rollup@3.29.4)(typescript@5.5.4)(vite@4.5.3(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6)):
vite-plugin-dts@4.4.0(@types/node@18.19.44)(rollup@3.29.4)(typescript@5.5.4)(vite@4.5.9(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6)):
dependencies:
'@microsoft/api-extractor': 7.48.1(@types/node@18.19.44)
'@rollup/pluginutils': 5.1.4(rollup@3.29.4)
@ -10561,13 +10653,13 @@ snapshots:
magic-string: 0.30.17
typescript: 5.5.4
optionalDependencies:
vite: 4.5.3(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6)
vite: 4.5.9(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6)
transitivePeerDependencies:
- '@types/node'
- rollup
- supports-color
vite@4.5.3(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6):
vite@4.5.9(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6):
dependencies:
esbuild: 0.18.20
postcss: 8.4.41
@ -10578,7 +10670,7 @@ snapshots:
less: 4.2.0
terser: 5.31.6
vite@5.4.11(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6):
vite@5.4.14(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6):
dependencies:
esbuild: 0.21.5
postcss: 8.4.49
@ -10598,7 +10690,7 @@ snapshots:
'@shikijs/transformers': 1.25.1
'@shikijs/types': 1.25.1
'@types/markdown-it': 14.1.2
'@vitejs/plugin-vue': 5.2.1(vite@5.4.11(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6))(vue@3.5.13(typescript@5.5.4))
'@vitejs/plugin-vue': 5.2.1(vite@5.4.14(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6))(vue@3.5.13(typescript@5.5.4))
'@vue/devtools-api': 7.6.8
'@vue/shared': 3.5.13
'@vueuse/core': 11.3.0(vue@3.5.13(typescript@5.5.4))
@ -10607,7 +10699,7 @@ snapshots:
mark.js: 8.11.1
minisearch: 7.1.1
shiki: 1.25.1
vite: 5.4.11(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6)
vite: 5.4.14(@types/node@18.19.44)(less@4.2.0)(terser@5.31.6)
vue: 3.5.13(typescript@5.5.4)
optionalDependencies:
postcss: 8.5.3

View File

@ -1,8 +1,12 @@
packages:
- 'packages/*'
- 'packages/*/*'
- 'src/'
- packages/*
- packages-user/*
- src/
ignore:
- 'packages/**/dist'
- 'packages/**/node_modules'
- packages/**/dist
- packages/**/node_modules
onlyBuiltDependencies:
- core-js
- esbuild
- ttf2woff2
- vue-demi

40
script/build-game.ts Normal file
View File

@ -0,0 +1,40 @@
import { build, loadConfigFromFile, mergeConfig, UserConfig } from 'vite';
import path from 'path';
import fs from 'fs-extra';
const outputDir = path.resolve(__dirname, '../dist/game');
// 清空 dist/game 目录
fs.emptyDirSync(outputDir);
// 构建游戏
async function buildGame() {
const configFile = path.resolve(__dirname, '../vite.config.ts');
const config = await loadConfigFromFile(
{ command: 'build', mode: 'production' },
configFile
);
const resolved = mergeConfig(config?.config ?? {}, {
build: {
outDir: outputDir,
sourcemap: true,
rollupOptions: {
input: path.resolve(__dirname, '../src/main.ts'),
output: {
format: 'es',
entryFileNames: '[name].[hash].js',
chunkFileNames: 'chunks/[name].[hash].js',
assetFileNames: 'assets/[name].[hash][extname]'
}
}
}
} satisfies UserConfig);
await build(resolved);
console.log('✅ Game built successfully.');
}
buildGame().catch(e => {
console.error(e);
process.exit(1);
});

51
script/build-packages.ts Normal file
View File

@ -0,0 +1,51 @@
import { build, loadConfigFromFile, mergeConfig, UserConfig } from 'vite';
import path from 'path';
import fs from 'fs-extra';
const packagesDir = path.resolve(__dirname, '../packages');
const outputDir = path.resolve(__dirname, '../dist/packages');
// 清空 dist 目录
fs.emptyDirSync(outputDir);
// 获取所有包目录
const packageDirs = fs.readdirSync(packagesDir).filter(name => {
const packagePath = path.join(packagesDir, name);
return fs.statSync(packagePath).isDirectory();
});
// 构建每一个包
async function buildPackages() {
for (const packageName of packageDirs) {
const packageDir = path.join(packagesDir, packageName);
const configFile = path.resolve(__dirname, '../vite.config.ts');
const config = await loadConfigFromFile(
{ command: 'build', mode: 'production' },
configFile
);
const resolved = mergeConfig(config?.config ?? {}, {
build: {
lib: {
entry: path.join(packageDir, 'src/index.ts'),
name: packageName,
formats: ['es'],
fileName: format => `${packageName}.${format}.js`
},
outDir: path.join(outputDir, packageName),
sourcemap: true,
emptyOutDir: true,
rollupOptions: {
external: [/node_modules/, /^@motajs\/.*/]
}
}
} satisfies UserConfig);
await build(resolved);
console.log(`✅ Package ${packageName} built successfully.`);
}
}
buildPackages().catch(e => {
console.error(e);
process.exit(1);
});

View File

@ -1,59 +0,0 @@
import './system';
import '../plugin/game/index';
import * as damage from './enemy/damage';
import { EventEmitter, IndexedEventEmitter } from '@motajs/legacy-common';
import { specials } from './enemy/special';
import { gameListener, hook, loading } from './game';
import * as battle from './enemy/battle';
import * as hero from './state/hero';
import * as miscMechanism from './mechanism/misc';
import { ItemState } from './state/item';
import {
BlockMover,
heroMoveCollection,
HeroMover,
ObjectMoverBase
} from './state/move';
// ----- 类注册
Mota.register('class', 'DamageEnemy', damage.DamageEnemy);
Mota.register('class', 'EnemyCollection', damage.EnemyCollection);
Mota.register('class', 'EventEmitter', EventEmitter);
Mota.register('class', 'IndexedEventEmitter', IndexedEventEmitter);
// ----- 函数注册
Mota.register('fn', 'getEnemy', battle.getEnemy);
Mota.register('fn', 'getHeroStatusOn', hero.getHeroStatusOn);
Mota.register('fn', 'getHeroStatusOf', hero.getHeroStatusOf);
Mota.register('fn', 'ensureFloorDamage', damage.ensureFloorDamage);
// ----- 变量注册
Mota.register('var', 'enemySpecials', specials);
Mota.register('var', 'hook', hook);
Mota.register('var', 'gameListener', gameListener);
Mota.register('var', 'loading', loading);
// ----- 模块注册
Mota.register('module', 'Mechanism', {
BluePalace: miscMechanism.BluePalace,
NightSpecial: miscMechanism.NightSpecial,
MiscData: miscMechanism.MiscData,
HeroSkill: miscMechanism.HeroSkill
});
Mota.register('module', 'State', {
ItemState,
HeroMover,
BlockMover,
ObjectMoverBase,
heroMoveCollection
});
main.loading = loading;
loading.once('coreInit', () => {
Mota.Plugin.init();
});
window.addEventListener('beforeunload', () => {
core.checkAutosave();
});
hook.on('restart', () => {
core.checkAutosave();
});

View File

@ -1,6 +1,6 @@
import { KeyCode } from '@motajs/client-base';
import { Hotkey, HotkeyData } from '@motajs/system-action';
import type { HeroMover, IMoveController } from '@/game/state/move';
import type { HeroMover, IMoveController } from '@user/data-state';
import { Ticker } from 'mutate-animate';
import { mainScope } from '@motajs/legacy-ui';

View File

@ -18,17 +18,21 @@
"baseUrl": ".",
"paths": {
"@/*": ["src/*"],
"@motajs/*": ["packages/*/src"]
"@motajs/*": ["packages/*/src"],
"@user/*": ["packages-user/*/src"]
}
},
"include": [
"src/**/*.ts",
"src/**/*.d.ts",
"src/**/*.tsx",
"src/**/*.vue",
"packages/**/*.ts",
"packages/**/*.d.ts",
"packages/**/*.tsx",
"packages/**/*.vue",
"packages-user/**/*.ts",
"packages-user/**/*.d.ts",
"packages-user/**/*.tsx",
"types/**/*.d.ts"
],
"references": [{ "path": "./tsconfig.node.json" }]

View File

@ -14,7 +14,7 @@ interface PluginDeclaration {
}
type Forward<T> = {
[K in keyof T as T[K] extends Function
[K in keyof T as T[K] extends (...params: any) => any
? K extends `_${string}`
? never
: K
@ -23,7 +23,7 @@ type Forward<T> = {
type ForwardKeys<T> = keyof Forward<T>;
declare const Mota: import('../../src/game/system').IMota;
declare const Mota: import('@user/entry-data').IMota;
interface Window {
Mota: import('../../src/game/system').IMota;
}

View File

@ -36,7 +36,13 @@ export default defineConfig({
}
}),
legacy({
targets: ['defaults', 'not IE 11'],
targets: [
'Chrome >= 56',
'Firefox >= 51',
'Edge >= 79',
'Safari >= 15',
'Opera >= 43'
],
polyfills: true,
modernPolyfills: true
}),