refactor: 迁移旧ui至新ui系统

This commit is contained in:
unanmed 2023-11-05 10:54:26 +08:00
parent 9a97a470f1
commit 8fcc570e5d
29 changed files with 219 additions and 320 deletions

View File

@ -405,16 +405,18 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = {
break; break;
case 67: // C怪物临界 case 67: // C怪物临界
if (core.getBlockCls(mx, my)?.startsWith('enemy')) { if (core.getBlockCls(mx, my)?.startsWith('enemy')) {
core.plugin.fixedDetailPanel = 'critical';
mota.plugin.fixed.showFixed.value = false; mota.plugin.fixed.showFixed.value = false;
mota.plugin.ui.fixedDetailOpened.value = true; mota.ui.main.open('fixedDetail', void 0, {
panel: 'critical'
});
} }
break; break;
case 69: // E怪物属性 case 69: // E怪物属性
if (core.getBlockCls(mx, my)?.startsWith('enemy')) { if (core.getBlockCls(mx, my)?.startsWith('enemy')) {
core.plugin.fixedDetailPanel = 'special';
mota.plugin.fixed.showFixed.value = false; mota.plugin.fixed.showFixed.value = false;
mota.plugin.ui.fixedDetailOpened.value = true; mota.ui.main.open('fixedDetail', void 0, {
panel: 'special'
});
} }
break; break;
case 77: // M快速标记 case 77: // M快速标记

View File

@ -1161,21 +1161,21 @@ var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a =
"name": "bgm查看器", "name": "bgm查看器",
"canUseItemEffect": "true", "canUseItemEffect": "true",
"text": "可以查看游戏内你已经听过的bgm歌曲名格式歌手——歌曲名。未完工。", "text": "可以查看游戏内你已经听过的bgm歌曲名格式歌手——歌曲名。未完工。",
"useItemEffect": "mota.plugin.utils.tip('warn', '当前道具还未制作完成!');\n// mota.plugin.ui.bgmOpened.value = true;" "useItemEffect": "mota.plugin.utils.tip('warn', '当前道具还未制作完成!');\n// mota.ui.main.open('bgm');"
}, },
"I559": { "I559": {
"cls": "constants", "cls": "constants",
"name": "系统设置", "name": "系统设置",
"canUseItemEffect": "true", "canUseItemEffect": "true",
"text": "内含所有系统设置项", "text": "内含所有系统设置项",
"useItemEffect": "if (!core.isReplaying()) mota.plugin.ui.settingsOpened.value = true;" "useItemEffect": "if (!core.isReplaying()) mota.ui.main.open('settings');"
}, },
"I560": { "I560": {
"cls": "constants", "cls": "constants",
"name": "百科全书", "name": "百科全书",
"canUseItemEffect": "true", "canUseItemEffect": "true",
"text": "一个包含游戏中所有功能详细说明的百科全书,可以查看游戏中所有的功能", "text": "一个包含游戏中所有功能详细说明的百科全书,可以查看游戏中所有的功能",
"useItemEffect": "if (!core.isReplaying()) mota.plugin.ui.descOpened.value = true;" "useItemEffect": "if (!core.isReplaying()) mota.ui.main.open('desc');"
}, },
"I565": { "I565": {
"cls": "constants", "cls": "constants",
@ -1233,7 +1233,7 @@ var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a =
"cls": "constants", "cls": "constants",
"name": "成就", "name": "成就",
"canUseItemEffect": "true", "canUseItemEffect": "true",
"useItemEffect": "mota.plugin.ui.achievementOpened.value = true;", "useItemEffect": "mota.ui.main.open('achievement');",
"text": "可以查看成就" "text": "可以查看成就"
} }
} }

View File

@ -1,20 +1,13 @@
<template> <template>
<!-- <div id="ui">
<template v-for="com of uiStack">
<component :is="com"></component>
</template>
</div> -->
<div id="ui-new"> <div id="ui-new">
<div id="ui-main"> <div id="ui-main">
<div id="ui-list"> <div id="ui-list">
<div class="ui-one" v-for="ui of mainUi.stack"> <div class="ui-one" v-for="ui of mainUi.stack">
<template> <component
<component :is="ui.ui.component"
:is="ui.ui.component" v-on="ui.vOn ?? {}"
v-on="ui.vOn ?? {}" v-bind="ui.vBind ?? {}"
v-bind="ui.vBind ?? {}" ></component>
></component>
</template>
</div> </div>
</div> </div>
</div> </div>
@ -64,9 +57,12 @@ onMounted(() => {
height: 100vh; height: 100vh;
display: none; display: none;
justify-content: center; justify-content: center;
align-items: center;
left: 0; left: 0;
top: 0; top: 0;
position: fixed; position: fixed;
background-color: #000b;
backdrop-filter: blur(5px);
} }
#ui-list { #ui-list {

View File

