init: 2.B

This commit is contained in:
AncTe committed 2026-02-28 20:23:34 +08:00
commit 6bf32174d8
610 files changed
+151444

No files matched your search

@@ -0,0 +1,521 @@
import { KeyCode } from '@motajs/client-base';
import { gameKey, HotkeyJSON } from '@motajs/system-action';
import { GameStorage } from '@motajs/legacy-system';
export const mainScope = Symbol.for('@key_main');
// todo: 读取上一个手动存档,存档至下一个存档栏
// ----- Register
gameKey
//#region 游戏按键
.group('game', '游戏按键')
.register({
id: 'moveUp',
name: '上移',
defaults: KeyCode.UpArrow
})
.register({
id: 'moveDown',
name: '下移',
defaults: KeyCode.DownArrow
})
.register({
id: 'moveLeft',
name: '左移',
defaults: KeyCode.LeftArrow
})
.register({
id: 'moveRight',
name: '右移',
defaults: KeyCode.RightArrow
})
//#region ui界面
.group('ui', 'ui界面')
.register({
id: 'book',
name: '怪物手册',
defaults: KeyCode.KeyX
})
.register({
id: 'save',
name: '存档界面',
defaults: KeyCode.KeyS
})
.register({
id: 'load',
name: '读档界面',
defaults: KeyCode.KeyD
})
.register({
id: 'toolbox',
name: '道具栏',
defaults: KeyCode.KeyT
})
.register({
id: 'equipbox',
name: '装备栏',
defaults: KeyCode.KeyQ
})
.register({
id: 'fly',
name: '楼层传送',
defaults: KeyCode.KeyG
})
.register({
id: 'menu',
name: '菜单',
defaults: KeyCode.Escape
})
.register({
id: 'replay',
name: '录像回放',
defaults: KeyCode.KeyR
})
.register({
id: 'shop',
name: '快捷商店',
defaults: KeyCode.KeyV
})
.register({
id: 'viewMap_1',
name: '浏览地图_1',
defaults: KeyCode.PageUp
})
.register({
id: 'viewMap_2',
name: '浏览地图_2',
defaults: KeyCode.PageDown
})
//#region 功能按键
.group('function', '功能按键')
.register({
id: 'undo_1',
name: '回退_1',
defaults: KeyCode.KeyA
})
.register({
id: 'undo_2',
name: '回退_2',
defaults: KeyCode.Digit5
})
.register({
id: 'redo_1',
name: '恢复_1',
defaults: KeyCode.KeyW
})
.register({
id: 'redo_2',
name: '恢复_2',
defaults: KeyCode.Digit6
})
.register({
id: 'turn',
name: '勇士转向',
defaults: KeyCode.KeyZ
})
.register({
id: 'getNext_1',
name: '轻按_1',
defaults: KeyCode.Space
})
.register({
id: 'getNext_2',
name: '轻按_2',
defaults: KeyCode.Digit7
})
.register({
id: 'quickEquip_1',
name: '切换/保存套装_1',
defaults: KeyCode.Digit1,
alt: true
})
.register({
id: 'quickEquip_2',
name: '切换/保存套装_2',
defaults: KeyCode.Digit2,
alt: true
})
.register({
id: 'quickEquip_3',
name: '切换/保存套装_3',
defaults: KeyCode.Digit3,
alt: true
})
.register({
id: 'quickEquip_4',
name: '切换/保存套装_4',
defaults: KeyCode.Digit4,
alt: true
})
.register({
id: 'quickEquip_5',
name: '切换/保存套装_5',
defaults: KeyCode.Digit5,
alt: true
})
.register({
id: 'quickEquip_6',
name: '切换/保存套装_6',
defaults: KeyCode.Digit6,
alt: true
})
.register({
id: 'quickEquip_7',
name: '切换/保存套装_7',
defaults: KeyCode.Digit7,
alt: true
})
.register({
id: 'quickEquip_8',
name: '切换/保存套装_8',
defaults: KeyCode.Digit8,
alt: true
})
.register({
id: 'quickEquip_9',
name: '切换/保存套装_9',
defaults: KeyCode.Digit9,
alt: true
})
.register({
id: 'quickEquip_0',
name: '切换/保存套装_0',
defaults: KeyCode.Digit0,
alt: true
})
//#region 系统按键
.group('system', '系统按键')
.register({
id: 'restart',
name: '回到开始界面',
defaults: KeyCode.KeyN
})
.register({
id: 'comment',
name: '评论区',
defaults: KeyCode.KeyP
})
.register({
id: 'debug',
name: '调试模式',
defaults: KeyCode.F8
})
//#region 通用按键
.group('general', '通用按键')
.register({
id: 'exit_1',
name: '退出ui界面_1',
defaults: KeyCode.KeyX
})
.register({
id: 'exit_2',
name: '退出ui界面_2',
defaults: KeyCode.Escape
})
.register({
id: 'confirm_1',
name: '确认_1',
defaults: KeyCode.Enter
})
.register({
id: 'confirm_2',
name: '确认_2',
defaults: KeyCode.Space
})
.register({
id: 'confirm_3',
name: '确认_3',
defaults: KeyCode.KeyC
})
//#region 开始界面
.group('@ui_start', '开始界面')
.register({
id: '@start_up',
name: '上移光标',
defaults: KeyCode.UpArrow
})
.register({
id: '@start_down',
name: '下移光标',
defaults: KeyCode.DownArrow
})
//#region 怪物手册
.group('@ui_book', '怪物手册')
.register({
id: '@book_up',
name: '上移光标',
defaults: KeyCode.UpArrow
})
.register({
id: '@book_down',
name: '下移光标',
defaults: KeyCode.DownArrow
})
.register({
id: '@book_pageDown_1',
name: '下移5个怪物_1',
defaults: KeyCode.RightArrow
})
.register({
id: '@book_pageDown_2',
name: '下移5个怪物_2',
defaults: KeyCode.PageDown
})
.register({
id: '@book_pageUp_1',
name: '上移5个怪物_1',
defaults: KeyCode.LeftArrow
})
.register({
id: '@book_pageUp_2',
name: '上移5个怪物_2',
defaults: KeyCode.PageUp
})
//#region 道具栏
.group('@ui_toolbox', '道具栏')
.register({
id: '@toolbox_right',
name: '光标右移',
defaults: KeyCode.RightArrow
})
.register({
id: '@toolbox_left',
name: '光标左移',
defaults: KeyCode.LeftArrow
})
.register({
id: '@toolbox_up',
name: '光标上移',
defaults: KeyCode.UpArrow
})
.register({
id: '@toolbox_down',
name: '光标下移',
defaults: KeyCode.DownArrow
})
//#region 商店
.group('@ui_shop', '商店')
.register({
id: '@shop_up',
name: '上移光标',
defaults: KeyCode.UpArrow
})
.register({
id: '@shop_down',
name: '下移光标',
defaults: KeyCode.DownArrow
})
.register({
id: '@shop_add',
name: '增加购买量',
defaults: KeyCode.RightArrow
})
.register({
id: '@shop_min',
name: '减少购买量',
defaults: KeyCode.LeftArrow
})
//#region 楼层传送
.group('@ui_fly', '楼层传送')
.register({
id: '@fly_left',
name: '左移地图',
defaults: KeyCode.LeftArrow
})
.register({
id: '@fly_right',
name: '右移地图',
defaults: KeyCode.RightArrow
})
.register({
id: '@fly_up',
name: '上移地图',
defaults: KeyCode.UpArrow
})
.register({
id: '@fly_down',
name: '下移地图',
defaults: KeyCode.DownArrow
})
.register({
id: '@fly_last',
name: '上一张地图',
defaults: KeyCode.PageDown
})
.register({
id: '@fly_next',
name: '下一张地图',
defaults: KeyCode.PageUp
})
//#region 传统楼传
.group('@ui_fly_tradition', '楼层传送-传统按键')
.register({
id: '@fly_down_t',
name: '上一张地图',
defaults: KeyCode.DownArrow
})
.register({
id: '@fly_up_t',
name: '下一张地图',
defaults: KeyCode.UpArrow
})
.register({
id: '@fly_left_t_1',
name: '前10张地图_1',
defaults: KeyCode.LeftArrow
})
.register({
id: '@fly_left_t_2',
name: '前10张地图_2',
defaults: KeyCode.PageDown
})
.register({
id: '@fly_right_t_1',
name: '后10张地图_1',
defaults: KeyCode.RightArrow
})
.register({
id: '@fly_right_t_2',
name: '后10张地图_2',
defaults: KeyCode.PageUp
})
// #region 存档界面
.group('@ui_save', '存档界面')
.register({
id: '@save_pageUp',
name: '向后翻页',
defaults: KeyCode.PageUp
})
.register({
id: '@save_pageDown',
name: '向前翻页',
defaults: KeyCode.PageDown
})
.register({
id: '@save_up',
name: '选择框向上',
defaults: KeyCode.UpArrow
})
.register({
id: '@save_down',
name: '选择框向下',
defaults: KeyCode.DownArrow
})
.register({
id: '@save_left',
name: '选择框向左',
defaults: KeyCode.LeftArrow
})
.register({
id: '@save_right',
name: '选择框向右',
defaults: KeyCode.RightArrow
})
//#region 浏览地图
.group('@ui_viewMap', '浏览地图')
.register({
id: '@viewMap_up_1',
name: '下一层地图_1',
defaults: KeyCode.UpArrow
})
.register({
id: '@viewMap_up_2',
name: '下一层地图_2',
defaults: KeyCode.PageUp
})
.register({
id: '@viewMap_down_1',
name: '上一层地图_1',
defaults: KeyCode.DownArrow
})
.register({
id: '@viewMap_down_2',
name: '上一层地图_2',
defaults: KeyCode.PageDown
})
.register({
id: '@viewMap_up_ten',
name: '下十层地图',
defaults: KeyCode.UpArrow,
ctrl: true
})
.register({
id: '@viewMap_down_ten',
name: '上十层地图',
defaults: KeyCode.DownArrow,
ctrl: true
})
.register({
id: '@viewMap_book',
name: '怪物手册',
defaults: KeyCode.KeyX
})
.register({
id: '@viewMap_fly',
name: '传送至',
defaults: KeyCode.KeyG
})
.register({
id: '@viewMap_reset',
name: '重置视角',
defaults: KeyCode.KeyR
});
// #endregion
gameKey.enable();
gameKey.use(mainScope);
//#region 按键实现
gameKey
.when(
() =>
!core.status.lockControl && !core.isMoving() && !core.isReplaying()
)
.realize('book', () => {
core.openBook(true);
})
.realize('toolbox', () => {
core.openToolbox(true);
})
.realize('equipbox', () => {
core.openEquipbox(true);
})
.realize('fly', () => {
core.useFly(true);
})
.realize('shop', () => {
core.openQuickShop(true);
})
.realize('undo', () => {
core.doSL('autoSave', 'load');
})
.realize('redo', () => {
core.doSL('autoSave', 'reload');
})
.realize('turn', () => {
core.turnHero();
})
.realize('getNext', () => {
core.getNextItem();
})
.realize('restart', () => {
core.confirmRestart();
})
.realize('comment', () => {
core.actions._clickGameInfo_openComments();
})
.realize('debug', () => {
core.debug();
});
// ----- Storage
const keyStorage = new GameStorage<Record<string, HotkeyJSON>>(
GameStorage.fromAuthor('AncTe', 'gameKey')
);
keyStorage.data = {};
keyStorage.read();
gameKey.on('set', (id, key, assist) => {
keyStorage.setValue(id, { key, assist });
});
gameKey.fromJSON(keyStorage.toJSON());
@@ -0,0 +1,2 @@
export * from './move';
export * from './hotkey';
@@ -0,0 +1,182 @@
import { KeyCode } from '@motajs/client-base';
import { Hotkey, HotkeyData } from '@motajs/system-action';
import { HeroMover, IMoveController } from '@user/data-state';
import { Ticker } from 'mutate-animate';
import { mainScope } from './hotkey';
type MoveKey = Record<Dir, HotkeyData>;
type MoveKeyConfig = Record<Dir, string>;
export class HeroKeyMover {
/** 当前按下的键 */
private pressedKey: Set<Dir> = new Set();
/** 当前的移动方向 */
private moveDir: Dir = 'down';
/** 当前是否正在使用按键移动 */
private moving: boolean = false;
/** 当前移动的控制器 */
private controller?: IMoveController;
/** 按键接续ticker */
private ticker = new Ticker();
/** 当前移动实例绑定的热键 */
hotkey: Hotkey;
/** 当前热键的移动按键信息 */
hotkeyData: MoveKey;
/** 移动实例 */
mover: HeroMover;
/** 移动可触发的作用域 */
scope: symbol = mainScope;
constructor(hotkey: Hotkey, mover: HeroMover, config?: MoveKeyConfig) {
this.hotkey = hotkey;
this.mover = mover;
hotkey.on('press', this.onPressKey);
hotkey.on('release', this.onReleaseKey);
const data = hotkey.data;
this.hotkeyData = {
left: data[config?.left ?? 'moveLeft'],
right: data[config?.right ?? 'moveRight'],
up: data[config?.up ?? 'moveUp'],
down: data[config?.down ?? 'moveDown']
};
// 静止时尝试启动移动
this.ticker.add(() => {
if (!this.moving) {
if (this.pressedKey.size > 0) {
const dir = [...this.pressedKey].at(-1);
if (!dir) return;
this.moveDir = dir;
this.tryStartMove();
}
}
});
}
/**
* 按键移动
* @param code 按键码
*/
private onPressKey = (code: KeyCode) => {
if (core.isReplaying() || !core.isPlaying()) return;
core.waitHeroToStop();
if (code === this.hotkeyData.left.key) this.press('left');
else if (code === this.hotkeyData.right.key) this.press('right');
else if (code === this.hotkeyData.up.key) this.press('up');
else if (code === this.hotkeyData.down.key) this.press('down');
};
/**
* 释放按键
* @param code 按键码
*/
private onReleaseKey = (code: KeyCode) => {
if (code === this.hotkeyData.left.key) this.release('left');
else if (code === this.hotkeyData.right.key) this.release('right');
else if (code === this.hotkeyData.up.key) this.release('up');
else if (code === this.hotkeyData.down.key) this.release('down');
};
/**
* 设置按键触发作用域
*/
setScope(scope: symbol) {
this.scope = scope;
}
/**
* 按下某个方向键
* @param dir 移动方向
*/
press(dir: Dir) {
if (this.hotkey.scope !== this.scope || core.status.lockControl) return;
this.pressedKey.add(dir);
this.moveDir = dir;
if (!this.moving) {
this.tryStartMove();
}
}
/**
* 松开方向键
* @param dir 移动方向
*/
release(dir: Dir) {
this.pressedKey.delete(dir);
if (this.pressedKey.size > 0) {
this.moveDir = [...this.pressedKey][0];
} else {
this.endMove();
}
}
/**
* 尝试开始移动
* @returns 是否成功开始移动
*/
tryStartMove() {
if (this.moving || core.status.lockControl) return false;
this.mover.oneStep(this.moveDir);
const controller = this.mover.startMove(false, false, false, true);
if (!controller) return false;
this.controller = controller;
controller.onEnd.then(() => {
this.moving = false;
this.controller = void 0;
this.mover.off('stepEnd', this.onStepEnd);
});
this.moving = true;
this.mover.on('stepEnd', this.onStepEnd);
return true;
}
/**
* 停止本次按键移动
*/
endMove() {
this.controller?.stop();
}
/**
* 移动结束
*/
private onStepEnd = () => {
const con = this.controller;
if (!con) return;
// 被禁止操作时
if (core.status.lockControl) {
con.stop();
return;
}
// 未移动时
if (!this.moving) {
con.stop();
return;
}
// 尝试移动
if (this.pressedKey.size > 0) {
if (con.queue.length === 0) {
con.push({ type: 'dir', value: this.moveDir });
}
} else {
con.stop();
}
};
destroy() {
this.hotkey.off('press', this.onPressKey);
this.hotkey.off('release', this.onReleaseKey);
this.mover.off('stepEnd', this.onStepEnd);
this.ticker.destroy();
}
}