refactor & fix: 插件与进程分离

This commit is contained in:
unanmed 2024-02-02 17:10:21 +08:00
parent 325a1e85ec
commit a9c64565e1
41 changed files with 473 additions and 467 deletions

View File

@ -23,7 +23,7 @@
"jszip": "^3.10.1", "jszip": "^3.10.1",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"lz-string": "^1.5.0", "lz-string": "^1.5.0",
"mutate-animate": "^1.3.2", "mutate-animate": "^1.3.3",
"three": "^0.149.0", "three": "^0.149.0",
"vue": "^3.3.4" "vue": "^3.3.4"
}, },

View File

@ -30,8 +30,8 @@ dependencies:
specifier: ^1.5.0 specifier: ^1.5.0
version: 1.5.0 version: 1.5.0
mutate-animate: mutate-animate:
specifier: ^1.3.2 specifier: ^1.3.3
version: 1.3.2 version: 1.3.3
three: three:
specifier: ^0.149.0 specifier: ^0.149.0
version: 0.149.0 version: 0.149.0
@ -2686,19 +2686,6 @@ packages:
resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==}
dev: true dev: true
/debug@3.2.7:
resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
requiresBuild: true
peerDependencies:
supports-color: '*'
peerDependenciesMeta:
supports-color:
optional: true
dependencies:
ms: 2.1.3
dev: true
optional: true
/debug@4.3.4: /debug@4.3.4:
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
engines: {node: '>=6.0'} engines: {node: '>=6.0'}
@ -3557,10 +3544,8 @@ packages:
image-size: 0.5.5 image-size: 0.5.5
make-dir: 2.1.0 make-dir: 2.1.0
mime: 1.6.0 mime: 1.6.0
needle: 3.2.0 needle: 3.3.1
source-map: 0.6.1 source-map: 0.6.1
transitivePeerDependencies:
- supports-color
dev: true dev: true
/lie@3.3.0: /lie@3.3.0:
@ -3866,8 +3851,8 @@ packages:
resolution: {integrity: sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==} resolution: {integrity: sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==}
dev: true dev: true
/mutate-animate@1.3.2: /mutate-animate@1.3.3:
resolution: {integrity: sha512-d9En7f9EBFHLy4DZtMyAVg6aEyv1+JldM+7I/Fcb2CvGVYxrgl6gqSqYz7W3Ts7SaWW6ckAqJaGVgusvXXv/OA==} resolution: {integrity: sha512-iv6ntOfMIWjaPUvKPb51J706qMghenLSukRQhzSrCyjEqUo/SHgWOFc3mK8J6FF/p5T81IinP3U/eCl0RivcdQ==}
dev: false dev: false
/nan@2.17.0: /nan@2.17.0:
@ -3883,17 +3868,14 @@ packages:
resolution: {integrity: sha512-fzN+T2K7/Ah25XU02MJkPZ5q4Tj5FpjmIYq4rvoHX4yb16HzFdCO6JxFFn5Y/oBhQ8no8fUZavnyIv9/+xkBBw==} resolution: {integrity: sha512-fzN+T2K7/Ah25XU02MJkPZ5q4Tj5FpjmIYq4rvoHX4yb16HzFdCO6JxFFn5Y/oBhQ8no8fUZavnyIv9/+xkBBw==}
dev: false dev: false
/needle@3.2.0: /needle@3.3.1:
resolution: {integrity: sha512-oUvzXnyLiVyVGoianLijF9O/RecZUf7TkBfimjGrLM4eQhXyeJwM6GeAWccwfQ9aa4gMCZKqhAOuLaMIcQxajQ==} resolution: {integrity: sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==}
engines: {node: '>= 4.4.x'} engines: {node: '>= 4.4.x'}
hasBin: true hasBin: true
requiresBuild: true requiresBuild: true
dependencies: dependencies:
debug: 3.2.7
iconv-lite: 0.6.3 iconv-lite: 0.6.3
sax: 1.2.4 sax: 1.2.4
transitivePeerDependencies:
- supports-color
dev: true dev: true
optional: true optional: true

View File

@ -1468,11 +1468,11 @@ control.prototype.updateDamage = function (floorId, ctx) {
}; };
control.prototype._updateDamage_damage = function (floorId, onMap) { control.prototype._updateDamage_damage = function (floorId, onMap) {
// Deprecated. See src/plugin/game/enemy/damage.ts EnemyCollection.render. // Deprecated. See src/game/enemy/damage.ts EnemyCollection.render.
}; };
control.prototype._updateDamage_extraDamage = function (floorId, onMap) { control.prototype._updateDamage_extraDamage = function (floorId, onMap) {
// Deprecated. See src/plugin/game/enemy/damage.ts EnemyCollection.render. // Deprecated. See src/game/enemy/damage.ts EnemyCollection.render.
}; };
////// 重绘地图显伤 ////// ////// 重绘地图显伤 //////

View File

@ -319,11 +319,11 @@ core.prototype._loadGameProcess = async function () {
if (main.pluginUseCompress) { if (main.pluginUseCompress) {
await main.loadScript(`project/processG.min.js?v=${main.version}`); await main.loadScript(`project/processG.min.js?v=${main.version}`);
} else { } else {
if (main.mode === 'play') { // if (main.mode === 'play') {
await main.loadScript(`src/game/index.ts`, true); // await main.loadScript(`src/game/index.ts`, true);
} else { // } else {
await main.loadScript(`src/game/index.esm.ts`, true); // await main.loadScript(`src/game/index.esm.ts`, true);
} // }
} }
}; };

View File

@ -103,43 +103,43 @@ enemys.prototype.getDamageString = function (enemy, x, y, floorId, hero) {
////// 接下来N个临界值和临界减伤计算 ////// ////// 接下来N个临界值和临界减伤计算 //////
enemys.prototype.nextCriticals = function (enemy, number, x, y, floorId, hero) { enemys.prototype.nextCriticals = function (enemy, number, x, y, floorId, hero) {
// Deprecated. See src/plugin/game/enemy/damage.ts DamageEnemy.calCritical. // Deprecated. See src/game/enemy/damage.ts DamageEnemy.calCritical.
}; };
/// 未破防临界采用二分计算 /// 未破防临界采用二分计算
enemys.prototype._nextCriticals_overAtk = function (enemy) { enemys.prototype._nextCriticals_overAtk = function (enemy) {
// Deprecated. See src/plugin/game/enemy/damage.ts DamageEnemy.calCritical. // Deprecated. See src/game/enemy/damage.ts DamageEnemy.calCritical.
}; };
enemys.prototype._nextCriticals_special = function (enemy) { enemys.prototype._nextCriticals_special = function (enemy) {
// Deprecated. See src/plugin/game/enemy/damage.ts DamageEnemy.calCritical. // Deprecated. See src/game/enemy/damage.ts DamageEnemy.calCritical.
}; };
enemys.prototype._nextCriticals_useBinarySearch = function (enemy) { enemys.prototype._nextCriticals_useBinarySearch = function (enemy) {
// Deprecated. See src/plugin/game/enemy/damage.ts DamageEnemy.calCritical. // Deprecated. See src/game/enemy/damage.ts DamageEnemy.calCritical.
}; };
////// N防减伤计算 ////// ////// N防减伤计算 //////
enemys.prototype.getDefDamage = function (enemy, k, x, y, floorId, hero) { enemys.prototype.getDefDamage = function (enemy, k, x, y, floorId, hero) {
// Deprecated. See src/plugin/game/enemy/damage.ts DamageEnemy.calDefDamage. // Deprecated. See src/game/enemy/damage.ts DamageEnemy.calDefDamage.
}; };
enemys.prototype.getEnemyInfo = function (enemy, hero, x, y, floorId) { enemys.prototype.getEnemyInfo = function (enemy, hero, x, y, floorId) {
// Deprecated. See src/plugin/game/enemy/damage.ts // Deprecated. See src/game/enemy/damage.ts
}; };
////// 获得战斗伤害信息(实际伤害计算函数) ////// ////// 获得战斗伤害信息(实际伤害计算函数) //////
enemys.prototype.getDamageInfo = function (enemy, hero, x, y, floorId) { enemys.prototype.getDamageInfo = function (enemy, hero, x, y, floorId) {
// Deprecated. See src/plugin/game/enemy/damage.ts // Deprecated. See src/game/enemy/damage.ts
}; };
////// 获得在某个勇士属性下怪物伤害 ////// ////// 获得在某个勇士属性下怪物伤害 //////
enemys.prototype.getDamage = function (enemy, x, y, floorId, hero) { enemys.prototype.getDamage = function (enemy, x, y, floorId, hero) {
// Deprecated. See src/plugin/game/enemy/damage.ts // Deprecated. See src/game/enemy/damage.ts
}; };
enemys.prototype._getDamage = function (enemy, hero, x, y, floorId) { enemys.prototype._getDamage = function (enemy, hero, x, y, floorId) {
// Deprecated. See src/plugin/game/enemy/damage.ts // Deprecated. See src/game/enemy/damage.ts
}; };
////// 获得当前楼层的怪物列表 ////// ////// 获得当前楼层的怪物列表 //////

View File

@ -27,9 +27,9 @@
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted } from 'vue'; import { onMounted } from 'vue';
import { mainUi, fixedUi } from './core/main/init/ui'; import { mainUi, fixedUi } from './core/main/init/ui';
import { hook } from '@/core/main/game';
onMounted(() => { onMounted(() => {
const { hook } = Mota.requireAll('var');
hook.emit('mounted'); hook.emit('mounted');
}); });

