diff --git a/public/libs/control.js b/public/libs/control.js index ed37371..feac06f 100644 --- a/public/libs/control.js +++ b/public/libs/control.js @@ -900,6 +900,7 @@ control.prototype._moveHero_moving = function () { // ------ 我已经看不懂这个函数了,反正好用就行23333333 core.status.heroStop = false; core.status.automaticRoute.moveDirectly = false; + var move = function () { if (!core.status.heroStop) { if (core.hasFlag('debug') && core.status.ctrlDown) { diff --git a/src/core/index.ts b/src/core/index.ts index ed8b265..8a3f5ad 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -69,6 +69,7 @@ import { Camera } from './render/camera'; import { Image, Text } from './render/preset/misc'; import { RenderItem } from './render/item'; import { texture } from './render/cache'; +import { RenderAdapter } from './render/adapter'; // ----- 类注册 Mota.register('class', 'AudioPlayer', AudioPlayer); @@ -154,7 +155,8 @@ Mota.register('module', 'Render', { Camera, Text, Image, - RenderItem + RenderItem, + RenderAdapter }); main.renderLoaded = true; diff --git a/src/core/main/custom/hotkey.ts b/src/core/main/custom/hotkey.ts index 014351d..2b23040 100644 --- a/src/core/main/custom/hotkey.ts +++ b/src/core/main/custom/hotkey.ts @@ -1,5 +1,5 @@ import { KeyCode } from '@/plugin/keyCodes'; -import { deleteWith, generateBinary, spliceBy } from '@/plugin/utils'; +import { deleteWith, generateBinary, keycode, spliceBy } from '@/plugin/utils'; import { EventEmitter } from '../../common/eventEmitter'; // todo: 按下时触发,长按(单次/连续)触发,按下连续触发,按下节流触发,按下加速节流触发 @@ -9,7 +9,13 @@ interface HotkeyEvent { emit: (key: KeyCode, assist: number, type: KeyEmitType) => void; } -type KeyEmitType = 'down' | 'up'; +type KeyEmitType = + | 'down' + | 'up' + | 'down-repeat' + | 'down-throttle' + | 'down-accelerate' + | 'down-timeout'; interface AssistHoykey { ctrl: boolean; @@ -44,6 +50,13 @@ export interface HotkeyJSON { assist: number; } +export interface HotkeyEmitConfig { + type: KeyEmitType; + throttle?: number; + accelerate?: number; + timeout?: number; +} + export class Hotkey extends EventEmitter { static list: Hotkey[]; @@ -51,6 +64,8 @@ export class Hotkey extends EventEmitter { name: string; data: Record = {}; keyMap: Map = new Map(); + /** 每个指令的配置信息 */ + configData: Map = new Map(); /** id to name */ groupName: Record = { none: '未分类按键' @@ -102,8 +117,9 @@ export class Hotkey extends EventEmitter { * 实现一个按键按下时的操作 * @param id 要实现的按键id,可以不包含数字后缀 * @param func 按键按下时执行的函数 + * @param config 按键触发配置,默认为按键抬起时触发 */ - realize(id: string, func: HotkeyFunc) { + realize(id: string, func: HotkeyFunc, config?: HotkeyEmitConfig) { const toSet = Object.values(this.data).filter(v => { const split = v.id.split('_'); const last = !isNaN(Number(split.at(-1))); @@ -175,6 +191,7 @@ export class Hotkey extends EventEmitter { * 触发一个按键 * @param key 要触发的按键 * @param assist 辅助按键,三位二进制数据,从低到高依次为`ctrl` `shift` `alt` + * @returns 是否有按键被触发 */ emitKey( key: KeyCode, @@ -209,10 +226,11 @@ export class Hotkey extends EventEmitter { * @param id 组的id * @param name 组的名称 */ - group(id: string, name: string) { + group(id: string, name: string, keys?: RegisterHotkeyData[]) { this.grouping = id; this.groupName[id] = name; this.groups[id] ??= []; + keys?.forEach(v => this.register(v)); return this; } @@ -272,6 +290,22 @@ export class Hotkey extends EventEmitter { } } +// todo +/** + * 热键控制器,用于控制按下时触发等操作 + */ +export class HotkeyController { + /** 所有按下的按键 */ + private pressed: Set = new Set(); + + /** 当前控制器管理的热键实例 */ + hotkey: Hotkey; + + constructor(hotkey: Hotkey) { + this.hotkey = hotkey; + } +} + export function unwarpBinary(bin: number): AssistHoykey { return { ctrl: !!(bin & (1 << 0)), @@ -293,3 +327,67 @@ export function checkAssist(bin: number, key: KeyCode) { export function isAssist(key: KeyCode) { return key === KeyCode.Ctrl || key === KeyCode.Shift || key === KeyCode.Alt; } + +export const gameKey = new Hotkey('gameKey', '游戏按键'); + +// ----- Listening +document.addEventListener('keyup', e => { + const assist = generateBinary([e.ctrlKey, e.shiftKey, e.altKey]); + const code = keycode(e.keyCode); + if (gameKey.emitKey(code, assist, 'up', e)) { + e.preventDefault(); + } else { + // polyfill样板 + if ( + main.dom.startPanel.style.display == 'block' && + (main.dom.startButtons.style.display == 'block' || + main.dom.levelChooseButtons.style.display == 'block') + ) { + if (e.keyCode == 38 || e.keyCode == 33) + // up/pgup + main.selectButton((main.selectedButton || 0) - 1); + else if (e.keyCode == 40 || e.keyCode == 34) + // down/pgdn + main.selectButton((main.selectedButton || 0) + 1); + else if (e.keyCode == 67 || e.keyCode == 13 || e.keyCode == 32) + // C/Enter/Space + main.selectButton(main.selectedButton); + else if ( + e.keyCode == 27 && + main.dom.levelChooseButtons.style.display == 'block' + ) { + // ESC + core.showStartAnimate(true); + e.preventDefault(); + } + e.stopPropagation(); + return; + } + if (main.dom.inputDiv.style.display == 'block') { + if (e.keyCode == 13) { + setTimeout(function () { + main.dom.inputYes.click(); + }, 50); + } else if (e.keyCode == 27) { + setTimeout(function () { + main.dom.inputNo.click(); + }, 50); + } + return; + } + if ( + core && + core.isPlaying && + core.status && + (core.isPlaying() || core.status.lockControl) + ) + core.onkeyUp(e); + } +}); +document.addEventListener('keydown', e => { + const assist = generateBinary([e.ctrlKey, e.shiftKey, e.altKey]); + const code = keycode(e.keyCode); + if (gameKey.emitKey(code, assist, 'down', e)) { + e.preventDefault(); + } +}); diff --git a/src/core/main/init/hotkey.ts b/src/core/main/init/hotkey.ts index 07b5735..f9d9847 100644 --- a/src/core/main/init/hotkey.ts +++ b/src/core/main/init/hotkey.ts @@ -1,22 +1,42 @@ import { KeyCode } from '@/plugin/keyCodes'; -import { Hotkey, HotkeyJSON } from '../custom/hotkey'; -import { - generateBinary, - keycode, - openDanmakuPoster, - tip -} from '@/plugin/utils'; +import { gameKey, HotkeyJSON } from '../custom/hotkey'; +import { openDanmakuPoster, tip } from '@/plugin/utils'; import { hovered } from './fixed'; import { hasMarkedEnemy, markEnemy, unmarkEnemy } from '@/plugin/mark'; import { mainUi } from './ui'; import { GameStorage } from '../storage'; export const mainScope = Symbol.for('@key_main'); -export const gameKey = new Hotkey('gameKey', '游戏按键'); // todo: 读取上一个手动存档,存档至下一个存档栏 // ----- Register gameKey + // -------------------- + .group('game', '游戏按键') + .register({ + id: 'moveUp', + type: 'down', + name: '上移', + defaults: KeyCode.UpArrow + }) + .register({ + id: 'moveDown', + type: 'down', + name: '下移', + defaults: KeyCode.DownArrow + }) + .register({ + id: 'moveLeft', + type: 'down', + name: '左移', + defaults: KeyCode.LeftArrow + }) + .register({ + id: 'moveRight', + type: 'down', + name: '右移', + defaults: KeyCode.RightArrow + }) // -------------------- .group('ui', 'ui界面') .register({ @@ -580,65 +600,3 @@ gameKey.on('set', (id, key, assist) => { keyStorage.setValue(id, { key, assist }); }); gameKey.fromJSON(keyStorage.toJSON()); - -// ----- Listening -document.addEventListener('keyup', e => { - const assist = generateBinary([e.ctrlKey, e.shiftKey, e.altKey]); - const code = keycode(e.keyCode); - if (gameKey.emitKey(code, assist, 'up', e)) { - e.preventDefault(); - } else { - // polyfill样板 - if ( - main.dom.startPanel.style.display == 'block' && - (main.dom.startButtons.style.display == 'block' || - main.dom.levelChooseButtons.style.display == 'block') - ) { - if (e.keyCode == 38 || e.keyCode == 33) - // up/pgup - main.selectButton((main.selectedButton || 0) - 1); - else if (e.keyCode == 40 || e.keyCode == 34) - // down/pgdn - main.selectButton((main.selectedButton || 0) + 1); - else if (e.keyCode == 67 || e.keyCode == 13 || e.keyCode == 32) - // C/Enter/Space - main.selectButton(main.selectedButton); - else if ( - e.keyCode == 27 && - main.dom.levelChooseButtons.style.display == 'block' - ) { - // ESC - core.showStartAnimate(true); - e.preventDefault(); - } - e.stopPropagation(); - return; - } - if (main.dom.inputDiv.style.display == 'block') { - if (e.keyCode == 13) { - setTimeout(function () { - main.dom.inputYes.click(); - }, 50); - } else if (e.keyCode == 27) { - setTimeout(function () { - main.dom.inputNo.click(); - }, 50); - } - return; - } - if ( - core && - core.isPlaying && - core.status && - (core.isPlaying() || core.status.lockControl) - ) - core.onkeyUp(e); - } -}); -document.addEventListener('keydown', e => { - const assist = generateBinary([e.ctrlKey, e.shiftKey, e.altKey]); - const code = keycode(e.keyCode); - if (gameKey.emitKey(code, assist, 'down', e)) { - e.preventDefault(); - } -}); diff --git a/src/core/render/adapter.ts b/src/core/render/adapter.ts index 2e6290b..e879cc4 100644 --- a/src/core/render/adapter.ts +++ b/src/core/render/adapter.ts @@ -1,4 +1,5 @@ type AdapterFunction = (item: T, ...params: any[]) => Promise; +type SyncAdapterFunction = (item: T, ...params: any[]) => any; /** * 渲染适配器,用作渲染层与数据层沟通的桥梁,用于在数据层等待渲染层执行,常用与动画等。 @@ -14,6 +15,7 @@ export class RenderAdapter { id: string; private execute: Map> = new Map(); + private syncExecutes: Map> = new Map(); constructor(id: string) { this.id = id; @@ -42,6 +44,14 @@ export class RenderAdapter { this.execute.set(id, fn); } + /** + * 设置同步执行函数 + * @param fn 对于每个元素执行的函数 + */ + recieveSync(id: string, fn: SyncAdapterFunction): void { + this.syncExecutes.set(id, fn); + } + /** * 对所有元素执行函数,当所有元素都运行完毕后兑现,类似于Promise.all * @returns 包含每个元素运行结果的数组 @@ -72,6 +82,19 @@ export class RenderAdapter { } } + /** + * 对所有元素执行同步函数 + * @returns 包含每个元素运行结果的数组 + */ + syncAll(fn: string, ...params: any[]): R[] { + const execute = this.syncExecutes.get(fn); + if (!execute) { + return []; + } else { + return [...this.items].map(v => execute!(v, ...params)); + } + } + /** * 销毁这个adapter */ diff --git a/src/core/render/cache.ts b/src/core/render/cache.ts index ad90fe2..de9989f 100644 --- a/src/core/render/cache.ts +++ b/src/core/render/cache.ts @@ -77,14 +77,19 @@ class TextureCache extends EventEmitter { /** 自动元件额外连接信息,用于对非自身图块进行连接 */ autoConn: Map> = new Map(); /** 行走图朝向绑定 */ - characterDirection: Record = { + characterDirection: Record = { down: 0, left: 1, right: 2, - up: 3 + up: 3, + leftup: 1, + leftdown: 1, + rightup: 2, + rightdown: 2 }; /** 行走图转向顺序 */ characterTurn: Dir[] = ['up', 'right', 'down', 'left']; + characterTurn2: Dir2[] = ['leftup', 'rightup', 'rightdown', 'leftdown']; constructor() { super(); diff --git a/src/core/render/preset/hero.ts b/src/core/render/preset/hero.ts index bb3a1e1..fdd704a 100644 --- a/src/core/render/preset/hero.ts +++ b/src/core/render/preset/hero.ts @@ -45,7 +45,7 @@ export class HeroRenderer /** 上一次帧数切换的时间 */ private lastFrameTime: number = 0; /** 当前的移动方向 */ - private moveDir: Move = 'down'; + private moveDir: Move2 = 'down'; /** 上一步走到格子上的时间 */ private lastStepTime: number = 0; /** 是否已经执行了当前步移动 */ @@ -54,11 +54,11 @@ export class HeroRenderer * 这一步的移动方向,与{@link moveDir}不同的是,在这一步走完之前,它都不会变, * 当这一步走完之后,才会将其设置为{@link moveDir}的值 */ - private stepDir: Dir = 'down'; + private stepDir: Dir2 = 'down'; /** 每步的格子增量 */ private stepDelta: Loc = { x: 0, y: 1 }; /** 动画显示的方向,用于适配后退 */ - private animateDir: Dir = 'down'; + // private animateDir: Dir = 'down'; /** * 设置勇士所用的图片资源 @@ -105,9 +105,9 @@ export class HeroRenderer * 根据方向获取勇士的裁切信息 * @param dir 方向 */ - getRenderFromDir(dir: Move): [number, number, number, number][] { + getRenderFromDir(dir: Move2): [number, number, number, number][] { if (!this.cellWidth || !this.cellHeight) return []; - let resolved: Dir; + let resolved: Dir2; if (dir === 'forward') resolved = this.dir; else if (dir === 'backward') resolved = backDir(this.dir); else resolved = dir; @@ -157,6 +157,8 @@ export class HeroRenderer if (progress >= 1) { this.renderable.x = x + dx; this.renderable.y = y + dy; + console.log(x, y, dx, dy, this.renderable.x, this.renderable.y); + this.emit('stepEnd'); } else { const rx = dx * progress + x; @@ -175,14 +177,14 @@ export class HeroRenderer if (this.moveDir === 'backward') this.stepDir = backDir(this.stepDir); else if (this.moveDir !== 'forward') this.stepDir = this.moveDir; this.lastStepTime = Date.now(); - this.stepDelta = core.utils.scan[this.stepDir]; + this.stepDelta = core.utils.scan2[this.stepDir]; this.turn(this.stepDir); } /** * 移动勇士 */ - move(dir: Move): Promise { + move(dir: Move2): Promise { if (this.status !== 'moving') { logger.error( 12, @@ -225,12 +227,19 @@ export class HeroRenderer * 勇士转向,不填表示顺时针转一个方向 * @param dir 移动方向 */ - turn(dir?: Dir): void { + turn(dir?: Dir2): void { if (!dir) { - const index = texture.characterTurn.indexOf(this.stepDir) + 1; - const length = texture.characterTurn.length; - const next = texture.characterTurn[index % length]; - return this.turn(next); + const index = texture.characterTurn2.indexOf(this.stepDir); + if (index === -1) { + const length = texture.characterTurn.length; + const index = texture.characterTurn.indexOf( + this.stepDir as Dir + ); + const next = texture.characterTurn[index % length]; + return this.turn(next); + } else { + return this.turn(texture.characterTurn[index]); + } } this.moveDir = dir; if (!this.renderable) return; @@ -333,3 +342,7 @@ adapter.recieve( return item.moveAs(x, y, time, fn); } ); +adapter.recieve('setMoveSpeed', (item, speed: number) => { + item.setMoveSpeed(speed); + return Promise.resolve(); +}); diff --git a/src/core/render/render.ts b/src/core/render/render.ts index e527d5f..da03db0 100644 --- a/src/core/render/render.ts +++ b/src/core/render/render.ts @@ -163,16 +163,16 @@ Mota.require('var', 'hook').once('reset', () => { layer.requestAfterFrame(() => { hero.setImage(core.material.images.images['hero2.png']); }); - hero.readyMove(); - layer.delegateTicker( - () => { - hero.move('right'); - }, - 10000, - () => { - hero.endMove(); - } - ); + // hero.readyMove(); + // layer.delegateTicker( + // () => { + // hero.move('right'); + // }, + // 10000, + // () => { + // hero.endMove(); + // } + // ); camera.move(240, 240); render.update(); diff --git a/src/game/system.ts b/src/game/system.ts index dae60d3..68969ce 100644 --- a/src/game/system.ts +++ b/src/game/system.ts @@ -27,7 +27,6 @@ import type { Danmaku } from '@/core/main/custom/danmaku'; import type * as misc from './mechanism/misc'; import type { MotaCanvas2D } from '@/core/fx/canvas2d'; import type * as portal from '@/core/fx/portal'; -import type { HeroRenderer } from '@/core/render/hero'; import type { texture } from '@/core/render/cache'; import type { MotaRenderer } from '@/core/render/render'; import type { Container } from '@/core/render/container'; @@ -35,6 +34,7 @@ import type { Sprite } from '@/core/render/sprite'; import type { Camera } from '@/core/render/camera'; import type { Image, Text } from '@/core/render/preset/misc'; import type { RenderItem } from '@/core/render/item'; +import type { RenderAdapter } from '@/core/render/adapter'; interface ClassInterface { // 渲染进程与游戏进程通用 @@ -105,15 +105,15 @@ interface ModuleInterface { Portal: typeof portal; }; Render: { - heroRender: HeroRenderer; texture: typeof texture; - MotaRenderer: MotaRenderer; - Container: Container; - Sprite: Sprite; - Camera: Camera; - Text: Text; - Image: Image; - RenderItem: RenderItem; + MotaRenderer: typeof MotaRenderer; + Container: typeof Container; + Sprite: typeof Sprite; + Camera: typeof Camera; + Text: typeof Text; + Image: typeof Image; + RenderItem: typeof RenderItem; + RenderAdapter: typeof RenderAdapter; }; } @@ -166,12 +166,12 @@ interface PluginInterface { interface PackageInterface { axios: typeof import('axios'); - 'chart.js': typeof import('chart.js'); + // 'chart.js': typeof import('chart.js'); jszip: typeof import('jszip'); lodash: typeof import('lodash-es'); 'lz-string': typeof import('lz-string'); 'mutate-animate': typeof import('mutate-animate'); - vue: typeof import('vue'); + // vue: typeof import('vue'); } export interface IMota { diff --git a/src/plugin/game/fallback.ts b/src/plugin/game/fallback.ts new file mode 100644 index 0000000..676d9d9 --- /dev/null +++ b/src/plugin/game/fallback.ts @@ -0,0 +1,203 @@ +import type { RenderAdapter } from '@/core/render/adapter'; +import type { HeroRenderer } from '@/core/render/preset/hero'; +import { backDir } from './utils'; + +interface Adapters { + 'hero-adapter'?: RenderAdapter; +} + +const adapters: Adapters = {}; + +export function init() { + if (!main.replayChecking) { + const Adapter = Mota.require('module', 'Render').RenderAdapter; + const hero = Adapter.get('hero-adapter'); + + adapters['hero-adapter'] = hero; + } + + function onMoveEnd(callback?: () => void) { + core.setHeroLoc('x', core.nextX(), true); + core.setHeroLoc('y', core.nextY(), true); + + var direction = core.getHeroLoc('direction'); + core.control._moveAction_popAutomaticRoute(); + core.status.route.push(direction); + + core.moveOneStep(); + core.checkRouteFolding(); + callback?.(); + } + + // ----- 勇士移动相关 + + control.prototype._moveAction_moving = function (callback?: () => void) { + const adapter = adapters['hero-adapter']; + if (!adapter) { + onMoveEnd(callback); + return; + } else { + adapter + .all('readyMove') + .then(() => { + return adapter.all('move', 'forward'); + }) + .then(() => { + onMoveEnd(callback); + return adapter.all('endMove'); + }); + } + }; + + const dir8to4: Record = { + up: 'up', + down: 'down', + left: 'left', + right: 'right', + leftup: 'left', + leftdown: 'left', + rightup: 'right', + rightdown: 'right' + }; + + events.prototype.eventMoveHero = async function ( + steps: string[], + time?: number, + callback?: () => void + ) { + time = time || core.values.moveSpeed; + + // const render = Mota.require('module', 'Render').heroRender; + var step = 0, + moveSteps = (steps || []) + .map(function (t) { + return [t.split(':')[0], parseInt(t.split(':')[1] || '1')]; + }) + .filter(function (t) { + return ( + [ + 'up', + 'down', + 'left', + 'right', + 'forward', + 'backward', + 'leftup', + 'leftdown', + 'rightup', + 'rightdown', + 'speed' + // @ts-ignore + ].indexOf(t[0]) >= 0 && !(t[0] == 'speed' && t[1] < 16) + ); + }); + + if (main.replayChecking) { + // 录像验证中,直接算出来最终位置瞬移过去即可 + const steps = moveSteps; + let { x: nx, y: ny, direction: nowDir } = core.status.hero.loc; + while (steps.length > 0) { + const [dir, count] = steps.shift()! as [string, number]; + if (dir === 'speed') continue; + let resolved: Dir2; + if (dir === 'forward' || dir === 'backward') resolved = nowDir; + else resolved = dir as Dir2; + + nowDir = dir8to4[resolved]; + + const { x, y } = core.utils.scan2[resolved]; + nx += x * count; + ny += y * count; + } + core.setHeroLoc('x', nx, true); + core.setHeroLoc('y', ny, true); + core.setHeroLoc('direction', nowDir, true); + core.updateFollowers(); + core.status.heroMoving = 0; + core.drawHero(); + callback?.(); + } else { + const adapter = adapters['hero-adapter']; + if (!adapter) return; + const steps: string[] = []; + moveSteps.forEach(([dir, count]) => { + if (dir === 'speed') { + steps.push(`speed:${count}`); + } else { + steps.push(...Array(count as number).fill(dir as string)); + } + }); + await adapter.all('readyMove'); + for (const dir of steps) { + if (dir.startsWith('speed')) { + const speed = parseInt(dir.slice(6)); + await adapter.all('setMoveSpeed', speed); + } else { + await adapter.all('move', dir as Move2); + } + } + await adapter.all('endMove'); + core.status.heroMoving = 0; + core.drawHero(); + callback?.(); + } + // core.status.heroMoving = -1; + // // render.move(false); + // var _run = function () { + // var cb = function () { + // core.status.heroMoving = 0; + // // render.move(false); + // core.drawHero(); + // if (callback) callback(); + // }; + + // var animate = window.setInterval( + // function () { + // if (moveSteps.length == 0) { + // delete core.animateFrame.asyncId[animate]; + // clearInterval(animate); + // cb(); + // } else { + // if ( + // step == 0 && + // moveSteps[0][0] == 'speed' && + // moveSteps[0][1] >= 16 + // ) { + // time = moveSteps[0][1]; + // moveSteps.shift(); + // clearInterval(animate); + // delete core.animateFrame.asyncId[animate]; + // _run(); + // } else if ( + // core.events._eventMoveHero_moving(++step, moveSteps) + // ) + // step = 0; + // } + // }, + // core.status.replay.speed == 24 + // ? 1 + // : time / 8 / core.status.replay.speed + // ); + + // core.animateFrame.lastAsyncId = animate; + // core.animateFrame.asyncId[animate] = cb; + // }; + // _run(); + }; + + control.prototype.turnHero = function (direction?: Dir) { + if (direction) { + core.setHeroLoc('direction', direction); + core.drawHero(); + core.status.route.push('turn:' + direction); + return; + } + core.setHeroLoc('direction', core.turnDirection(':right') as Dir); + core.drawHero(); + core.status.route.push('turn'); + core.checkRouteFolding(); + if (!main.replayChecking) { + adapters['hero-adapter']?.all('turn', direction); + } + }; +} diff --git a/src/plugin/game/index.ts b/src/plugin/game/index.ts index 1031b8d..6ce77c3 100644 --- a/src/plugin/game/index.ts +++ b/src/plugin/game/index.ts @@ -16,6 +16,7 @@ import * as utils from './utils'; import * as chase from './chase'; import * as remainEnemy from './enemy/remainEnemy'; import * as checkBlock from './enemy/checkblock'; +import * as fallback from './fallback'; import './hook'; Mota.Plugin.register('utils_g', utils); @@ -37,6 +38,8 @@ Mota.Plugin.register('remainEnemy_g', remainEnemy); Mota.Plugin.register('checkBlock_g', checkBlock, checkBlock.init); // todo: 这几个不应该放到插件 Mota.Plugin.register('ui_g', ui, ui.init); +// 用于暂时向后兼容的插件,若干个版本后会删除 +Mota.Plugin.register('fallback_g', fallback, fallback.init); // export { // halo, diff --git a/src/plugin/game/utils.ts b/src/plugin/game/utils.ts index e279f00..0635705 100644 --- a/src/plugin/game/utils.ts +++ b/src/plugin/game/utils.ts @@ -17,13 +17,19 @@ export function slide(arr: T[], delta: number): T[] { return arr; } -export function backDir(dir: Dir): Dir { - return { - up: 'down', - down: 'up', - left: 'right', - right: 'left' - }[dir] as Dir; +const backDirMap: Record = { + up: 'down', + down: 'up', + left: 'right', + right: 'left', + leftup: 'rightdown', + rightup: 'leftdown', + leftdown: 'rightup', + rightdown: 'leftup' +}; + +export function backDir(dir: Dir2): Dir2 { + return backDirMap[dir]; } export function has(v: T): v is NonNullable { diff --git a/src/types/control.d.ts b/src/types/control.d.ts index 6fa5d7c..8b5b7fa 100644 --- a/src/types/control.d.ts +++ b/src/types/control.d.ts @@ -1092,6 +1092,7 @@ interface Control { offset: Loc & { offset: number }, frame?: number ): void; + _moveAction_popAutomaticRoute(): void; } declare const control: new () => Control; diff --git a/src/types/util.d.ts b/src/types/util.d.ts index 67bdf16..44c380d 100644 --- a/src/types/util.d.ts +++ b/src/types/util.d.ts @@ -604,6 +604,8 @@ type TextPosition = 'up' | 'center' | 'down'; */ type Move = 'forward' | 'backward' | Dir; +type Move2 = Move | Dir2; + /** * 缓动模式,不过在高级动画插件面前不堪一击( */ diff --git a/src/ui/book.vue b/src/ui/book.vue index 84a4975..92d140f 100644 --- a/src/ui/book.vue +++ b/src/ui/book.vue @@ -48,7 +48,7 @@ import { LeftOutlined } from '@ant-design/icons-vue'; import { ToShowEnemy, detailInfo } from '../plugin/ui/book'; import { getDetailedEnemy } from '../plugin/ui/fixed'; import { GameUi } from '@/core/main/custom/ui'; -import { gameKey } from '@/core/main/init/hotkey'; +import { gameKey } from '@/core/main/custom/hotkey'; import { mainUi } from '@/core/main/init/ui'; import { mainSetting } from '@/core/main/setting'; import { isMobile } from '@/plugin/use'; diff --git a/src/ui/bookDetail.vue b/src/ui/bookDetail.vue index f223545..0d213d5 100644 --- a/src/ui/bookDetail.vue +++ b/src/ui/bookDetail.vue @@ -83,7 +83,7 @@ import { LeftOutlined, RightOutlined } from '@ant-design/icons-vue'; import EnemyCritical from '../panel/enemyCritical.vue'; import EnemyTarget from '../panel/enemyTarget.vue'; import { detailInfo } from '../plugin/ui/book'; -import { gameKey } from '@/core/main/init/hotkey'; +import { gameKey } from '@/core/main/custom/hotkey'; const props = defineProps<{ fromBook?: boolean; diff --git a/src/ui/danmakuEditor.vue b/src/ui/danmakuEditor.vue index 92ff593..c9fbdd6 100644 --- a/src/ui/danmakuEditor.vue +++ b/src/ui/danmakuEditor.vue @@ -163,7 +163,7 @@ import { GameUi } from '@/core/main/custom/ui'; import { sleep } from 'mutate-animate'; import { fixedUi } from '@/core/main/init/ui'; import { calStringSize, tip } from '@/plugin/utils'; -import { gameKey } from '@/core/main/init/hotkey'; +import { gameKey } from '@/core/main/custom/hotkey'; import { isNil } from 'lodash-es'; import { stringifyCSS, parseCss, getIconHeight } from '@/plugin/utils'; import { logger, LogLevel } from '@/core/common/logger'; diff --git a/src/ui/desc.vue b/src/ui/desc.vue index 355d776..5682f23 100644 --- a/src/ui/desc.vue +++ b/src/ui/desc.vue @@ -23,7 +23,7 @@ import desc from '../data/desc.json'; import { splitText } from '../plugin/utils'; import Colomn from '../components/colomn.vue'; import { GameUi } from '@/core/main/custom/ui'; -import { gameKey } from '@/core/main/init/hotkey'; +import { gameKey } from '@/core/main/custom/hotkey'; import { mainUi } from '@/core/main/init/ui'; const props = defineProps<{ diff --git a/src/ui/equipbox.vue b/src/ui/equipbox.vue index bf90ad5..7cc8443 100644 --- a/src/ui/equipbox.vue +++ b/src/ui/equipbox.vue @@ -195,7 +195,7 @@ import { has, tip, type } from '../plugin/utils'; import { cancelGlobalDrag, isMobile, useDrag } from '../plugin/use'; import { hyper } from 'mutate-animate'; import { GameUi } from '@/core/main/custom/ui'; -import { gameKey } from '@/core/main/init/hotkey'; +import { gameKey } from '@/core/main/custom/hotkey'; import { getStatusLabel } from '../plugin/utils'; import { mainUi } from '@/core/main/init/ui'; diff --git a/src/ui/fly.vue b/src/ui/fly.vue index 5a40bac..774e303 100644 --- a/src/ui/fly.vue +++ b/src/ui/fly.vue @@ -100,7 +100,7 @@ import { import { debounce } from 'lodash-es'; import { tip } from '../plugin/utils'; import { GameUi } from '@/core/main/custom/ui'; -import { gameKey } from '@/core/main/init/hotkey'; +import { gameKey } from '@/core/main/custom/hotkey'; import { createChangable } from '@/plugin/ui/common'; import { mainUi } from '@/core/main/init/ui'; import { mainSetting } from '@/core/main/setting'; diff --git a/src/ui/hotkey.vue b/src/ui/hotkey.vue index a2b81cc..69f12a8 100644 --- a/src/ui/hotkey.vue +++ b/src/ui/hotkey.vue @@ -44,7 +44,7 @@ import { computed, onMounted, onUnmounted, reactive, ref } from 'vue'; import { KeyCode, KeyCodeUtils } from '@/plugin/keyCodes'; import { generateBinary, keycode } from '@/plugin/utils'; import { cloneDeep } from 'lodash-es'; -import { gameKey } from '@/core/main/init/hotkey'; +import { gameKey } from '@/core/main/custom/hotkey'; interface HotkeyKeys { index: number; diff --git a/src/ui/settings.vue b/src/ui/settings.vue index f7064f3..1478a10 100644 --- a/src/ui/settings.vue +++ b/src/ui/settings.vue @@ -84,7 +84,7 @@ import { RightOutlined, LeftOutlined } from '@ant-design/icons-vue'; import { splitText } from '../plugin/utils'; import Scroll from '../components/scroll.vue'; import { isMobile } from '../plugin/use'; -import { gameKey } from '@/core/main/init/hotkey'; +import { gameKey } from '@/core/main/custom/hotkey'; import { GameUi } from '@/core/main/custom/ui'; import { mainUi } from '@/core/main/init/ui'; diff --git a/src/ui/shop.vue b/src/ui/shop.vue index 6f46157..3f0c816 100644 --- a/src/ui/shop.vue +++ b/src/ui/shop.vue @@ -173,7 +173,7 @@ import { splitText, tip } from '../plugin/utils'; import Scroll from '../components/scroll.vue'; import BoxAnimate from '../components/boxAnimate.vue'; import { GameUi } from '@/core/main/custom/ui'; -import { gameKey } from '@/core/main/init/hotkey'; +import { gameKey } from '@/core/main/custom/hotkey'; import { mainUi } from '@/core/main/init/ui'; const props = defineProps<{ diff --git a/src/ui/skillTree.vue b/src/ui/skillTree.vue index 608d737..216cdb2 100644 --- a/src/ui/skillTree.vue +++ b/src/ui/skillTree.vue @@ -84,7 +84,7 @@ import Scroll from '../components/scroll.vue'; import { has, splitText, tip } from '../plugin/utils'; import { isMobile } from '../plugin/use'; import { sleep } from 'mutate-animate'; -import { gameKey } from '@/core/main/init/hotkey'; +import { gameKey } from '@/core/main/custom/hotkey'; import { GameUi } from '@/core/main/custom/ui'; import { mainUi } from '@/core/main/init/ui'; diff --git a/src/ui/start.vue b/src/ui/start.vue index 346eea4..b9b4999 100644 --- a/src/ui/start.vue +++ b/src/ui/start.vue @@ -69,7 +69,7 @@ import { doByInterval, keycode } from '../plugin/utils'; import { triggerFullscreen } from '../plugin/utils'; import { isMobile } from '../plugin/use'; import { GameUi } from '@/core/main/custom/ui'; -import { gameKey } from '@/core/main/init/hotkey'; +import { gameKey } from '@/core/main/custom/hotkey'; import { mainUi } from '@/core/main/init/ui'; import { CustomToolbar } from '@/core/main/custom/toolbar'; import { mainSetting } from '@/core/main/setting'; diff --git a/src/ui/toolbox.vue b/src/ui/toolbox.vue index bc69734..6e51d90 100644 --- a/src/ui/toolbox.vue +++ b/src/ui/toolbox.vue @@ -116,9 +116,8 @@ import { isMobile } from '../plugin/use'; import { type, keycode, has } from '../plugin/utils'; import { hyper, sleep } from 'mutate-animate'; import { message } from 'ant-design-vue'; -import { KeyCode } from '../plugin/keyCodes'; import { GameUi } from '@/core/main/custom/ui'; -import { gameKey } from '@/core/main/init/hotkey'; +import { gameKey } from '@/core/main/custom/hotkey'; import { mainUi } from '@/core/main/init/ui'; const props = defineProps<{