@ -1,47 +0,0 @@
<template>
<!-- <div id="non-ui">
<Start v-if="startOpened"></Start>
<StatusBar v-if="showStatusBar"></StatusBar>
<MarkedEnemy v-if="showMarkedEnemy && showStatusBar"></MarkedEnemy>
<Studied
v-if="showStudiedSkill && showStatusBar && showStudied"
></Studied>
<Fixed v-if="showStatusBar && useFixed"></Fixed>
<Chapter v-if="chapterShowed" :chapter="chapterContent"></Chapter>
<CompleteAchievement
v-if="showComplete"
:complete="completeAchi"
></CompleteAchievement>
</div> -->
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { showStatusBar, startOpened } from './plugin/uiController';
import { chapterContent, chapterShowed } from './plugin/ui/chapter';
import { showMarkedEnemy } from './plugin/mark';
import { showComplete, completeAchi } from './plugin/ui/achievement';
import MarkedEnemy from './ui/markedEnemy.vue';
import StatusBar from './ui/statusBar.vue';
import Chapter from './ui/chapter.vue';
import Fixed from './ui/fixed.vue';
import Start from './ui/start.vue';
import CompleteAchievement from './ui/completeAchievement.vue';
import { mainSetting } from './core/main/setting';
const useFixed = ref(true);
mainSetting.on('valueChange', (key, n, o) => {
if (key === 'action.fixed') useFixed.value = n as boolean;
});
</script>
<style lang="less" scoped>
#non-ui {
width: 0;
height: 0;
overflow: visible;
left: 0;
top: 0;
}
</style>

View File

@ -302,9 +302,10 @@ hotkey
const [x, y] = flags.mouseLoc ?? []; const [x, y] = flags.mouseLoc ?? [];
const [mx, my] = getLocFromMouseLoc(x, y); const [mx, my] = getLocFromMouseLoc(x, y);
if (core.getBlockCls(mx, my)?.startsWith('enemy')) { if (core.getBlockCls(mx, my)?.startsWith('enemy')) {
core.plugin.fixedDetailPanel = 'special';
mota.plugin.fixed.showFixed.value = false; mota.plugin.fixed.showFixed.value = false;
mota.plugin.ui.fixedDetailOpened.value = true; mota.ui.main.open('fixedDetail', void 0, {
panel: 'special'
});
} }
} }
}) })
@ -314,9 +315,10 @@ hotkey
const [x, y] = flags.mouseLoc ?? []; const [x, y] = flags.mouseLoc ?? [];
const [mx, my] = getLocFromMouseLoc(x, y); const [mx, my] = getLocFromMouseLoc(x, y);
if (core.getBlockCls(mx, my)?.startsWith('enemy')) { if (core.getBlockCls(mx, my)?.startsWith('enemy')) {
core.plugin.fixedDetailPanel = 'critical';
mota.plugin.fixed.showFixed.value = false; mota.plugin.fixed.showFixed.value = false;
mota.plugin.ui.fixedDetailOpened.value = true; mota.ui.main.open('fixedDetail', void 0, {
panel: 'critical'
});
} }
} }
}) })

View File