View File

@ -1,5 +1,8 @@
// todo: 更改utils.ts的形式使common文件夹可以同时在渲染进程和游戏进程使用 // todo: 更改utils.ts的形式使common文件夹可以同时在渲染进程和游戏进程使用
import { has } from '@/plugin/utils';
function has<T>(value: T): value is NonNullable<T> {
return value !== null && value !== undefined;
}
export interface EmitableEvent { export interface EmitableEvent {
[event: string]: (...params: any) => any; [event: string]: (...params: any) => any;
@ -21,6 +24,8 @@ type EmitFn<F extends (...params: any) => any> = (
...params: Parameters<F> ...params: Parameters<F>
) => any; ) => any;
console.log(1);
export class EventEmitter<T extends EmitableEvent = {}> { export class EventEmitter<T extends EmitableEvent = {}> {
protected events: { protected events: {
[P in keyof T]?: Listener<T[P]>[]; [P in keyof T]?: Listener<T[P]>[];

View File

@ -1,49 +1,33 @@
import { BgmController, bgm } from './audio/bgm'; import { BgmController, bgm } from './audio/bgm';
import { SoundController, sound } from './audio/sound'; import { SoundController, SoundEffect, sound } from './audio/sound';
import { EventEmitter } from './common/eventEmitter'; import { readyAllResource } from './loader/load';
import { loading, readyAllResource } from './loader/load';
import { import {
Resource,
ResourceStore, ResourceStore,
ResourceType, ZippedResource,
resource, resource,
zipResource zipResource
} from './loader/resource'; } from './loader/resource';
import { UiController } from './main/custom/ui'; import { Focus, GameUi, UiController } from './main/custom/ui';
import { GameEvent, gameListener, hook } from './main/game';
import { GameStorage } from './main/storage'; import { GameStorage } from './main/storage';
// import { resolvePlugin } from './plugin';
import './main/init/'; import './main/init/';
import './main/custom/toolbar'; import './main/custom/toolbar';
import { fixedUi, mainUi } from './main/init/ui'; import { fixedUi, mainUi } from './main/init/ui';
import { gameKey } from './main/init/hotkey'; import { gameKey } from './main/init/hotkey';
import { mainSetting, settingStorage } from './main/setting'; import {
import { isMobile } from '../plugin/use'; MotaSetting,
SettingDisplayer,
mainSetting,
settingStorage
} from './main/setting';
import { KeyCode } from '@/plugin/keyCodes'; import { KeyCode } from '@/plugin/keyCodes';
import { status } from '@/plugin/ui/statusBar'; import { status } from '@/plugin/ui/statusBar';
import './plugin'; import './plugin';
import './package'; import './package';
import { AudioPlayer } from './audio/audio';
// interface AncTePlugin { import { CustomToolbar } from './main/custom/toolbar';
// pop: ReturnType<typeof import('../plugin/pop').default>; import { Hotkey } from './main/custom/hotkey';
// use: ReturnType<typeof import('../plugin/use').default>; import { Keyboard } from './main/custom/keyboard';
// animate: ReturnType<typeof import('../plugin/animateController').default>;
// utils: ReturnType<typeof import('../plugin/utils').default>;
// status: ReturnType<typeof import('../plugin/ui/statusBar').default>;
// fly: ReturnType<typeof import('../plugin/ui/fly').default>;
// chase: ReturnType<typeof import('../plugin/chase/chase').default>;
// webglUtils: ReturnType<typeof import('../plugin/webgl/utils').default>;
// shadow: ReturnType<typeof import('../plugin/shadow/shadow').default>;
// gameShadow: ReturnType<
// typeof import('../plugin/shadow/gameShadow').default
// >;
// achievement: ReturnType<typeof import('../plugin/ui/achievement').default>;
// completion: ReturnType<typeof import('../plugin/completion').default>;
// path: ReturnType<typeof import('../plugin/fx/path').default>;
// gameCanvas: ReturnType<typeof import('../plugin/fx/gameCanvas').default>;
// noise: ReturnType<typeof import('../plugin/fx/noise').default>;
// smooth: ReturnType<typeof import('../plugin/fx/smoothView').default>;
// frag: ReturnType<typeof import('../plugin/fx/frag').default>;
// }
// export interface Mota { // export interface Mota {
// sound: SoundController; // sound: SoundController;
@ -81,19 +65,38 @@ function ready() {
readyAllResource(); readyAllResource();
// loading.once('coreInit', resolvePlugin); // loading.once('coreInit', resolvePlugin);
} }
ready();
// ----- 类注册
Mota.register('class', 'AudioPlayer', AudioPlayer);
Mota.register('class', 'BgmController', BgmController);
Mota.register('class', 'CustomToolbar', CustomToolbar);
Mota.register('class', 'Focus', Focus);
Mota.register('class', 'GameStorage', GameStorage);
Mota.register('class', 'GameUi', GameUi);
Mota.register('class', 'Hotkey', Hotkey);
Mota.register('class', 'Keyboard', Keyboard);
Mota.register('class', 'MotaSetting', MotaSetting);
Mota.register('class', 'Resource', Resource);
Mota.register('class', 'ResourceStore', ResourceStore);
Mota.register('class', 'SettingDisplayer', SettingDisplayer);
Mota.register('class', 'SoundController', SoundController);
Mota.register('class', 'SoundEffect', SoundEffect);
Mota.register('class', 'UiController', UiController);
Mota.register('class', 'ZippedResource', ZippedResource);
// ----- 函数注册
// ----- 变量注册
Mota.register('var', 'mainUi', mainUi); Mota.register('var', 'mainUi', mainUi);
Mota.register('var', 'fixedUi', fixedUi); Mota.register('var', 'fixedUi', fixedUi);
Mota.register('var', 'hook', hook);
Mota.register('var', 'gameListener', gameListener);
Mota.register('var', 'bgm', bgm); Mota.register('var', 'bgm', bgm);
Mota.register('var', 'sound', sound); Mota.register('var', 'sound', sound);
Mota.register('var', 'gameKey', gameKey); Mota.register('var', 'gameKey', gameKey);
Mota.register('var', 'loading', loading);
Mota.register('var', 'mainSetting', mainSetting); Mota.register('var', 'mainSetting', mainSetting);
Mota.register('var', 'KeyCode', KeyCode); Mota.register('var', 'KeyCode', KeyCode);
Mota.register('var', 'resource', resource); Mota.register('var', 'resource', resource);
Mota.register('var', 'zipResource', zipResource); Mota.register('var', 'zipResource', zipResource);
Mota.register('var', 'settingStorage', settingStorage); Mota.register('var', 'settingStorage', settingStorage);
Mota.register('var', 'status', status); Mota.register('var', 'status', status);
// ----- 模块注册
ready();

View File

@ -7,13 +7,6 @@ import {
resource as res resource as res
} from './resource'; } from './resource';
interface GameLoadEvent extends EmitableEvent {
coreLoaded: () => void;
autotileLoaded: () => void;
coreInit: () => void;
materialLoaded: () => void;
}
const info = resource; const info = resource;
/** /**
@ -35,6 +28,7 @@ export function readyAllResource() {
* *
*/ */
/* @__PURE__ */ async function readyDevResource() { /* @__PURE__ */ async function readyDevResource() {
const loading = Mota.require('var', 'loading');
const loadData = (await import('../../data/resource-dev.json')).default; const loadData = (await import('../../data/resource-dev.json')).default;
loadData.forEach(v => { loadData.forEach(v => {
@ -50,79 +44,3 @@ export function readyAllResource() {
animates.active(); animates.active();
}); });
} }
class GameLoading extends EventEmitter<GameLoadEvent> {
private autotileLoaded: number = 0;
private autotileNum?: number;
private autotileListened: boolean = false;
private materialsNum: number = main.materials.length;
private materialsLoaded: number = 0;
constructor() {
super();
this.on(
'coreInit',
() => {
this.autotileNum = Object.keys(
core.material.icons.autotile
).length;
},
{ immediate: true }
);
this.on('materialLoaded', () => {
core.loader._loadMaterials_afterLoad();
});
}
addMaterialLoaded() {
this.once('coreInit', () => {
this.materialsLoaded++;
if (this.materialsLoaded === this.materialsNum) {
this.emit('materialLoaded');
}
});
}
addAutotileLoaded() {
this.once('coreInit', () => {
this.autotileLoaded++;
if (this.autotileLoaded === this.autotileNum) {
this.emit('autotileLoaded');
}
});
}
/**
*
* @param autotiles
*/
onAutotileLoaded(
autotiles: Partial<Record<AllIdsOf<'autotile'>, HTMLImageElement>>
) {
if (this.autotileListened) return;
this.autotileListened = true;
this.on('autotileLoaded', () => {
const keys = Object.keys(
core.material.icons.autotile
) as AllIdsOf<'autotile'>[];
keys.forEach(v => {
core.material.images.autotile[v] = autotiles[v]!;
});
setTimeout(() => {
core.maps._makeAutotileEdges();
});
});
}
}
export const loading = new GameLoading();
declare global {
interface Main {
loading: GameLoading;
}
}
main.loading = loading;

View File

@ -4,7 +4,6 @@ import { ensureArray } from '@/plugin/utils';
import { has } from '@/plugin/utils'; import { has } from '@/plugin/utils';
import JSZip from 'jszip'; import JSZip from 'jszip';
import { EmitableEvent, EventEmitter } from '../common/eventEmitter'; import { EmitableEvent, EventEmitter } from '../common/eventEmitter';
import { loading } from './load';
// todo: 应当用register去注册资源类型然后进行分块处理 // todo: 应当用register去注册资源类型然后进行分块处理
@ -59,6 +58,7 @@ export class Resource<
} }
protected onLoad(v: ResourceData[T]) { protected onLoad(v: ResourceData[T]) {
const loading = Mota.require('var', 'loading');
// 资源类型处理 // 资源类型处理
if (this.type === 'fonts') { if (this.type === 'fonts') {
document.fonts.add(new FontFace(this.name, v as ArrayBuffer)); document.fonts.add(new FontFace(this.name, v as ArrayBuffer));

View File

@ -40,6 +40,8 @@ export interface HotkeyJSON {
assist: number; assist: number;
} }
console.log(2);
export class Hotkey extends EventEmitter<HotkeyEvent> { export class Hotkey extends EventEmitter<HotkeyEvent> {
static list: Hotkey[]; static list: Hotkey[];

View File

@ -15,7 +15,6 @@ import {
import { gameKey } from '../init/hotkey'; import { gameKey } from '../init/hotkey';
import { unwarpBinary } from './hotkey'; import { unwarpBinary } from './hotkey';
import { fixedUi } from '../init/ui'; import { fixedUi } from '../init/ui';
import { hook } from '../game';
interface CustomToolbarEvent extends EmitableEvent { interface CustomToolbarEvent extends EmitableEvent {
add: (item: ValueOf<ToolbarItemMap>) => void; add: (item: ValueOf<ToolbarItemMap>) => void;

View File

@ -1,5 +1,4 @@
import { debounce } from 'lodash-es'; import { debounce } from 'lodash-es';
import { gameListener, hook } from '../game';
import { fixedUi, mainUi } from './ui'; import { fixedUi, mainUi } from './ui';
import { ref } from 'vue'; import { ref } from 'vue';
import { sleep } from 'mutate-animate'; import { sleep } from 'mutate-animate';
@ -38,6 +37,7 @@ const closeFixed = () => {
// todo: 应当在这里实现查看临界与特殊属性的功能 // todo: 应当在这里实现查看临界与特殊属性的功能
export let hovered: Block | null; export let hovered: Block | null;
const { hook, gameListener } = Mota.requireAll('var');
gameListener.on('hoverBlock', block => { gameListener.on('hoverBlock', block => {
closeFixed(); closeFixed();
hovered = block; hovered = block;

View File

@ -1,7 +1,6 @@
import * as UI from '@ui/.'; import * as UI from '@ui/.';
import * as MiscUI from './misc'; import * as MiscUI from './misc';
import { GameUi, UiController } from '../custom/ui'; import { GameUi, UiController } from '../custom/ui';
import { hook } from '../game';
export const mainUi = new UiController(); export const mainUi = new UiController();
mainUi.register( mainUi.register(
@ -36,6 +35,7 @@ fixedUi.register(
); );
fixedUi.showAll(); fixedUi.showAll();
const hook = Mota.require('var', 'hook');
hook.once('mounted', () => { hook.once('mounted', () => {
const ui = document.getElementById('ui-main')!; const ui = document.getElementById('ui-main')!;
const fixed = document.getElementById('ui-fixed')!; const fixed = document.getElementById('ui-fixed')!;

View File

@ -1,7 +1,5 @@
import { FunctionalComponent, reactive } from 'vue'; import { FunctionalComponent, reactive } from 'vue';
import { EmitableEvent, EventEmitter } from '../common/eventEmitter'; import { EmitableEvent, EventEmitter } from '../common/eventEmitter';
import { loading } from '../loader/load';
import { hook } from './game';
import { GameStorage } from './storage'; import { GameStorage } from './storage';
import { has, triggerFullscreen } from '@/plugin/utils'; import { has, triggerFullscreen } from '@/plugin/utils';
import { createSettingComponents } from './init/settings'; import { createSettingComponents } from './init/settings';
@ -478,6 +476,7 @@ mainSetting
) )
); );
const loading = Mota.require('var', 'loading');
loading.once('coreInit', () => { loading.once('coreInit', () => {
mainSetting.reset({ mainSetting.reset({
'screen.fullscreen': !!document.fullscreenElement, 'screen.fullscreen': !!document.fullscreenElement,
@ -497,6 +496,7 @@ loading.once('coreInit', () => {
}); });
}); });
const { hook } = Mota.requireAll('var');
hook.on('reset', () => { hook.on('reset', () => {
mainSetting.reset({ mainSetting.reset({
'action.autoSkill': flags.autoSkill ?? true 'action.autoSkill': flags.autoSkill ?? true

View File

@ -27,7 +27,6 @@ import * as frag from '@/plugin/fx/frag';
import * as use from '@/plugin/use'; import * as use from '@/plugin/use';
import * as gameCanvas from '@/plugin/fx/gameCanvas'; import * as gameCanvas from '@/plugin/fx/gameCanvas';
import * as smooth from '@/plugin/fx/smoothView'; import * as smooth from '@/plugin/fx/smoothView';
import { loading } from './loader/load';
Mota.Plugin.register('shadow_r', shadow, shadow.init); Mota.Plugin.register('shadow_r', shadow, shadow.init);
Mota.Plugin.register('gameShadow_r', gameShadow, gameShadow.init); Mota.Plugin.register('gameShadow_r', gameShadow, gameShadow.init);
@ -40,10 +39,6 @@ Mota.Plugin.register('use_r', use);
Mota.Plugin.register('gameCanvas_r', gameCanvas); Mota.Plugin.register('gameCanvas_r', gameCanvas);
Mota.Plugin.register('smooth_r', smooth, smooth.init); Mota.Plugin.register('smooth_r', smooth, smooth.init);
loading.once('coreInit', () => {
Mota.Plugin.init();
});
// // todo: 将插件更改为注册形式,分为渲染进程和游戏进程两部分,同时分配优先级 // // todo: 将插件更改为注册形式,分为渲染进程和游戏进程两部分,同时分配优先级
// export function resolvePlugin() { // export function resolvePlugin() {

239
src/game/enemy/battle.ts Normal file
View File

@ -0,0 +1,239 @@
import { DamageEnemy, ensureFloorDamage, getSingleEnemy } from './damage';
import { findDir, has } from '../../plugin/game/utils';
export interface CurrentEnemy {
enemy: DamageEnemy;
onMapEnemy: DamageEnemy[];
}
export function getEnemy(
x: number,
y: number,
floorId: FloorIds = core.status.floorId
) {
const enemy = core.status.maps[floorId].enemy.list.find(v => {
return v.x === x && v.y === y;
});
if (!enemy) {
throw new Error(
`Get null when getting enemy on '${x},${y}' in '${floorId}'`
);
}
return enemy;
}
export function canBattle(
x: number,
y: number,
floorId: FloorIds = core.status.floorId
) {
const enemy = getEnemy(x, y, floorId);
const { damage } = enemy.calDamage();
return damage < core.status.hero.hp;
}
export function battle(
x: number,
y: number,
force: boolean = false,
callback?: () => void
) {
core.saveAndStopAutomaticRoute();
const enemy = getEnemy(x, y);
// 非强制战斗
if (!core.enemys.canBattle(x, y) && !force && !core.status.event.id) {
core.stopSound();
core.playSound('操作失败');
core.drawTip('你打不过此怪物!', enemy.id);
return core.clearContinueAutomaticRoute(callback);
}
// 自动存档
if (!core.status.event.id) core.autosave(true);
// 战前事件
// 战后事件
afterBattle(enemy, x, y);
callback?.();
}
export function afterBattle(enemy: DamageEnemy, x?: number, y?: number) {
const floorId = core.status.floorId;
const special = enemy.info.special;
// 播放战斗动画
let animate: AnimationIds = 'hand';
// 检查当前装备是否存在攻击动画
const equipId = core.getEquip(0);
if (equipId && (core.material.items[equipId].equip || {}).animate)
animate = core.material.items[equipId].equip.animate;
// 检查该动画是否存在SE如果不存在则使用默认音效
if (!core.material.animates[animate]?.se) core.playSound('attack.mp3');
// 战斗伤害
const info = enemy.calDamage(core.status.hero);
const damage = info.damage;
// 判定是否致死
if (damage >= core.status.hero.hp) {
core.status.hero.hp = 0;
core.updateStatusBar(false, true);
core.events.lose('战斗失败');
return;
}
// 扣减体力值并记录统计数据
core.status.hero.hp -= damage;
core.status.hero.statistics.battleDamage += damage;
core.status.hero.statistics.battle++;
// 智慧之源
if (special.includes(14) && flags.hard === 2) {
core.addFlag(
'inte_' + floorId,
Math.ceil((core.status.hero.mdef / 10) * 0.3) * 10
);
core.status.hero.mdef -=
Math.ceil((core.status.hero.mdef / 10) * 0.3) * 10;
}
// 极昼永夜
if (special.includes(22)) {
flags[`night_${floorId}`] ??= 0;
flags[`night_${floorId}`] -= enemy.enemy.night!;
}
if (special.includes(23)) {
flags[`night_${floorId}`] ??= 0;
flags[`night_${floorId}`] += enemy.enemy.day;
}
// if (core.plugin.skillTree.getSkillLevel(11) > 0) {
// core.plugin.study.declineStudiedSkill();
// }
// 如果是融化怪,需要特殊标记一下
if (special.includes(25) && has(x) && has(y)) {
flags[`melt_${floorId}`] ??= {};
flags[`melt_${floorId}`][`${x},${y}`] = enemy.enemy.melt;
}
// 获得金币
const money = enemy.enemy.money;
core.status.hero.money += money;
core.status.hero.statistics.money += money;
// 获得经验
const exp = enemy.enemy.exp;
core.status.hero.exp += exp;
core.status.hero.statistics.exp += exp;
const hint =
'打败 ' + enemy.enemy.name + ',金币+' + money + ',经验+' + exp;
core.drawTip(hint, enemy.id);
if (core.getFlag('bladeOn') && core.getFlag('blade')) {
core.setFlag('blade', false);
}
if (core.getFlag('shieldOn') && core.getFlag('shield')) {
core.setFlag('shield', false);
}
// 事件的处理
const todo: MotaEvent = [];
// 战后事件
if (has(core.status.floorId)) {
const loc = `${x},${y}` as LocString;
todo.push(...(core.floors[core.status.floorId].afterBattle[loc] ?? []));
}
todo.push(...(enemy.enemy.afterBattle ?? []));
// 如果事件不为空,将其插入
if (todo.length > 0) core.insertAction(todo, x, y);
if (has(x) && has(y)) {
core.drawAnimate(animate, x, y);
core.removeBlock(x, y);
} else core.drawHeroAnimate(animate);
// 如果已有事件正在处理中
if (core.status.event.id == null) core.continueAutomaticRoute();
else core.clearContinueAutomaticRoute();
}
export function getCurrentEnemys(floorId = core.status.floorId) {
floorId = floorId || core.status.floorId;
const enemys: CurrentEnemy[] = [];
const used: Record<string, DamageEnemy[]> = {};
ensureFloorDamage(floorId);
const floor = core.status.maps[floorId];
floor.enemy.list.forEach(v => {
if (!(v.id in used)) {
const e = new DamageEnemy(v.enemy);
e.calAttribute();
e.getRealInfo();
e.calDamage();
const curr: CurrentEnemy = {
enemy: e,
onMapEnemy: [v]
};
enemys.push(curr);
used[v.id] = curr.onMapEnemy;
} else {
used[v.id].push(v);
}
});
return enemys.sort((a, b) => {
const ad = a.enemy.calDamage().damage;
const bd = b.enemy.calDamage().damage;
return ad - bd;
});
}
export function init() {
core.events._sys_battle = function (data: Block, callback?: () => void) {
// 检查战前事件
const floor = core.floors[core.status.floorId];
const beforeBattle: MotaEvent = [];
const loc = `${data.x},${data.y}` as LocString;
const enemy = getEnemy(data.x, data.y);
beforeBattle.push(...(floor.beforeBattle[loc] ?? []));
beforeBattle.push(...(enemy.enemy.beforeBattle ?? []));
if (beforeBattle.length > 0) {
beforeBattle.push({ type: 'battle', x: data.x, y: data.y });
core.clearContinueAutomaticRoute();
// 自动存档
var inAction = core.status.event.id == 'action';
if (inAction) {
core.insertAction(beforeBattle, data.x, data.y);
core.doAction();
} else {
core.autosave(true);
core.insertAction(beforeBattle, data.x, data.y, callback);
}
} else {
this.battle(data.x, data.y, false, callback);
}
};
core.events._action_battle = function (data, x, y, prefix) {
if (data.id) {
const enemy = getSingleEnemy(data.id as EnemyIds);
// todo: 与不在地图上的怪物战斗
} else {
if (data.floorId != core.status.floorId) {
core.doAction();
return;
}
const [ex, ey] = this.__action_getLoc(
data.loc,
x,
y,
prefix
) as LocArr;
this.battle(ex, ey, true, core.doAction);
}
};
}

View File

@ -1,6 +1,12 @@
import { getHeroStatusOf, getHeroStatusOn } from '../hero'; import { getHeroStatusOf, getHeroStatusOn } from '@/plugin/game/hero';
import { Range, RangeCollection } from '../range'; import { Range, RangeCollection } from '@/plugin/game/range';
import { checkV2, ensureArray, formatDamage, has, manhattan } from '../utils'; import {
checkV2,
ensureArray,
formatDamage,
has,
manhattan
} from '@/plugin/game/utils';
interface HaloType { interface HaloType {
square: { square: {

View File

@ -1,4 +1,4 @@
import { getHeroStatusOn } from '../hero'; import { getHeroStatusOn } from '@/plugin/game/hero';
export interface SpecialDeclaration { export interface SpecialDeclaration {
code: number; code: number;

View File

@ -1,5 +1,81 @@
import { EmitableEvent, EventEmitter } from '../common/eventEmitter'; import { EmitableEvent, EventEmitter } from '../core/common/eventEmitter';
import { loading } from '../loader/load';
// ----- 加载事件
interface GameLoadEvent extends EmitableEvent {
coreLoaded: () => void;
autotileLoaded: () => void;
coreInit: () => void;
materialLoaded: () => void;
}
class GameLoading extends EventEmitter<GameLoadEvent> {
private autotileLoaded: number = 0;
private autotileNum?: number;
private autotileListened: boolean = false;
private materialsNum: number = main.materials.length;
private materialsLoaded: number = 0;
constructor() {
super();
this.on(
'coreInit',
() => {
this.autotileNum = Object.keys(
core.material.icons.autotile
).length;
},
{ immediate: true }
);
this.on('materialLoaded', () => {
core.loader._loadMaterials_afterLoad();
});
}
addMaterialLoaded() {
this.once('coreInit', () => {
this.materialsLoaded++;
if (this.materialsLoaded === this.materialsNum) {
this.emit('materialLoaded');
}
});
}
addAutotileLoaded() {
this.once('coreInit', () => {
this.autotileLoaded++;
if (this.autotileLoaded === this.autotileNum) {
this.emit('autotileLoaded');
}
});
}
/**
*
* @param autotiles
*/
onAutotileLoaded(
autotiles: Partial<Record<AllIdsOf<'autotile'>, HTMLImageElement>>
) {
if (this.autotileListened) return;
this.autotileListened = true;
this.on('autotileLoaded', () => {
const keys = Object.keys(
core.material.icons.autotile
) as AllIdsOf<'autotile'>[];
keys.forEach(v => {
core.material.images.autotile[v] = autotiles[v]!;
});
setTimeout(() => {
core.maps._makeAutotileEdges();
});
});
}
}
export const loading = new GameLoading();
export interface GameEvent extends EmitableEvent { export interface GameEvent extends EmitableEvent {
/** Emitted in events.prototype.resetGame. */ /** Emitted in events.prototype.resetGame. */
@ -118,3 +194,9 @@ class GameListener extends EventEmitter<ListenerEvent> {
} }
export const gameListener = new GameListener(); export const gameListener = new GameListener();
declare global {
interface Main {
loading: GameLoading;
}
}

View File

@ -1,2 +1,32 @@
import './system'; import './system';
import '../plugin/game/index'; import '../plugin/game/index';
import { DamageEnemy, EnemyCollection } from './enemy/damage';
import {
EmitableEvent,
EventEmitter,
IndexedEventEmitter
} from '@/core/common/eventEmitter';
import { Range } from '@/plugin/game/range';
import { specials } from './enemy/special';
import { gameListener, hook, loading } from './game';
// ----- 类注册
Mota.register('class', 'DamageEnemy', DamageEnemy);
Mota.register('class', 'EnemyCollection', EnemyCollection);
Mota.register('class', 'EventEmitter', EventEmitter);
Mota.register('class', 'IndexedEventEmitter', IndexedEventEmitter);
Mota.register('class', 'Range', Range);
// ----- 函数注册
// ----- 变量注册
Mota.register('var', 'enemySpecials', specials);
Mota.register('var', 'hook', hook);
Mota.register('var', 'gameListener', gameListener);
Mota.register('var', 'loading', loading);
// ----- 模块注册
main.loading = loading;
loading.once('coreInit', () => {
Mota.Plugin.init();
});

View File

@ -6,7 +6,7 @@ import type {
EventEmitter, EventEmitter,
IndexedEventEmitter IndexedEventEmitter
} from '@/core/common/eventEmitter'; } from '@/core/common/eventEmitter';
import type { loading } from '@/core/loader/load'; import type { loading } from './game';
import type { import type {
Resource, Resource,
ResourceStore, ResourceStore,
@ -17,15 +17,15 @@ import type { Hotkey } from '@/core/main/custom/hotkey';
import type { Keyboard } from '@/core/main/custom/keyboard'; import type { Keyboard } from '@/core/main/custom/keyboard';
import type { CustomToolbar } from '@/core/main/custom/toolbar'; import type { CustomToolbar } from '@/core/main/custom/toolbar';
import type { Focus, GameUi, UiController } from '@/core/main/custom/ui'; import type { Focus, GameUi, UiController } from '@/core/main/custom/ui';
import type { gameListener, hook } from '@/core/main/game'; import type { gameListener, hook } from './game';
import type { import type {
MotaSetting, MotaSetting,
SettingDisplayer, SettingDisplayer,
SettingStorage SettingStorage
} from '@/core/main/setting'; } from '@/core/main/setting';
import type { GameStorage } from '@/core/main/storage'; import type { GameStorage } from '@/core/main/storage';
import type { DamageEnemy, EnemyCollection } from '@/plugin/game/enemy/damage'; import type { DamageEnemy, EnemyCollection } from './enemy/damage';
import type { specials } from '@/plugin/game/enemy/special'; import type { specials } from './enemy/special';
import type { Range } from '@/plugin/game/range'; import type { Range } from '@/plugin/game/range';
import type { KeyCode } from '@/plugin/keyCodes'; import type { KeyCode } from '@/plugin/keyCodes';
import type { Ref } from 'vue'; import type { Ref } from 'vue';
@ -89,10 +89,13 @@ interface VariableInterface {
enemySpecials: typeof specials; enemySpecials: typeof specials;
} }
interface ModuleInterface {}
interface SystemInterfaceMap { interface SystemInterfaceMap {
class: ClassInterface; class: ClassInterface;
fn: FunctionInterface; fn: FunctionInterface;
var: VariableInterface; var: VariableInterface;
module: ModuleInterface;
} }
type InterfaceType = keyof SystemInterfaceMap; type InterfaceType = keyof SystemInterfaceMap;
@ -374,6 +377,7 @@ class Mota {
private static classes: Record<string, any> = {}; private static classes: Record<string, any> = {};
private static functions: Record<string, any> = {}; private static functions: Record<string, any> = {};
private static variables: Record<string, any> = {}; private static variables: Record<string, any> = {};
private static modules: Record<string, any> = {};
static rewrite = rewrite; static rewrite = rewrite;
static r = r; static r = r;
@ -414,7 +418,9 @@ class Mota {
? this.classes ? this.classes
: type === 'fn' : type === 'fn'
? this.functions ? this.functions
: this.variables; : type === 'var'
? this.variables
: this.modules;
} }
} }

View File

@ -1,9 +1,9 @@
import { createApp } from 'vue'; import { createApp } from 'vue';
import './game/index';
import './core/index';
import App from './App.vue'; import App from './App.vue';
import './styles.less'; import './styles.less';
import 'ant-design-vue/dist/antd.dark.css'; import 'ant-design-vue/dist/antd.dark.css';
import './game/index';
import './core/index';
createApp(App).mount('#root'); createApp(App).mount('#root');

View File

@ -5,7 +5,6 @@ import {
} from './ui/achievement'; } from './ui/achievement';
import { changeLocalStorage } from './utils'; import { changeLocalStorage } from './utils';
import list from '../data/achievement.json'; import list from '../data/achievement.json';
import { loading } from '@/core/loader/load';
export const floors: Record<number, FloorIds[]> = { export const floors: Record<number, FloorIds[]> = {
1: ['MT0', 'tower7'] 1: ['MT0', 'tower7']
@ -22,6 +21,8 @@ export const achiDict: Record<number, number> = {
1: 0 1: 0
}; };
const loading = Mota.require('var', 'loading');
loading.once('coreInit', () => { loading.once('coreInit', () => {
Object.values(floors).forEach((v, i) => { Object.values(floors).forEach((v, i) => {
const from = core.floorIds.indexOf(v[0]); const from = core.floorIds.indexOf(v[0]);

View File

@ -52,15 +52,15 @@ export function init() {
const hso = hyper('sin', 'out'); const hso = hyper('sin', 'out');
let time2 = Date.now(); let time2 = Date.now();
Mota.rewrite(core.control, '_moveAction_moving', 'front', () => { Mota.rewrite(core.control, '_moveAction_moving', 'front', () => {
const t = setting.getValue('screen.smoothView', false) ? 200 : 1; const t = setting.getValue('screen.smoothView', false) ? 200 : 0;
if (Date.now() - time2 > 20) tran.mode(hso).time(t).absolute(); if (Date.now() - time2 > 20) tran.mode(hso).time(t).absolute();
}); });
Mota.rewrite(core.control, 'moveDirectly', 'front', () => { Mota.rewrite(core.control, 'moveDirectly', 'front', () => {
const t = setting.getValue('screen.smoothView', false) ? 600 : 1; const t = setting.getValue('screen.smoothView', false) ? 600 : 0;
time2 = Date.now(); time2 = Date.now();
tran.mode(hso).time(t).absolute(); tran.mode(hso).time(t).absolute();
}); });
Mota.rewrite(core.events, '_changeFloor_beforeChange', 'front', () => { Mota.rewrite(core.events, '_changeFloor_beforeChange', 'front', () => {
tran.time(1).absolute(); tran.time(0).absolute();
}); });
} }

View File

@ -1,245 +0,0 @@
import { DamageEnemy, ensureFloorDamage, getSingleEnemy } from './damage';
import { findDir, has } from '../utils';
export interface CurrentEnemy {
enemy: DamageEnemy;
onMapEnemy: DamageEnemy[];
}
export function getEnemy(
x: number,
y: number,
floorId: FloorIds = core.status.floorId
) {
const enemy = core.status.maps[floorId].enemy.list.find(v => {
return v.x === x && v.y === y;
});
if (!enemy) {
throw new Error(
`Get null when getting enemy on '${x},${y}' in '${floorId}'`
);
}
return enemy;
}
export function init() {
core.enemys.canBattle = function (
x: number,
y: number,
floorId: FloorIds = core.status.floorId
) {
const enemy = getEnemy(x, y, floorId);
const { damage } = enemy.calDamage();
return damage < core.status.hero.hp;
};
core.events.battle = function (
x: number,
y: number,
force: boolean = false,
callback?: () => void
) {
core.saveAndStopAutomaticRoute();
const enemy = getEnemy(x, y);
// 非强制战斗
if (!core.enemys.canBattle(x, y) && !force && !core.status.event.id) {
core.stopSound();
core.playSound('操作失败');
core.drawTip('你打不过此怪物!', enemy.id);
return core.clearContinueAutomaticRoute(callback);
}
// 自动存档
if (!core.status.event.id) core.autosave(true);
// 战前事件
// 战后事件
this.afterBattle(enemy, x, y);
callback?.();
};
core.events.afterBattle = function (
enemy: DamageEnemy,
x?: number,
y?: number
) {
const floorId = core.status.floorId;
const special = enemy.info.special;
// 播放战斗动画
let animate: AnimationIds = 'hand';
// 检查当前装备是否存在攻击动画
const equipId = core.getEquip(0);
if (equipId && (core.material.items[equipId].equip || {}).animate)
animate = core.material.items[equipId].equip.animate;
// 检查该动画是否存在SE如果不存在则使用默认音效
if (!core.material.animates[animate]?.se) core.playSound('attack.mp3');
// 战斗伤害
const info = enemy.calDamage(core.status.hero);
const damage = info.damage;
// 判定是否致死
if (damage >= core.status.hero.hp) {
core.status.hero.hp = 0;
core.updateStatusBar(false, true);
core.events.lose('战斗失败');
return;
}
// 扣减体力值并记录统计数据
core.status.hero.hp -= damage;
core.status.hero.statistics.battleDamage += damage;
core.status.hero.statistics.battle++;
// 智慧之源
if (special.includes(14) && flags.hard === 2) {
core.addFlag(
'inte_' + floorId,
Math.ceil((core.status.hero.mdef / 10) * 0.3) * 10
);
core.status.hero.mdef -=
Math.ceil((core.status.hero.mdef / 10) * 0.3) * 10;
}
// 极昼永夜
if (special.includes(22)) {
flags[`night_${floorId}`] ??= 0;
flags[`night_${floorId}`] -= enemy.enemy.night!;
}
if (special.includes(23)) {
flags[`night_${floorId}`] ??= 0;
flags[`night_${floorId}`] += enemy.enemy.day;
}
// if (core.plugin.skillTree.getSkillLevel(11) > 0) {
// core.plugin.study.declineStudiedSkill();
// }
// 如果是融化怪,需要特殊标记一下
if (special.includes(25) && has(x) && has(y)) {
flags[`melt_${floorId}`] ??= {};
flags[`melt_${floorId}`][`${x},${y}`] = enemy.enemy.melt;
}
// 获得金币
const money = enemy.enemy.money;
core.status.hero.money += money;
core.status.hero.statistics.money += money;
// 获得经验
const exp = enemy.enemy.exp;
core.status.hero.exp += exp;
core.status.hero.statistics.exp += exp;
const hint =
'打败 ' + enemy.enemy.name + ',金币+' + money + ',经验+' + exp;
core.drawTip(hint, enemy.id);
if (core.getFlag('bladeOn') && core.getFlag('blade')) {
core.setFlag('blade', false);
}
if (core.getFlag('shieldOn') && core.getFlag('shield')) {
core.setFlag('shield', false);
}
// 事件的处理
const todo: MotaEvent = [];
// 战后事件
if (has(core.status.floorId)) {
const loc = `${x},${y}` as LocString;
todo.push(
...(core.floors[core.status.floorId].afterBattle[loc] ?? [])
);
}
todo.push(...(enemy.enemy.afterBattle ?? []));
// 如果事件不为空,将其插入
if (todo.length > 0) core.insertAction(todo, x, y);
if (has(x) && has(y)) {
core.drawAnimate(animate, x, y);
core.removeBlock(x, y);
} else core.drawHeroAnimate(animate);
// 如果已有事件正在处理中
if (core.status.event.id == null) core.continueAutomaticRoute();
else core.clearContinueAutomaticRoute();
};
core.events._sys_battle = function (data: Block, callback?: () => void) {
// 检查战前事件
const floor = core.floors[core.status.floorId];
const beforeBattle: MotaEvent = [];
const loc = `${data.x},${data.y}` as LocString;
const enemy = getEnemy(data.x, data.y);
beforeBattle.push(...(floor.beforeBattle[loc] ?? []));
beforeBattle.push(...(enemy.enemy.beforeBattle ?? []));
if (beforeBattle.length > 0) {
beforeBattle.push({ type: 'battle', x: data.x, y: data.y });
core.clearContinueAutomaticRoute();
// 自动存档
var inAction = core.status.event.id == 'action';
if (inAction) {
core.insertAction(beforeBattle, data.x, data.y);
core.doAction();
} else {
core.autosave(true);
core.insertAction(beforeBattle, data.x, data.y, callback);
}
} else {
this.battle(data.x, data.y, false, callback);
}
};
core.events._action_battle = function (data, x, y, prefix) {
if (data.id) {
const enemy = getSingleEnemy(data.id as EnemyIds);
// todo: 与不在地图上的怪物战斗
} else {
if (data.floorId != core.status.floorId) {
core.doAction();
return;
}
const [ex, ey] = this.__action_getLoc(
data.loc,
x,
y,
prefix
) as LocArr;
this.battle(ex, ey, true, core.doAction);
}
};
core.enemys.getCurrentEnemys = function (floorId = core.status.floorId) {
floorId = floorId || core.status.floorId;
const enemys: CurrentEnemy[] = [];
const used: Record<string, DamageEnemy[]> = {};
ensureFloorDamage(floorId);
const floor = core.status.maps[floorId];
floor.enemy.list.forEach(v => {
if (!(v.id in used)) {
const e = new DamageEnemy(v.enemy);
e.calAttribute();
e.getRealInfo();
e.calDamage();
const curr: CurrentEnemy = {
enemy: e,
onMapEnemy: [v]
};
enemys.push(curr);
used[v.id] = curr.onMapEnemy;
} else {
used[v.id].push(v);
}
});
return enemys.sort((a, b) => {
const ad = a.enemy.calDamage().damage;
const bd = b.enemy.calDamage().damage;
return ad - bd;
});
};
}

View File

@ -1,4 +1,4 @@
import { ensureFloorDamage } from '../enemy/damage'; import { ensureFloorDamage } from '@/game/enemy/damage';
export function init() { export function init() {
core.control.updateDamage = function (floorId = core.status.floorId, ctx) { core.control.updateDamage = function (floorId = core.status.floorId, ctx) {

View File

@ -1,4 +1,4 @@
import { getEnemy } from '../enemy/battle'; import { getEnemy } from '@/game/enemy/battle';
import { formatDamage } from '../utils'; import { formatDamage } from '../utils';
export function init() { export function init() {

View File

@ -2,14 +2,12 @@
import * as fiveLayer from './fiveLayer'; import * as fiveLayer from './fiveLayer';
import * as heroFourFrames from './fx/heroFourFrames'; import * as heroFourFrames from './fx/heroFourFrames';
import * as itemDetail from './fx/itemDetail'; import * as itemDetail from './fx/itemDetail';
import * as checkBlock from './enemy/checkblock';
import * as replay from './replay'; import * as replay from './replay';
import * as ui from './ui'; import * as ui from './ui';
import * as rewrite from './fx/rewrite'; import * as rewrite from './fx/rewrite';
import * as halo from './fx/halo'; import * as halo from './fx/halo';
import * as hero from './hero'; import * as hero from './hero';
import * as loopMap from './loopMap'; import * as loopMap from './loopMap';
import * as remainEnemy from './enemy/remainEnemy';
import * as removeMap from './removeMap'; import * as removeMap from './removeMap';
import * as shop from './shop'; import * as shop from './shop';
import * as skill from './skill'; import * as skill from './skill';
@ -18,9 +16,8 @@ import * as study from './study';
import * as towerBoss from './towerBoss'; import * as towerBoss from './towerBoss';
import * as utils from './utils'; import * as utils from './utils';
import * as chase from './chase'; import * as chase from './chase';
import * as damage from './enemy/damage'; import * as remainEnemy from './enemy/remainEnemy';
import * as battle from './enemy/battle'; import * as checkBlock from './enemy/checkblock';
import * as special from './enemy/special';
Mota.Plugin.register('utils_g', utils); Mota.Plugin.register('utils_g', utils);
Mota.Plugin.register('loopMap_g', loopMap, loopMap.init); Mota.Plugin.register('loopMap_g', loopMap, loopMap.init);
@ -28,7 +25,6 @@ Mota.Plugin.register('shop_g', shop);
Mota.Plugin.register('replay_g', replay, replay.init); Mota.Plugin.register('replay_g', replay, replay.init);
Mota.Plugin.register('skillTree_g', skillTree); Mota.Plugin.register('skillTree_g', skillTree);
Mota.Plugin.register('removeMap_g', removeMap); Mota.Plugin.register('removeMap_g', removeMap);
Mota.Plugin.register('remainEnemy_g', remainEnemy);
Mota.Plugin.register('chase_g', chase); Mota.Plugin.register('chase_g', chase);
Mota.Plugin.register('skill_g', skill); Mota.Plugin.register('skill_g', skill);
Mota.Plugin.register('towerBoss_g', towerBoss); Mota.Plugin.register('towerBoss_g', towerBoss);
@ -36,13 +32,11 @@ Mota.Plugin.register('fiveLayer_g', fiveLayer, fiveLayer.init);
Mota.Plugin.register('heroFourFrames_g', heroFourFrames, heroFourFrames.init); Mota.Plugin.register('heroFourFrames_g', heroFourFrames, heroFourFrames.init);
Mota.Plugin.register('rewrite_g', rewrite, rewrite.init); Mota.Plugin.register('rewrite_g', rewrite, rewrite.init);
Mota.Plugin.register('itemDetail_g', itemDetail, itemDetail.init); Mota.Plugin.register('itemDetail_g', itemDetail, itemDetail.init);
Mota.Plugin.register('checkBlock_g', checkBlock, checkBlock.init);
Mota.Plugin.register('halo_g', halo); Mota.Plugin.register('halo_g', halo);
Mota.Plugin.register('study_g', study); Mota.Plugin.register('study_g', study);
Mota.Plugin.register('remainEnemy_g', remainEnemy);
Mota.Plugin.register('checkBlock_g', checkBlock, checkBlock.init);
// todo: 这几个不应该放到插件 // todo: 这几个不应该放到插件
Mota.Plugin.register('damage_g', damage);
Mota.Plugin.register('battle_g', battle, battle.init);
Mota.Plugin.register('special_g', special);
Mota.Plugin.register('hero_g', hero); Mota.Plugin.register('hero_g', hero);
Mota.Plugin.register('ui_g', ui, ui.init); Mota.Plugin.register('ui_g', ui, ui.init);

View File

@ -1,4 +1,3 @@
///<reference path="../../../src/types/core.d.ts" />
import { slide } from './utils'; import { slide } from './utils';
const list = ['tower6']; const list = ['tower6'];

View File

@ -1,5 +1,3 @@
///<reference path="../../../src/types/core.d.ts" />
export function removeMaps( export function removeMaps(
fromId: FloorIds, fromId: FloorIds,
toId: FloorIds, toId: FloorIds,

View File

@ -1,5 +1,3 @@
///<reference path="../../../src/types/core.d.ts" />
import { upgradeSkill } from './skillTree'; import { upgradeSkill } from './skillTree';
const replayableSettings = ['autoSkill']; const replayableSettings = ['autoSkill'];

View File

@ -1,5 +1,3 @@
///<reference path="../../../src/types/core.d.ts" />
let levels: number[] = []; let levels: number[] = [];
/** /**

View File

@ -1,5 +1,5 @@
// @ts-nocheck // @ts-nocheck
import { clip } from './replay.js'; import { clip } from './replay';
// 1000多行改不动了原来什么样就什么样吧 // 1000多行改不动了原来什么样就什么样吧

View File

@ -1,8 +1,7 @@
import { fixedUi } from '@/core/main/init/ui'; import { fixedUi } from '@/core/main/init/ui';
import type { DamageEnemy } from './game/enemy/damage'; import type { DamageEnemy } from '../game/enemy/damage';
import { tip } from './utils'; import { tip } from './utils';
import { ref, Ref } from 'vue'; import { ref, Ref } from 'vue';
import { hook } from '@/core/main/game';
export interface MarkInfo<T extends EnemyIds> { export interface MarkInfo<T extends EnemyIds> {
id: T; id: T;
@ -35,7 +34,7 @@ const marked: MarkInfo<EnemyIds>[] = [];
*/ */
export function markEnemy(id: EnemyIds) { export function markEnemy(id: EnemyIds) {
if (hasMarkedEnemy(id)) return; if (hasMarkedEnemy(id)) return;
const { DamageEnemy } = Mota.Plugin.require('damage_g'); const DamageEnemy = Mota.require('class', 'DamageEnemy');
const enemy = new DamageEnemy(core.material.enemys[id]); const enemy = new DamageEnemy(core.material.enemys[id]);
enemy.calAttribute(); enemy.calAttribute();
enemy.getRealInfo(); enemy.getRealInfo();
@ -159,6 +158,7 @@ export function hasMarkedEnemy(id: EnemyIds) {
return marked.some(v => v.id === id); return marked.some(v => v.id === id);
} }
const hook = Mota.require('var', 'hook');
hook.on('statusBarUpdate', () => { hook.on('statusBarUpdate', () => {
checkMarkedEnemy(); checkMarkedEnemy();
}); });

View File

@ -1,4 +1,4 @@
import type { CurrentEnemy } from '../game/enemy/battle'; import type { CurrentEnemy } from '../../game/enemy/battle';
import { has } from '../utils'; import { has } from '../utils';
export interface ToShowEnemy extends CurrentEnemy { export interface ToShowEnemy extends CurrentEnemy {

View File

@ -1,6 +1,6 @@
import { getDamageColor } from '../utils'; import { getDamageColor } from '../utils';
import { ToShowEnemy } from './book'; import { ToShowEnemy } from './book';
import type { DamageEnemy } from '../game/enemy/damage'; import type { DamageEnemy } from '../../game/enemy/damage';
import { isMobile } from '../use'; import { isMobile } from '../use';
export function getLocFromMouseLoc(x: number, y: number): LocArr { export function getLocFromMouseLoc(x: number, y: number): LocArr {

View File

@ -272,8 +272,6 @@ interface Enemys {
floorId?: FloorIds, floorId?: FloorIds,
dir?: Dir | 'none' | (Dir | 'none')[] dir?: Dir | 'none' | (Dir | 'none')[]
): boolean; ): boolean;
getCurrentEnemys(floorId: FloorIds): any[];
} }
declare const enemys: new () => Enemys; declare const enemys: new () => Enemys;

View File

@ -758,9 +758,6 @@ interface Events extends EventData {
*/ */
tryUseItem(itemId: ItemIdOf<'tools' | 'constants'>): void; tryUseItem(itemId: ItemIdOf<'tools' | 'constants'>): void;
beforeBattle(): boolean;
afterBattle(enemy: DamageEnemy, x?: number, y?: number): void;
_sys_battle(data: Block, callback?: () => void): void; _sys_battle(data: Block, callback?: () => void): void;
_action_battle(data: any, x?: number, y?: number, prefix?: any): void; _action_battle(data: any, x?: number, y?: number, prefix?: any): void;

View File

@ -32,7 +32,7 @@
import { onMounted, onUpdated, ref, watch } from 'vue'; import { onMounted, onUpdated, ref, watch } from 'vue';
import Box from '../components/box.vue'; import Box from '../components/box.vue';
import { GameUi } from '@/core/main/custom/ui'; import { GameUi } from '@/core/main/custom/ui';
import type { DamageEnemy } from '@/plugin/game/enemy/damage'; import type { DamageEnemy } from '@/game/enemy/damage';
import { nextFrame } from '@/plugin/utils'; import { nextFrame } from '@/plugin/utils';
const props = defineProps<{ const props = defineProps<{

View File

@ -68,7 +68,6 @@ import { Matrix4 } from '../plugin/webgl/matrix';
import { doByInterval, keycode } from '../plugin/utils'; import { doByInterval, keycode } from '../plugin/utils';
import { KeyCode } from '../plugin/keyCodes'; import { KeyCode } from '../plugin/keyCodes';
import { triggerFullscreen } from '../plugin/utils'; import { triggerFullscreen } from '../plugin/utils';
import { loading } from '../core/loader/load';
import { isMobile } from '../plugin/use'; import { isMobile } from '../plugin/use';
import { GameUi } from '@/core/main/custom/ui'; import { GameUi } from '@/core/main/custom/ui';
import { gameKey } from '@/core/main/init/hotkey'; import { gameKey } from '@/core/main/init/hotkey';
@ -308,6 +307,8 @@ onMounted(async () => {
start = document.getElementById('start') as HTMLDivElement; start = document.getElementById('start') as HTMLDivElement;
background = document.getElementById('background') as HTMLImageElement; background = document.getElementById('background') as HTMLImageElement;
const loading = Mota.require('var', 'loading');
loading.once('coreInit', async () => { loading.once('coreInit', async () => {
window.addEventListener('resize', resize); window.addEventListener('resize', resize);
resize(); resize();