@ -124,6 +124,12 @@ interface ShowableGameUi {
type UiVOn = Record<string, (param?: any) => void>; type UiVOn = Record<string, (param?: any) => void>;
type UiVBind = Record<string, any>; type UiVBind = Record<string, any>;
interface MountedVBind {
num: number;
ui: GameUi;
[x: string]: any;
}
export class GameUi extends EventEmitter<GameUiEvent> { export class GameUi extends EventEmitter<GameUiEvent> {
static uiList: GameUi[] = []; static uiList: GameUi[] = [];
@ -151,6 +157,11 @@ export class GameUi extends EventEmitter<GameUiEvent> {
interface IndexedGameUi extends ShowableGameUi { interface IndexedGameUi extends ShowableGameUi {
num: number; num: number;
vBind?: MountedVBind;
}
interface HoldOnController {
end(): void;
} }
export class UiController extends Focus<IndexedGameUi> { export class UiController extends Focus<IndexedGameUi> {
@ -166,11 +177,13 @@ export class UiController extends Focus<IndexedGameUi> {
this.on('splice', spliced => { this.on('splice', spliced => {
spliced.forEach(v => { spliced.forEach(v => {
v.ui.emit('close'); v.ui.emit('close');
if (this.stack.length === 0) {
if (!this.hold) this.emit('end');
this.hold = false;
}
}); });
if (this.stack.length === 0) {
console.log(this.hold);
if (!this.hold) this.emit('end');
this.hold = false;
}
}); });
this.on('add', item => { this.on('add', item => {
if (this.stack.length === 1) { if (this.stack.length === 1) {
@ -201,11 +214,17 @@ export class UiController extends Focus<IndexedGameUi> {
* ui不会导致ui整体被关闭ui背景闪烁 * ui不会导致ui整体被关闭ui背景闪烁
* holdOn使 app: * holdOn使 app:
* ```txt * ```txt
* hold on -> close -> use item -> hook -> stack.length === 0 ? hide app : no action * hold on -> close -> use item -> hook -> stack.length === 0 ? end() : no action
* ``` * ```
*/ */
holdOn() { holdOn(): HoldOnController {
this.hold = true; this.hold = true;
return {
end: () => {
this.emit('end');
}
};
} }
/** /**
@ -222,7 +241,6 @@ export class UiController extends Focus<IndexedGameUi> {
* @param id ui的id * @param id ui的id
*/ */
closeByName(id: string) { closeByName(id: string) {
console.log(id);
if (!this.equal) { if (!this.equal) {
const ui = this.stack.findIndex(v => v.ui.id === id); const ui = this.stack.findIndex(v => v.ui.id === id);
this.spliceIndex(ui); this.spliceIndex(ui);
@ -245,7 +263,15 @@ export class UiController extends Focus<IndexedGameUi> {
const ui = this.get(id); const ui = this.get(id);
if (!ui) return -1; if (!ui) return -1;
const num = this.num++; const num = this.num++;
this.add({ num, ...ui.with(vOn, vBind) }); const sui = ui.with(vOn, {
num,
ui,
...(vBind ?? {})
});
this.add({
num,
...sui
} as IndexedGameUi);
return num; return num;
} }
@ -292,4 +318,12 @@ export class UiController extends Focus<IndexedGameUi> {
getByNum(num: number) { getByNum(num: number) {
return this.stack.find(v => v.num === num); return this.stack.find(v => v.num === num);
} }
/**
* ui的唯一标识符来判断当前是否存在某个ui
* @param id ui的唯一标识符
*/
hasName(id: string) {
return this.stack.some(v => v.ui.id === id);
}
} }

View File

@ -1,21 +1,4 @@
import Book from '@ui/book.vue'; import * as UI from '@ui/.';
import Toolbox from '@ui/toolbox.vue';
import Equipbox from '@ui/equipbox.vue';
import Settings from '@ui/settings.vue';
import Desc from '@ui/desc.vue';
import Skill from '@ui/skill.vue';
import SkillTree from '@ui/skillTree.vue';
import Fly from '@ui/fly.vue';
import FixedDetail from '@ui/fixedDetail.vue';
import Shop from '@ui/shop.vue';
import Achievement from '@ui/achievement.vue';
import Bgm from '@ui/bgmList.vue';
import StatusBar from '@ui/statusBar.vue';
import Mark from '@ui/markedEnemy.vue';
import Fixed from '@ui/fixed.vue';
import Chapter from '@ui/chapter.vue';
import CompleteAchi from '@ui/completeAchievement.vue';
import Start from '@ui/start.vue';
import { GameUi, UiController } from '../custom/ui'; import { GameUi, UiController } from '../custom/ui';
import { Hotkey } from '../custom/hotkey'; import { Hotkey } from '../custom/hotkey';
import { KeyCode } from '@/plugin/keyCodes'; import { KeyCode } from '@/plugin/keyCodes';
@ -38,29 +21,29 @@ exitKey
export const mainUi = new UiController(); export const mainUi = new UiController();
mainUi.register( mainUi.register(
new GameUi('book', Book, exitKey), new GameUi('book', UI.Book, exitKey),
new GameUi('toolbox', Toolbox, exitKey), new GameUi('toolbox', UI.Toolbox, exitKey),
new GameUi('equipbox', Equipbox, exitKey), new GameUi('equipbox', UI.Equipbox, exitKey),
new GameUi('settings', Settings, exitKey), new GameUi('settings', UI.Settings, exitKey),
new GameUi('desc', Desc, exitKey), new GameUi('desc', UI.Desc, exitKey),
new GameUi('skill', Skill, exitKey), new GameUi('skill', UI.Skill, exitKey),
new GameUi('skillTree', SkillTree, exitKey), new GameUi('skillTree', UI.SkillTree, exitKey),
new GameUi('fly', Fly, exitKey), new GameUi('fly', UI.Fly, exitKey),
new GameUi('fixedDetail', FixedDetail, exitKey), new GameUi('fixedDetail', UI.FixedDetail, exitKey),
new GameUi('shop', Shop, exitKey), new GameUi('shop', UI.Shop, exitKey),
new GameUi('achievement', Achievement, exitKey), new GameUi('achievement', UI.Achievement, exitKey),
new GameUi('bgm', Bgm, exitKey) new GameUi('bgm', UI.BgmList, exitKey)
// todo: 把游戏主 div 加入到 mainUi 里面 // todo: 把游戏主 div 加入到 mainUi 里面
); );
export const fixedUi = new UiController(true); export const fixedUi = new UiController(true);
fixedUi.register( fixedUi.register(
new GameUi('statusBar', StatusBar), new GameUi('statusBar', UI.StatusBar),
new GameUi('markedEnemy', Mark), new GameUi('markedEnemy', UI.Marked),
new GameUi('fixed', Fixed), new GameUi('fixed', UI.Fixed),
new GameUi('chapter', Chapter), new GameUi('chapter', UI.Chapter),
new GameUi('completeAchi', CompleteAchi), new GameUi('completeAchi', UI.CompleteAchi),
new GameUi('start', Start) new GameUi('start', UI.Start)
); );
hook.once('mounted', () => { hook.once('mounted', () => {
@ -69,9 +52,11 @@ hook.once('mounted', () => {
mainUi.on('start', () => { mainUi.on('start', () => {
ui.style.display = 'flex'; ui.style.display = 'flex';
core.lockControl();
}); });
mainUi.on('end', () => { mainUi.on('end', () => {
ui.style.display = 'none'; ui.style.display = 'none';
core.closePanel();
}); });
fixedUi.on('start', () => { fixedUi.on('start', () => {
fixed.style.display = 'block'; fixed.style.display = 'block';
@ -79,4 +64,7 @@ hook.once('mounted', () => {
fixedUi.on('end', () => { fixedUi.on('end', () => {
fixed.style.display = 'none'; fixed.style.display = 'none';
}); });
// todo: 暂时先这么搞,之后重写加载界面,需要改成先显示加载界面,加载完毕后再打开这个界面
fixedUi.open('start');
}); });

View File

@ -715,10 +715,11 @@ export class DamageEnemy<T extends EnemyIds = EnemyIds> {
start = curr; start = curr;
} }
if (i++ >= 10000) { if (i++ >= 10000) {
throw new Error( console.warn(
`Unexpected endless loop in calculating critical.` + `Unexpected endless loop in calculating critical.` +
`Enemy Id: ${this.id}. Loc: ${this.x},${this.y}. Floor: ${this.floorId}` `Enemy Id: ${this.id}. Loc: ${this.x},${this.y}. Floor: ${this.floorId}`
); );
break;
} }
} }

View File

@ -113,8 +113,10 @@ function getRealStatus(
declare global { declare global {
interface PluginDeclaration { interface PluginDeclaration {
getHeroStatusOf: typeof getHeroStatusOf; hero: {
getHeroStatusOn: typeof getHeroStatusOn; getHeroStatusOf: typeof getHeroStatusOf;
getHeroStatusOn: typeof getHeroStatusOn;
};
} }
} }

View File

@ -227,7 +227,7 @@ export function getSkillConsume(skill) {
export function openTree() { export function openTree() {
if (main.replayChecking) return; if (main.replayChecking) return;
mota.plugin.ui.skillTreeOpened.value = true; mota.ui.main.open('skillTree');
} }
/** /**

View File

@ -11,8 +11,9 @@ export {};
function openItemShop(itemShopId) { function openItemShop(itemShopId) {
if (!core.isReplaying()) { if (!core.isReplaying()) {
core.plugin.openedShopId = itemShopId; mota.ui.main.open('shop', void 0, {
mota.plugin.ui.shopOpened.value = true; shopId: itemShopId
});
} }
} }
@ -24,22 +25,19 @@ export {};
} }
ui.prototype.drawBook = function () { ui.prototype.drawBook = function () {
if (!core.isReplaying()) if (!core.isReplaying()) return mota.ui.main.open('book');
return (mota.plugin.ui.bookOpened.value = true);
}; };
ui.prototype._drawToolbox = function () { ui.prototype._drawToolbox = function () {
if (!core.isReplaying()) if (!core.isReplaying()) return mota.ui.main.open('toolbox');
return (mota.plugin.ui.toolOpened.value = true);
}; };
ui.prototype._drawEquipbox = function () { ui.prototype._drawEquipbox = function () {
if (!core.isReplaying()) if (!core.isReplaying()) return mota.ui.main.open('equipbox');
return (mota.plugin.ui.equipOpened.value = true);
}; };
ui.prototype.drawFly = function () { ui.prototype.drawFly = function () {
if (!core.isReplaying()) return (mota.plugin.ui.flyOpened.value = true); if (!core.isReplaying()) return mota.ui.main.open('fly');
}; };
control.prototype.updateStatusBar_update = function () { control.prototype.updateStatusBar_update = function () {
@ -54,6 +52,7 @@ export {};
updateVueStatusBar(); updateVueStatusBar();
}; };
// todo: 多个状态栏分离与控制
control.prototype.showStatusBar = function () { control.prototype.showStatusBar = function () {
if (main.mode == 'editor') return; if (main.mode == 'editor') return;
core.removeFlag('hideStatusBar'); core.removeFlag('hideStatusBar');
@ -93,7 +92,7 @@ export {};
function openSkill() { function openSkill() {
if (core.isReplaying()) return; if (core.isReplaying()) return;
mota.plugin.ui.skillOpened.value = true; mota.ui.main.open('skill');
} }
core.plugin.gameUi = { core.plugin.gameUi = {

View File

@ -67,7 +67,7 @@ export function getNowStatus(nowEquip?: Equip, onCol: boolean = false) {
{toShow.map(v => { {toShow.map(v => {
let status: string; let status: string;
if (v === 'lv') status = core.getLvName() ?? ''; if (v === 'lv') status = core.getLvName() ?? '';
else status = core.plugin.getHeroStatusOn(v)?.toString(); else status = core.plugin.hero.getHeroStatusOn(v)?.toString();
let add = 0; let add = 0;
if (has(nowEquip)) { if (has(nowEquip)) {

View File

@ -1,126 +1,21 @@
import { sleep } from 'mutate-animate'; import { ref } from 'vue';
import { Component, markRaw, ref, Ref, shallowReactive, watch } from 'vue';
import Book from '../ui/book.vue';
import Toolbox from '../ui/toolbox.vue';
import Equipbox from '../ui/equipbox.vue';
import Settings from '../ui/settings.vue';
import Desc from '../ui/desc.vue';
import Skill from '../ui/skill.vue';
import SkillTree from '../ui/skillTree.vue';
import Fly from '../ui/fly.vue';
import FixedDetail from '../ui/fixedDetail.vue';
import Shop from '../ui/shop.vue';
import Achievement from '../ui/achievement.vue';
import Bgm from '../ui/bgmList.vue';
// todo: 优化开启控制器 // todo: 优化开启控制器
export const bookOpened = ref(false);
export const toolOpened = ref(false);
export const equipOpened = ref(false);
export const showStatusBar = ref(false); export const showStatusBar = ref(false);
export const settingsOpened = ref(false);
export const descOpened = ref(false);
export const skillOpened = ref(false);
export const skillTreeOpened = ref(false);
export const flyOpened = ref(false);
export const showStudiedSkill = ref(false); export const showStudiedSkill = ref(false);
export const fixedDetailOpened = ref(false);
export const shopOpened = ref(false);
export const startOpened = ref(true); export const startOpened = ref(true);
export const achievementOpened = ref(false);
export const bgmOpened = ref(false);
export const transition = ref(true); export const transition = ref(true);
export const noClosePanel = ref(false); export const noClosePanel = ref(false);
export const startAnimationEnded = ref(false); export const startAnimationEnded = ref(false);
let app: HTMLDivElement;
/** ui声明列表 */
const UI_LIST: [Ref<boolean>, Component][] = [
// [bookOpened, Book],
// [toolOpened, Toolbox],
// [equipOpened, Equipbox],
// [settingsOpened, Settings],
// [descOpened, Desc],
// [skillOpened, Skill],
// [skillTreeOpened, SkillTree],
// [flyOpened, Fly],
// [fixedDetailOpened, FixedDetail],
// [shopOpened, Shop],
// [achievementOpened, Achievement],
// [bgmOpened, Bgm]
];
/** ui栈 */
export const uiStack = shallowReactive<Component[]>([]);
export default function init() { export default function init() {
// app = document.getElementById('root') as HTMLDivElement;
// UI_LIST.forEach(([ref, com]) => {
// watch(ref, n => {
// if (n === true) {
// uiStack.push(markRaw(com));
// showApp();
// } else {
// const index = uiStack.findIndex(v => v === com);
// if (index === -1) return;
// if (uiStack.length === 1) {
// hideApp(index);
// } else {
// uiStack.splice(index, 1);
// }
// }
// });
// });
return { return {
uiStack,
transition, transition,
bookOpened,
toolOpened,
equipOpened,
showStatusBar, showStatusBar,
settingsOpened,
descOpened,
skillOpened,
skillTreeOpened,
flyOpened,
showStudiedSkill, showStudiedSkill,
fixedDetailOpened, startAnimationEnded
shopOpened,
startOpened,
startAnimationEnded,
achievementOpened,
bgmOpened
}; };
} }
async function showApp() {
core.lockControl();
if (transition.value) {
app.style.transition = 'all 0.6s linear';
} else {
app.style.transition = 'none';
}
app.style.display = 'flex';
await sleep(50);
app.style.opacity = '1';
}
async function hideApp(index: number) {
if (transition.value) {
app.style.transition = 'all 0.6s linear';
app.style.opacity = '0';
await sleep(600);
} else {
app.style.transition = '';
app.style.opacity = '0';
}
uiStack.splice(index, 1);
app.style.display = 'none';
if (!noClosePanel.value) core.closePanel();
noClosePanel.value = false;
}

48
src/types/plugin.d.ts vendored
View File

@ -168,75 +168,27 @@ interface PluginUtils {
} }
interface PluginUis { interface PluginUis {
/** 定点查看的界面,特殊属性还是临界 */
fixedDetailPanel: 'special' | 'critical';
/** 打开的商店id */
openedShopId: string;
/** ui是否使用渐变 */ /** ui是否使用渐变 */
readonly transition: Ref<boolean>; readonly transition: Ref<boolean>;
/** 手册是否打开 */
readonly bookOpened: Ref<boolean>;
/** 道具栏是否打开 */
readonly toolOpened: Ref<boolean>;
/** 装备栏是否打开 */
readonly equipOpened: Ref<boolean>;
/** 是否显示状态栏 */ /** 是否显示状态栏 */
readonly showStatusBar: Ref<boolean>; readonly showStatusBar: Ref<boolean>;
/** 设置界面是否打开 */
readonly settingsOpened: Ref<boolean>;
/** 是否正在进行章节显示 */ /** 是否正在进行章节显示 */
readonly chapterShowed: Ref<boolean>; readonly chapterShowed: Ref<boolean>;
/** 章节显示的内容 */ /** 章节显示的内容 */
readonly chapterContent: Ref<boolean>; readonly chapterContent: Ref<boolean>;
/** 百科全书是否打开了 */
readonly descOpened: Ref<boolean>;
/** 技能查看界面是否打开 */
readonly skillOpened: Ref<boolean>;
/** 技能树界面是否打开 */
readonly skillTreeOpened: Ref<boolean>;
/** 楼传界面是否打开 */
readonly flyOpened: Ref<boolean>;
/** 是否展示标记的怪物 */ /** 是否展示标记的怪物 */
readonly showMarkedEnemy: Ref<boolean>; readonly showMarkedEnemy: Ref<boolean>;
/** 是否展示已学习的技能 */ /** 是否展示已学习的技能 */
readonly showStudiedSkill: Ref<boolean>; readonly showStudiedSkill: Ref<boolean>;
/** 定点查看是否打开 */
readonly fixedDetailOpened: Ref<boolean>;
/** 是否展示移动鼠标显示怪物信息的盒子 */ /** 是否展示移动鼠标显示怪物信息的盒子 */
readonly showFixed: Ref<boolean>; readonly showFixed: Ref<boolean>;
/** 商店是否打开 */
readonly shopOpened: Ref<boolean>;
/** 开始界面是否打开 */
readonly startOpened: Ref<boolean>;
/** 成就界面是否打开 */
readonly achievementOpened: Ref<boolean>;
/** bgm界面是否打开 */
readonly bgmOpened: Ref<boolean>;
/** ui栈 */
readonly uiStack: Ref<any[]>;
/** /**
* *
* @param chapter * @param chapter

View File

@ -98,7 +98,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed, ref } from 'vue'; import { computed, ref } from 'vue';
import { achievementOpened, noClosePanel } from '../plugin/uiController'; import { noClosePanel } from '../plugin/uiController';
import { LeftOutlined } from '@ant-design/icons-vue'; import { LeftOutlined } from '@ant-design/icons-vue';
import list from '../data/achievement.json'; import list from '../data/achievement.json';
import { import {
@ -109,6 +109,10 @@ import {
import Scroll from '../components/scroll.vue'; import Scroll from '../components/scroll.vue';
import { isMobile } from '../plugin/use'; import { isMobile } from '../plugin/use';
const props = defineProps<{
num: number;
}>();
type AchievementList = typeof list; type AchievementList = typeof list;
type AchievementType = keyof AchievementList; type AchievementType = keyof AchievementList;
@ -173,12 +177,13 @@ function getAllAchievements(type: AchievementType): ResolvedAchievement[] {
} }
function exit() { function exit() {
// ???
try { try {
core.closePanel(); core.closePanel();
} catch { } catch {
noClosePanel.value = true; noClosePanel.value = true;
} }
achievementOpened.value = false; mota.ui.main.close(props.num);
} }
</script> </script>

View File

@ -33,6 +33,10 @@ import Colomn from '../components/colomn.vue';
import bgm from '../data/bgm.json'; import bgm from '../data/bgm.json';
import { splitText } from '../plugin/utils'; import { splitText } from '../plugin/utils';
const props = defineProps<{
num: number;
}>();
interface Bgm { interface Bgm {
img: string; img: string;
area: string; area: string;
@ -51,7 +55,7 @@ const content = computed(() => {
const name = computed(() => list[selected.value]!.name); const name = computed(() => list[selected.value]!.name);
function exit() { function exit() {
mota.plugin.ui.bgmOpened.value = false; mota.ui.main.close(props.num);
} }
function select(id: BgmIds) { function select(id: BgmIds) {

View File

@ -49,6 +49,12 @@ import { KeyCode } from '../plugin/keyCodes';
import { noClosePanel } from '../plugin/uiController'; import { noClosePanel } from '../plugin/uiController';
import { ToShowEnemy, detailInfo } from '../plugin/ui/book'; import { ToShowEnemy, detailInfo } from '../plugin/ui/book';
import { getDetailedEnemy } from '../plugin/ui/fixed'; import { getDetailedEnemy } from '../plugin/ui/fixed';
import { GameUi } from '@/core/main/custom/ui';
const props = defineProps<{
num: number;
ui: GameUi;
}>();
const floorId = const floorId =
// @ts-ignore // @ts-ignore
@ -113,7 +119,7 @@ async function show() {
*/ */
async function exit() { async function exit() {
noClosePanel.value = true; noClosePanel.value = true;
mota.plugin.ui.bookOpened.value = false; mota.ui.main.close(props.num);
if (mota.plugin.ui.transition.value) await sleep(650); if (mota.plugin.ui.transition.value) await sleep(650);
else await sleep(100); else await sleep(100);
if (core.events.recoverEvents(core.status.event.interval)) { if (core.events.recoverEvents(core.status.event.interval)) {

View File

@ -23,12 +23,16 @@ import desc from '../data/desc.json';
import { has, splitText } from '../plugin/utils'; import { has, splitText } from '../plugin/utils';
import Colomn from '../components/colomn.vue'; import Colomn from '../components/colomn.vue';
const props = defineProps<{
num: number;
}>();
type DescKey = keyof typeof desc; type DescKey = keyof typeof desc;
const selected = ref(Object.keys(desc)[0] as DescKey); const selected = ref(Object.keys(desc)[0] as DescKey);
function exit() { function exit() {
mota.plugin.ui.descOpened.value = false; mota.ui.main.close(props.num);
} }
const content = computed(() => { const content = computed(() => {

View File

@ -179,7 +179,15 @@ import {
SortAscendingOutlined, SortAscendingOutlined,
SortDescendingOutlined SortDescendingOutlined
} from '@ant-design/icons-vue'; } from '@ant-design/icons-vue';
import { computed, onMounted, onUnmounted, reactive, ref, watch } from 'vue'; import {
computed,
nextTick,
onMounted,
onUnmounted,
reactive,
ref,
watch
} from 'vue';
import Scroll from '../components/scroll.vue'; import Scroll from '../components/scroll.vue';
import { getAddStatus, getEquips, getNowStatus } from '../plugin/ui/equipbox'; import { getAddStatus, getEquips, getNowStatus } from '../plugin/ui/equipbox';
import BoxAnimate from '../components/boxAnimate.vue'; import BoxAnimate from '../components/boxAnimate.vue';
@ -187,6 +195,12 @@ import { has, keycode, tip, type } from '../plugin/utils';
import { cancelGlobalDrag, isMobile, useDrag } from '../plugin/use'; import { cancelGlobalDrag, isMobile, useDrag } from '../plugin/use';
import { hyper, sleep } from 'mutate-animate'; import { hyper, sleep } from 'mutate-animate';
import { KeyCode } from '../plugin/keyCodes'; import { KeyCode } from '../plugin/keyCodes';
import { GameUi } from '@/core/main/custom/ui';
const props = defineProps<{
num: number;
ui: GameUi;
}>();
const equips = ref(getEquips()); const equips = ref(getEquips());
const col = ref('all'); const col = ref('all');
@ -303,7 +317,7 @@ function changeSort() {
} }
function exit() { function exit() {
mota.plugin.ui.equipOpened.value = false; mota.ui.main.close(props.num);
} }
function clickList(i: number) { function clickList(i: number) {
@ -420,13 +434,11 @@ function dragout(e: Event) {
toEquipType.value = -1; toEquipType.value = -1;
} }
async function toTool() { function toTool() {
const before = mota.plugin.ui.transition.value;
mota.plugin.ui.transition.value = false; mota.plugin.ui.transition.value = false;
mota.ui.main.holdOn();
exit(); exit();
await sleep(50); mota.ui.main.open('toolbox');
mota.plugin.ui.toolOpened.value = true;
mota.plugin.ui.transition.value = before;
} }
function keyup(e: KeyboardEvent) { function keyup(e: KeyboardEvent) {
@ -447,9 +459,10 @@ watch(toShow, n => {
onMounted(async () => { onMounted(async () => {
bind(); bind();
if (mota.plugin.ui.transition.value) await sleep(600); await sleep(50);
else await sleep(50); nextTick(() => {
document.addEventListener('keyup', keyup); document.addEventListener('keyup', keyup);
});
}); });
onUnmounted(() => { onUnmounted(() => {

View File

@ -72,7 +72,7 @@ async function calHeight() {
vw = window.innerWidth; vw = window.innerWidth;
width.value = vh * 0.28; width.value = vh * 0.28;
await new Promise(res => requestAnimationFrame(res)); await new Promise(res => requestAnimationFrame(res));
if (mota.plugin.ui.fixedDetailOpened.value) { if (mota.ui.main.hasName('fixedDetail')) {
showFixed.value = false; showFixed.value = false;
} }
updateMain(); updateMain();

View File

@ -13,7 +13,12 @@ import { getDetailedEnemy, getLocFromMouseLoc } from '../plugin/ui/fixed';
import BookDetail from './bookDetail.vue'; import BookDetail from './bookDetail.vue';
import { detailInfo } from '../plugin/ui/book'; import { detailInfo } from '../plugin/ui/book';
const panel = core.plugin.fixedDetailPanel ?? 'special'; const props = defineProps<{
num: number;
panel?: 'special' | 'critical' | 'target';
}>();
const panel = props.panel ?? 'special';
detailInfo.pos = 0; detailInfo.pos = 0;
@ -30,7 +35,7 @@ if (enemy) {
} }
function close() { function close() {
mota.plugin.ui.fixedDetailOpened.value = false; mota.ui.main.close(props.num);
} }
</script> </script>

View File

@ -97,6 +97,10 @@ import { downloadCanvasImage, keycode, tip } from '../plugin/utils';
import { sleep } from 'mutate-animate'; import { sleep } from 'mutate-animate';
import { KeyCode } from '../plugin/keyCodes'; import { KeyCode } from '../plugin/keyCodes';
const props = defineProps<{
num: number;
}>();
type Loc2 = [number, number, number, number]; type Loc2 = [number, number, number, number];
const area = getArea(); const area = getArea();
@ -147,7 +151,7 @@ let thumbCtx: CanvasRenderingContext2D;
let downloadMode = false; let downloadMode = false;
function exit() { function exit() {
mota.plugin.ui.flyOpened.value = false; mota.ui.main.close(props.num);
} }
const title = computed(() => { const title = computed(() => {

21
src/ui/index.ts Normal file
View File

@ -0,0 +1,21 @@
export { default as Achievement } from './achievement.vue';
export { default as BgmList } from './bgmList.vue';
export { default as Book } from './book.vue';
export { default as BookDetail } from './bookDetail.vue';
export { default as Chapter } from './chapter.vue';
export { default as CompleteAchi } from './completeAchievement.vue';
export { default as Desc } from './desc.vue';
export { default as Equipbox } from './equipbox.vue';
export { default as Fixed } from './fixed.vue';
export { default as FixedDetail } from './fixedDetail.vue';
export { default as Fly } from './fly.vue';
export { default as Marked } from './markedEnemy.vue';
export { default as Settings } from './settings.vue';
export { default as Shop } from './shop.vue';
export { default as Skill } from './skill.vue';
export { default as SkillTree } from './skillTree.vue';
export { default as Start } from './start.vue';
export { default as StatusBar } from './statusBar.vue';
export { default as Studied } from './studied.vue';
export { default as Study } from './study.vue';
export { default as Toolbox } from './toolbox.vue';

View File

@ -94,7 +94,7 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { computed, onMounted, onUnmounted, onUpdated, shallowRef } from 'vue'; import { computed, onMounted, onUnmounted, shallowRef } from 'vue';
import { import {
mainSetting, mainSetting,
MotaSetting, MotaSetting,
@ -107,7 +107,6 @@ import settingText from '../data/settings.json';
import { RightOutlined, LeftOutlined } from '@ant-design/icons-vue'; import { RightOutlined, LeftOutlined } from '@ant-design/icons-vue';
import { keycode, splitText } from '../plugin/utils'; import { keycode, splitText } from '../plugin/utils';
import Scroll from '../components/scroll.vue'; import Scroll from '../components/scroll.vue';
import { settingsOpened } from '../plugin/uiController';
import { isMobile } from '../plugin/use'; import { isMobile } from '../plugin/use';
import { sleep } from 'mutate-animate'; import { sleep } from 'mutate-animate';
import { KeyCode } from '../plugin/keyCodes'; import { KeyCode } from '../plugin/keyCodes';
@ -115,6 +114,7 @@ import { KeyCode } from '../plugin/keyCodes';
const props = defineProps<{ const props = defineProps<{
info?: MotaSetting; info?: MotaSetting;
text?: SettingText; text?: SettingText;
num: number;
}>(); }>();
const setting = props.info ?? mainSetting; const setting = props.info ?? mainSetting;
@ -172,7 +172,7 @@ function changeValue(value: number | boolean) {
} }
function exit() { function exit() {
settingsOpened.value = false; mota.ui.main.close(props.num);
} }
function key(e: KeyboardEvent) { function key(e: KeyboardEvent) {

View File

@ -176,8 +176,13 @@ import BoxAnimate from '../components/boxAnimate.vue';
import { KeyCode } from '../plugin/keyCodes'; import { KeyCode } from '../plugin/keyCodes';
import { sleep } from 'mutate-animate'; import { sleep } from 'mutate-animate';
const id = core.plugin.openedShopId; const props = defineProps<{
const shop = core.status.shops[core.plugin.openedShopId] as ItemShopEvent; num: number;
shopId: string;
}>();
const id = props.shopId;
const shop = core.status.shops[id] as ItemShopEvent;
if (!shop.item) { if (!shop.item) {
throw new TypeError( throw new TypeError(
`Wrong global shop type delivered in opening item shop.` `Wrong global shop type delivered in opening item shop.`
@ -303,7 +308,7 @@ function keydown(e: KeyboardEvent) {
function exit() { function exit() {
if (bought) core.status.route.push('closeShop'); if (bought) core.status.route.push('closeShop');
mota.plugin.ui.shopOpened.value = false; mota.ui.main.close(props.num);
} }
onMounted(async () => { onMounted(async () => {

View File

@ -22,6 +22,10 @@ import skills from '../data/skill.json';
import { has } from '../plugin/utils'; import { has } from '../plugin/utils';
import Column from '../components/colomn.vue'; import Column from '../components/colomn.vue';
const props = defineProps<{
num: number;
}>();
type Skills = keyof typeof skills; type Skills = keyof typeof skills;
const selected = ref<Skills>('none'); const selected = ref<Skills>('none');
@ -60,7 +64,7 @@ const content = computed(() => {
}); });
function exit() { function exit() {
mota.plugin.ui.skillOpened.value = false; mota.ui.main.close(props.num);
} }
</script> </script>

View File

@ -82,6 +82,10 @@ import { isMobile } from '../plugin/use';
import { sleep } from 'mutate-animate'; import { sleep } from 'mutate-animate';
import { KeyCode } from '../plugin/keyCodes'; import { KeyCode } from '../plugin/keyCodes';
const props = defineProps<{
num: number;
}>();
let canvas: HTMLCanvasElement; let canvas: HTMLCanvasElement;
let ctx: CanvasRenderingContext2D; let ctx: CanvasRenderingContext2D;
@ -173,7 +177,7 @@ const level = computed(() => {
}); });
function exit() { function exit() {
mota.plugin.ui.skillTreeOpened.value = false; mota.ui.main.close(props.num);
} }
function resize() { function resize() {

View File

@ -67,7 +67,6 @@ import { sleep } from 'mutate-animate';
import { Matrix4 } from '../plugin/webgl/matrix'; 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 { achievementOpened } from '../plugin/uiController';
import { triggerFullscreen } from '../plugin/utils'; import { triggerFullscreen } from '../plugin/utils';
import { loading } from '../core/loader/load'; import { loading } from '../core/loader/load';
import { isMobile } from '../plugin/use'; import { isMobile } from '../plugin/use';
@ -149,7 +148,7 @@ async function clickStartButton(id: string) {
} }
if (id === 'replay') core.chooseReplayFile(); if (id === 'replay') core.chooseReplayFile();
if (id === 'achievement') { if (id === 'achievement') {
achievementOpened.value = true; mota.ui.main.open('achievement');
} }
} }

View File

@ -118,6 +118,10 @@ import { hyper, sleep } from 'mutate-animate';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import { KeyCode } from '../plugin/keyCodes'; import { KeyCode } from '../plugin/keyCodes';
const props = defineProps<{
num: number;
}>();
type ItemMode = 'tools' | 'constants'; type ItemMode = 'tools' | 'constants';
type ShowItemIds = ItemIdOf<'constants' | 'tools'> | 'none'; type ShowItemIds = ItemIdOf<'constants' | 'tools'> | 'none';
@ -165,7 +169,7 @@ async function select(id: ShowItemIds, nouse: boolean = false) {
} }
function exit() { function exit() {
mota.plugin.ui.toolOpened.value = false; mota.ui.main.close(props.num);
} }
async function use(id: ShowItemIds) { async function use(id: ShowItemIds) {
@ -187,12 +191,9 @@ async function use(id: ShowItemIds) {
} }
async function toEquip() { async function toEquip() {
const before = mota.plugin.ui.transition.value; mota.ui.main.holdOn();
mota.plugin.ui.transition.value = false;
exit(); exit();
await sleep(50); mota.ui.main.open('equipbox');
mota.plugin.ui.equipOpened.value = true;
mota.plugin.ui.transition.value = before;
} }
function keyup(e: KeyboardEvent) { function keyup(e: KeyboardEvent) {