mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-04-11 15:47:06 +08:00
refactor: UI 移入 @motajs/legacy-ui
This commit is contained in:
parent
4aa894a204
commit
693e531639
@ -1 +1,3 @@
|
||||
export * from './keyCodes';
|
||||
|
||||
export * as Render from '@motajs/render';
|
||||
|
0
packages/legacy-client/src/index.ts
Normal file
0
packages/legacy-client/src/index.ts
Normal file
0
packages/legacy-data/src/index.ts
Normal file
0
packages/legacy-data/src/index.ts
Normal file
8
packages/legacy-ui/package.json
Normal file
8
packages/legacy-ui/package.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "@motajs/legacy-ui",
|
||||
"dependencies": {
|
||||
"@motajs/render": "workspace:*",
|
||||
"@motajs/common": "workspace:*",
|
||||
"@motajs/client": "workspace:*"
|
||||
}
|
||||
}
|
@ -49,8 +49,8 @@
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, onUnmounted, onUpdated, ref, watch } from 'vue';
|
||||
import { ArrowsAltOutlined, DragOutlined } from '@ant-design/icons-vue';
|
||||
import { isMobile, useDrag, cancelGlobalDrag } from '../plugin/use';
|
||||
import { has, requireUniqueSymbol } from '../plugin/utils';
|
||||
import { isMobile, useDrag, cancelGlobalDrag } from '../use';
|
||||
import { has, requireUniqueSymbol } from '../utils';
|
||||
|
||||
// todo: 重写
|
||||
|
@ -8,8 +8,8 @@
|
||||
|
||||
<script lang="tsx" setup>
|
||||
import { onMounted, onUnmounted, onUpdated } from 'vue';
|
||||
import { addAnimate, removeAnimate } from '../plugin/animateController';
|
||||
import { has, requireUniqueSymbol } from '../plugin/utils';
|
||||
import { addAnimate, removeAnimate } from '../animateController';
|
||||
import { has, requireUniqueSymbol } from '../utils';
|
||||
|
||||
const id = requireUniqueSymbol().toFixed(0);
|
||||
|
@ -23,11 +23,11 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, onUnmounted, onUpdated, ref } from 'vue';
|
||||
import { onMounted, onUpdated } from 'vue';
|
||||
import { LeftOutlined } from '@ant-design/icons-vue';
|
||||
import Scroll from './scroll.vue';
|
||||
import { isMobile } from '../plugin/use';
|
||||
import { has, requireUniqueSymbol } from '../plugin/utils';
|
||||
import { isMobile } from '../use';
|
||||
import { has, requireUniqueSymbol } from '../utils';
|
||||
|
||||
const emits = defineEmits<{
|
||||
(e: 'close'): void;
|
@ -4,7 +4,6 @@
|
||||
@click="select"
|
||||
@mousemove="enter"
|
||||
:selected="selected"
|
||||
:style="style"
|
||||
>
|
||||
<div class="info">
|
||||
<div class="leftbar">
|
||||
@ -20,9 +19,7 @@
|
||||
v-if="has(enemy.special) && enemy.special.length > 0"
|
||||
>
|
||||
<template v-for="(text, i) in enemy.showSpecial">
|
||||
<span
|
||||
v-if="i < (isMobile ? 1 : 2)"
|
||||
:style="{ color: text[2] }"
|
||||
<span v-if="i < (isMobile ? 1 : 2)"
|
||||
> {{ text[0] }} </span
|
||||
>
|
||||
<span v-if="i === (isMobile ? 1 : 2)">...</span>
|
||||
@ -113,11 +110,10 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { has } from '../plugin/utils';
|
||||
import { has } from '../utils';
|
||||
import BoxAnimate from '../components/boxAnimate.vue';
|
||||
import { isMobile } from '../plugin/use';
|
||||
import { ToShowEnemy } from '../plugin/ui/book';
|
||||
import border from '@/data/enemyBorder.json';
|
||||
import { isMobile } from '../use';
|
||||
import { ToShowEnemy } from '../tools/book';
|
||||
|
||||
const props = defineProps<{
|
||||
enemy: ToShowEnemy;
|
||||
@ -133,8 +129,6 @@ const core = window.core;
|
||||
|
||||
const w = window.innerWidth * 0.032;
|
||||
|
||||
const style = border[props.enemy.enemy.enemy.id as keyof typeof border] ?? {};
|
||||
|
||||
/**
|
||||
* 选择这个怪物时
|
||||
*/
|
@ -4,10 +4,9 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, onUnmounted } from 'vue';
|
||||
import { requireUniqueSymbol } from '../plugin/utils';
|
||||
import { MinimapDrawer, getArea } from '../plugin/ui/fly';
|
||||
import { hook } from '@/game/game';
|
||||
import { useDrag, useWheel } from '@/plugin/use';
|
||||
import { requireUniqueSymbol } from '../utils';
|
||||
import { MinimapDrawer, getArea } from '../tools/fly';
|
||||
import { useDrag, useWheel } from '../use';
|
||||
import { debounce } from 'lodash-es';
|
||||
import { mainSetting } from '@/core/main/setting';
|
||||
|
||||
@ -135,6 +134,7 @@ onMounted(() => {
|
||||
}
|
||||
drawer.drawMap();
|
||||
|
||||
const hook = Mota.require('var', 'hook');
|
||||
hook.on('afterChangeFloor', onChange);
|
||||
hook.on('afterBattle', afterBattle);
|
||||
|
@ -12,8 +12,8 @@
|
||||
<script lang="ts" setup>
|
||||
import { sleep } from 'mutate-animate';
|
||||
import { onMounted, onUnmounted, onUpdated } from 'vue';
|
||||
import { cancelGlobalDrag, useDrag, useWheel } from '../plugin/use';
|
||||
import { requireUniqueSymbol } from '@/plugin/utils';
|
||||
import { cancelGlobalDrag, useDrag, useWheel } from '../use';
|
||||
import { requireUniqueSymbol } from '../utils';
|
||||
|
||||
let main: HTMLDivElement;
|
||||
|
88
packages/legacy-ui/src/data/achievement.json
Normal file
88
packages/legacy-ui/src/data/achievement.json
Normal file
@ -0,0 +1,88 @@
|
||||
{
|
||||
"normal": [
|
||||
{
|
||||
"name": "虚惊一场",
|
||||
"text": [
|
||||
"打完山洞门口的兽人后只剩一滴血"
|
||||
],
|
||||
"point": 30
|
||||
},
|
||||
{
|
||||
"name": "真能刷",
|
||||
"text": [
|
||||
"勇气之路的刷血怪刷到 <span style=\"color: gold\">15w</span> 以上的血"
|
||||
],
|
||||
"point": 30
|
||||
}
|
||||
],
|
||||
"challenge": [
|
||||
{
|
||||
"name": "逃出生天",
|
||||
"text": [
|
||||
"通过山路追逐战的困难难度"
|
||||
],
|
||||
"point": 20
|
||||
},
|
||||
{
|
||||
"name": "冰与火之舞",
|
||||
"text": [
|
||||
"完成第二章音游特殊战的困难难度"
|
||||
],
|
||||
"point": 50
|
||||
}
|
||||
],
|
||||
"explore": [
|
||||
{
|
||||
"name": "勇气巅峰",
|
||||
"text": [
|
||||
"第一章完成度达到100%"
|
||||
],
|
||||
"progress": "${Mota.Plugin.require('completion_r').getChapterCompletion(1)} / 100",
|
||||
"percent": true,
|
||||
"point": 50
|
||||
},
|
||||
{
|
||||
"name": "你是怎么办到的?!",
|
||||
"text": [
|
||||
"与山路上的若干个神秘木牌对话"
|
||||
],
|
||||
"progress": "${core.getLocalStorage('mountSign', 0)} / 5",
|
||||
"hide": "该探索成就需要你自己探索如何达成",
|
||||
"point": 25
|
||||
},
|
||||
{
|
||||
"name": "智慧之心",
|
||||
"text": [
|
||||
"第二章完成度达到100%"
|
||||
],
|
||||
"progress": "${Mota.Plugin.require('completion_r').getChapterCompletion(2)} / 100",
|
||||
"percent": true,
|
||||
"point": 50
|
||||
},
|
||||
{
|
||||
"name": "源头?",
|
||||
"text": [
|
||||
"在冰封雪原第一个山洞的水源处使用跳跃技能,并向前一步触发剧情"
|
||||
],
|
||||
"hide": "该探索成就需要你自己探索如何达成",
|
||||
"point": 30
|
||||
},
|
||||
{
|
||||
"name": "学坏了",
|
||||
"text": [
|
||||
"学习电摇嘲讽技能"
|
||||
],
|
||||
"hide": "该探索成就需要你自己探索如何达成",
|
||||
"point": 20
|
||||
},
|
||||
{
|
||||
"name": "满腹经纶",
|
||||
"text": [
|
||||
"把第二章中所有能学习的技能都学一遍"
|
||||
],
|
||||
"hide": "该探索成就需要你自己探索如何达成",
|
||||
"progress": "",
|
||||
"point": 50
|
||||
}
|
||||
]
|
||||
}
|
563
packages/legacy-ui/src/data/desc.json
Normal file
563
packages/legacy-ui/src/data/desc.json
Normal file
@ -0,0 +1,563 @@
|
||||
{
|
||||
"tip": {
|
||||
"text": "注意事项",
|
||||
"condition": "true",
|
||||
"desc": [
|
||||
"这里显示本塔中需要注意的事项。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"1. <span style=\"color: yellow; font-weight: 700\">",
|
||||
"本百科全书字数很多,可以选择性地阅读。</span>不过本条目最好可以全部阅读一遍。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"2. 本百科全书的内容会<span style=\"color: gold\">随着游戏的推进而增加新内容</span>,",
|
||||
"同时每次增加新内容时都会有提示。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"3. <span style=\"color: gold\">背包中的系统设置同样非常重要,有些问题可以在那里找到原因</span>。",
|
||||
"例如当你获得技能时可能会发现开启不了技能,",
|
||||
"就是因为你打开了<span style=\"color: gold\">自动切换技能</span>的功能,在系统设置里面有说。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"4. <span style=\"color: yellow; font-weight: 700\">重要!!!</span>本塔没有考虑录像的二次播放性,",
|
||||
"这意味着如果你从头播放一个录像,播放完成后继续游玩,提交成绩后不能保证绿录像,请谨慎考虑。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"5. 本塔中<span style=\"color: gold\">几乎所有 ui 都可以纵向滚动</span>,如果发现显示不全,",
|
||||
"可以尝试上下拖动,就像浏览网页一样。电脑端还可以使用滚轮上下滚动。",
|
||||
"大部分可以纵向滚动的 ui 都会在右方有一个滚动条,也可以拖动它进行滚动,例如本百科全书的条目列表和",
|
||||
"条目说明都是可以通过上述方式滚动的。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"6. 本塔主要面向电脑端设计,",
|
||||
"<span style=\"color: gold\">建议使用电脑游玩以获得更好的游戏体验,同时使用约16:9的比例游玩更加合适",
|
||||
"</span>。但是手机依然可以游玩本塔,",
|
||||
"但部分操作可能不是很方便,ui 也可能不是很美观,不过依然可以完整体验本游戏。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"7. 对于手机端,可以点击<span style=\"color: gold\">右下角的难度文字</span>来切换工具栏至数字键。",
|
||||
"这样,你可以更加方便地进行使用技能等操作。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"8. 本塔中几乎所有 ui 在打开时都会有一个0.6s的动画,如果不想要,可以在开头捡的系统设置里面关闭(默认关闭)。",
|
||||
"同时,几乎所有 ui 的退出按钮都在左上角。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"9. 地图上显示的怪物临界有可能不准,当其与折线图有差异时,<span style=\"color: gold\">请以折线图为准</span>。"
|
||||
]
|
||||
},
|
||||
"about": {
|
||||
"text": "关于游戏",
|
||||
"condition": "true",
|
||||
"desc": [
|
||||
"使用样板:Vite 魔塔样板",
|
||||
"<br>",
|
||||
"样板版本:V2.10.0",
|
||||
"<br>",
|
||||
"游戏版本:V1.0.0-alpha",
|
||||
"<br>",
|
||||
"游戏作者:古祠",
|
||||
"<br>",
|
||||
"游戏开源地址:<a href=\"https://github.com/unanmed/HumanBreak\" target=\"_blank\">",
|
||||
"https://github.com/unanmed/HumanBreak</a>",
|
||||
"<br>",
|
||||
"本塔遵循MIT开源协议。<a href=\"LICENSE\" target=\"_blank\">查看开源协议</a>",
|
||||
"<br>",
|
||||
"音乐来源:网易云音乐等",
|
||||
"<br>",
|
||||
"素材来源:大素材库、爱给网、网站素材库等",
|
||||
"<br>",
|
||||
"<span style=\"color: gold\">特别说明:素材与音乐均来自网络,不得用于商业用途,仅用于参考与学习</span>",
|
||||
"<br>",
|
||||
"特别鸣谢(排名不分先后):",
|
||||
"<br>",
|
||||
"1. 无名甲烷菌(提供部分特殊属性与机制想法)",
|
||||
"<br>",
|
||||
"测试(排名不分先后):",
|
||||
"<br>",
|
||||
"1. 永葆一颗童心",
|
||||
"<br>",
|
||||
"2. 影法师",
|
||||
"<br>",
|
||||
"3. 夜战天明889",
|
||||
"<br>",
|
||||
"4. 霸道的老鼠"
|
||||
]
|
||||
},
|
||||
"tutorial": {
|
||||
"text": "新手教程",
|
||||
"condition": "true",
|
||||
"desc": [
|
||||
"本条目是魔塔游戏的新手教程,如果对魔塔有一定的了解,可以直接忽略。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"魔塔是一种固定数值rpg游戏,在打怪的时候,遵循<span style=\"color: gold\">我打你一下,你打我一下</span>",
|
||||
"的原则,造成的伤害是己方攻击减去对方防御,最后怪物的伤害便是你在战斗中失去的生命值。当然,为了游戏体验,",
|
||||
"战斗过程会被省略。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"宝石可以增加你的属性,在大部分魔塔中,红宝石增加攻击,蓝宝石增加防御,本塔也不例外。血瓶可以增加你的生命值。",
|
||||
"一般情况下,拾取宝物的优先级是<span style=\"color: gold\">红宝石 > 蓝宝石 > 血瓶</span>,",
|
||||
"但部分情况可能不是这样,这需要你自己的游玩经验等。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"本塔还拥有升级机制,升级时能够给你增加大量的属性,因此,一般情况下当你接近升级时,需要尽快打怪升级。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"然后是门。在魔塔中,很多门都不是必开的门,它们的作用一般是可以躲开怪物拿宝石,或者门里面有血瓶等。",
|
||||
"当你血量足够时,这些门可以不用开,不然可能会有必开的门无法开启导致卡关。对于钥匙,每种颜色的钥匙开对应颜色的门,",
|
||||
"价值是<span style=\"color: gold\">红 > 蓝 > 黄</span>。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"为了更加方便,本塔增加了宝石血瓶显示数据的功能,这样你可以清晰地知道每个宝石增加了多少属性。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"下面是勇士基础属性的说明:",
|
||||
"<br>",
|
||||
"<span style=\"color: lightgreen\">1. 生命值</span>:",
|
||||
"勇士的血量,当它归零时,游戏结束",
|
||||
"<br>",
|
||||
"<span style=\"color: lightcoral\">2. 攻击</span>:",
|
||||
"勇士的攻击,攻击越高,每回合对怪物造成的伤害越高",
|
||||
"<br>",
|
||||
"<span style=\"color: lightblue\">3. 防御</span>:",
|
||||
"勇士的防御,防御越高,怪物每回合对你造成的伤害越低",
|
||||
"<br>",
|
||||
"<span style=\"color: green\">4. 经验</span>:",
|
||||
"勇士的经验,到达一定值后会升级。本塔在状态栏中显示为距离升级剩余的经验",
|
||||
"<br>",
|
||||
"<span style=\"color: gold\">5. 金币</span>:",
|
||||
"勇士的金币,可以用于购买物品。本塔中在进入第二章后会有用",
|
||||
"<br>",
|
||||
"<span style=\"color: lightgreen\">6. 护盾</span>:",
|
||||
"勇士的护盾,用处是能够在战后减少同等数值的伤害,在本塔中可以使伤害变为负值。本塔中,在点开无上之盾技能后,",
|
||||
"智慧会充当护盾。更多信息可以查看“勇士属性”条目。"
|
||||
]
|
||||
},
|
||||
"noun": {
|
||||
"text": "名词解释",
|
||||
"condition": "true",
|
||||
"desc": [
|
||||
"本条目会解释诸如临界等魔塔术语,对魔塔有一定了解的可以直接忽略。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"<span style=\"color: lightcoral\">1. 临界</span>:",
|
||||
"在魔塔中,临界是一个非常重要的东西。首先,我们很容易可以得到,吃攻击时只有当减少了战斗回合数时怪物的伤害会减少,",
|
||||
"那么,吃攻击时怪物的减伤是不连续的。而<span style=\"color: gold\">距离下一次减少怪物的伤害需要加的攻击的量</span>",
|
||||
"便是临界。当我们吃一个攻击恰好使怪物伤害减少时,称为“踩临界”。一般情况下,踩临界的减伤要比吃防御要高,",
|
||||
"因此,当能踩到临界时,我们应当先踩临界,再吃防御。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"<span style=\"color: lightblue\">2. 加防</span>:",
|
||||
"加防指的是加防对怪物的减伤。在本塔中,会以“n防”的形式显示在怪物手册或其他地方。在本塔中,一般你不需要刻意计算",
|
||||
"临界与加防减伤,你可以在怪物手册中<span style=\"color: gold\">查看减伤折线图</span>,",
|
||||
"更多信息请查看“怪物手册”条目。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"<span style=\"color: gold\">3. 咸鱼</span>:",
|
||||
"一般来讲,开不必开的门,或者使用不必使用的道具被称为咸鱼,或者是咸门,咸道具。一般情况下,说“咸”便是指咸鱼。",
|
||||
"一般情况下,门后面有宝石且无法通过其他方式进入的都是必开门,而只有血瓶的都是咸鱼门。"
|
||||
]
|
||||
},
|
||||
"shortcut": {
|
||||
"text": "快捷键",
|
||||
"condition": "true",
|
||||
"desc": [
|
||||
"这里包含本塔中所有的快捷键。对于手机端,可以点击工具栏的难度的位置切换工具栏至数字键。",
|
||||
"下面会分为样板快捷键和本塔快捷键两类分别说明。可以ctrl+F进行搜索快捷键的功能。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"下面是样板中的所有快捷键:",
|
||||
"<br>",
|
||||
"<span style=\"color: gold\">X</span>:打开怪物手册",
|
||||
"<br>",
|
||||
"<span style=\"color: gold\">S</span>:打开存档界面",
|
||||
"<br>",
|
||||
"<span style=\"color: gold\">D</span>:打开读档界面",
|
||||
"<br>",
|
||||
"<span style=\"color: gold\">A或5</span>:读取自动存档",
|
||||
"<br>",
|
||||
"<span style=\"color: gold\">W或6</span>:撤销读取的自动存档",
|
||||
"<br>",
|
||||
"<span style=\"color: gold\">Q</span>:打开装备栏",
|
||||
"<br>",
|
||||
"<span style=\"color: gold\">T</span>:打开道具栏",
|
||||
"<br>",
|
||||
"<span style=\"color: gold\">G</span>:打开楼层传送器",
|
||||
"<br>",
|
||||
"<span style=\"color: gold\">Z或单击勇士</span>:勇士转向",
|
||||
"<br>",
|
||||
"<span style=\"color: gold\">空格或双击勇士或7</span>:轻按(拾取勇士周围的宝物但不移动勇士)",
|
||||
"<br>",
|
||||
"<span style=\"color: gold\">Esc</span>:打开游戏菜单",
|
||||
"<br>",
|
||||
"<span style=\"color: gold\">R</span>:打开录像回放菜单",
|
||||
"<br>",
|
||||
"<span style=\"color: gold\">N</span>:询问是否返回游戏主菜单",
|
||||
"<br>",
|
||||
"<span style=\"color: gold\">V</span>:打开快捷商店",
|
||||
"<br>",
|
||||
"<span style=\"color: gold\">B</span>:打开数据统计界面",
|
||||
"<br>",
|
||||
"<span style=\"color: gold\">Alt + 数字键</span>:快速换装",
|
||||
"<br>",
|
||||
"<span style=\"color: gold\">PgUp或PgDn</span>:浏览地图",
|
||||
"<br>",
|
||||
"<span style=\"color: gold\">P</span>:打开评论区",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"下面是本塔中新增的快捷键(不包括技能,技能快捷键请在查看技能界面中查看):",
|
||||
"<br>",
|
||||
"<span style=\"color: gold\">M</span>:快速标记怪物",
|
||||
"<br>",
|
||||
"<span style=\"color: gold\">J</span>:打开技能树",
|
||||
"<br>",
|
||||
"<span style=\"color: gold\">H</span>:打开百科全书",
|
||||
"<br>",
|
||||
"<span style=\"color: gold\">E</span>:查看鼠标位置怪物的特殊属性信息",
|
||||
"<br>",
|
||||
"<span style=\"color: gold\">C</span>:查看鼠标位置怪物的详细临界信息"
|
||||
]
|
||||
},
|
||||
"extraAttr": {
|
||||
"text": "勇士属性",
|
||||
"condition": "true",
|
||||
"desc": [
|
||||
"这里只对本塔中新增的勇士属性进行说明。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"<span style=\"color: lightblue\">1. 智慧</span>:",
|
||||
"智慧是该塔的核心属性之一。智慧可用于智慧加点,该功能会在进入第一章后开启。使用智慧可以点技能树。",
|
||||
"除此之外,智慧也有其它功能。例如点开无上之盾技能后智慧还可以充当护盾,第二章点开学习技能后可以使用智慧学习怪物技能等。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"<span style=\"color: lightgreen\">2. 生命回复</span>:",
|
||||
"生命回复指的是勇士每回合回复的生命值。当与怪物战斗时,勇士每回合都会回复对应量的生命值。因此,当吃攻击时,",
|
||||
"与怪物战斗的回合数可能会减少,导致生命回复的总回复量减少。不过大部分情况下不需要在意这一点,",
|
||||
"减少一回合并不会对吸的血造成很大的影响,除了一些特殊情况。",
|
||||
"该项会显示在状态栏的生命值右方偏下的位置。该项不会超过勇士防御的十分之一,如果真实值溢出,那么多余部分会忽略,",
|
||||
"当防御提高时,其值会一同改变",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"<span style=\"color: lightcoral\">3. 额外攻击</span>:",
|
||||
"额外攻击指的是勇士每回合的额外造成的伤害。一般情况下,当勇士破了怪物的防御时,该项便会起作用。",
|
||||
"额外攻击相当于魔攻,无法通过一般方式减免。当勇士攻击怪物时,每回合都会附加对应量的伤害,对坚固怪同样有效。",
|
||||
"额外攻击会显示在状态栏的攻击右方偏下的位置。"
|
||||
]
|
||||
},
|
||||
"statusBar": {
|
||||
"text": "状态栏",
|
||||
"condition": "true",
|
||||
"desc": [
|
||||
"在本塔中,状态栏与游戏画面是分开的。<span style=\"color: gold\">你可以自由拖动状态栏,也可以修改其大小</span>。",
|
||||
"具体方法如下:点击一下状态栏之后,左上角的拖拽图标会放大,此时你可以按住它拖动状态栏。",
|
||||
"你可以直接将鼠标放到状态栏的边框上,然后直接拖动以改变状态栏的大小。手机端可以先点击一下状态栏使边框",
|
||||
"变宽,然后拖动。电脑端点击状态栏也可以使边框变宽。如果你想折叠状态栏,完全可以拖动状态栏的下边框,",
|
||||
"然后直接拖动至上方,这时状态栏便会变成一条线,相当于折叠了状态栏",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"<span style=\"color: gold\">状态栏可以纵向滚动</span>,",
|
||||
"如果你发现状态栏显示不全,可以尝试拉大状态栏,或者纵向拖动状态栏,就像网页上下滚动一样。",
|
||||
"电脑端还可以使用滚轮上下滚动。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"如果你觉得状态栏有些碍事,你完全可以将其缩小,或者把它放到不碍事的地方。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"状态栏上面可能会有按钮,你可以直接点击。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"对状态栏布局的说明。",
|
||||
"<br>",
|
||||
"本塔的状态栏的布局较为灵活。它是横向的布局,在状态栏较宽时可以看到,属性会横向依次显示。按照显示顺序,",
|
||||
"状态栏显示项依次为:",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"1. <span style=\"color: gold\">楼层名</span>,点击后进入浏览地图界面",
|
||||
"<br>",
|
||||
"2. <span style=\"color: gold\">勇士等级</span>",
|
||||
"<br>",
|
||||
"3. <span style=\"color: gold\">当前开启的技能</span>",
|
||||
"<br>",
|
||||
"4. <span style=\"color: lightgreen\">当前勇士生命值</span>,右方偏下为每回合回复的生命值",
|
||||
",当点开治愈之泉技能时,右方偏上会显示距离增加生命回复剩余血瓶数",
|
||||
"<br>",
|
||||
"5. <span style=\"color: lightcoral\">当前勇士的攻击</span>,右方偏下为勇士的额外攻击",
|
||||
"<br>",
|
||||
"6. <span style=\"color: lightblue\">当前勇士的防御</span>,当有魔法防御时,右方偏下为勇士的魔法防御",
|
||||
"<br>",
|
||||
"7. <span style=\"color: lightgreen\">当前勇士的智慧</span>,可以用于智慧加点等",
|
||||
"<br>",
|
||||
"8. <span style=\"color: gold\">当前勇士的金币</span>",
|
||||
"<br>",
|
||||
"9. <span style=\"color: lightgreen\">当前勇士距离升级剩余经验数</span>",
|
||||
"<br>",
|
||||
"10. <span style=\"color: gold\">三色钥匙</span>",
|
||||
"<br>",
|
||||
"11. <span style=\"color: gold\">打开技能树</span>(进入第一章后开启)",
|
||||
"<br>",
|
||||
"12. <span style=\"color: gold\">查看勇士的技能</span>(进入第一章后开启)"
|
||||
]
|
||||
},
|
||||
"markEnemy": {
|
||||
"text": "标记怪物",
|
||||
"condition": "true",
|
||||
"desc": [
|
||||
"标记怪物可以使你能够更加方便地了解一个怪物的情况。",
|
||||
"<br>",
|
||||
"你可以通过以下两种方式标记怪物:",
|
||||
"<br>",
|
||||
"1. 打开怪物手册,选中怪物,进入怪物更多信息栏,点击标记怪物。",
|
||||
"<br>",
|
||||
"2. 将鼠标移动到你想要标记的怪物上面,<span style=\"color: gold\">",
|
||||
"按下M键</span>,即可标记怪物,注意浏览地图中不能用该方式标记。",
|
||||
"手机端暂时没有快速标记怪物的方式。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"<span style=\"color: gold\">当一个怪物被标记后,怪物会有以下行为</span>:",
|
||||
"<br>",
|
||||
"1. 当勇士恰好能打败怪物时,会进行提示",
|
||||
"<br>",
|
||||
"2. 当怪物的伤害恰好低于勇士生命值的2/3或1/3时,会进行提示",
|
||||
"<br>",
|
||||
"3. 当勇士恰好踩到怪物的临界时,会进行提示",
|
||||
"<br>",
|
||||
"4. 当怪物零伤时,会进行提示",
|
||||
"<br>",
|
||||
"5. 被标记的怪物会出现类似于状态栏的盒子,可以随意拖动和改变大小。你也可以选择关闭这个盒子,",
|
||||
"被关闭后可以通过重新标记来打开。这个盒子会显示标记的怪物的临界与伤害信息等,与状态栏一样,可以纵向滚动。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"这个功能可以用于标记boss或者较强的挡路怪,当这些怪能够攻击时你可以直接收到信息,不需要再时刻费心注意怪物的伤害。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"<span style=\"color: gold\">注意,标记的怪物是不计入存档的,同时标记的怪物只在本次游戏中有效,刷新页面后便会消失。</span>"
|
||||
]
|
||||
},
|
||||
"book": {
|
||||
"text": "怪物手册",
|
||||
"condition": "true",
|
||||
"desc": [
|
||||
"本塔的怪物手册功能很多,下面一一介绍。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"首先,你可以按X打开怪物手册。除此之外,将鼠标移动到怪物上也可以定点查看怪物的粗略信息。",
|
||||
"将鼠标移动到一个怪物上,按下<span style=\"color: gold\">",
|
||||
"E键</span>,可以查看该怪物的特殊属性信息。按下<span style=\"color: gold\">",
|
||||
"C键</span>,可以查看该怪物的详细临界信息。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"怪物手册打开的时候有一个0.6秒的动画,如果不想要可以在开头捡的系统设置里面关闭(默认关闭)。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"打开怪物手册后,怪物手册的布局与样板自带的类似。与样板不同的是,这里的怪物手册不再是翻页式结构。",
|
||||
"<span style=\"color: gold\">这里的怪物手册是滚动式结构</span>,",
|
||||
"你可以像浏览网页一样,用手指或鼠标上下滚动或者拖动右边的滚动条,电脑端还可以使用滚轮。",
|
||||
"对于电脑端,还可以使用键盘操作。上和下可以上下选择怪物,左和右可以向上或向下移动5个怪物。这些操作与样板都类似。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"点击一个怪物或者按下回车空格后,将进入怪物详细信息界面。这个界面分为多个栏,分别是特殊属性栏,详细临界栏,更多信息栏。",
|
||||
"进入怪物详细信息后默认在特殊属性栏,该栏可以查看怪物的特殊属性。",
|
||||
"注意特殊属性依然可以纵向滚动。在特殊属性下方,",
|
||||
"是怪物的临界表,可以粗略地查看怪物的临界信息。在下方,你可以点击详细临界信息进入详细临界栏。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"在详细临界栏中,怪物的伤害会以<span style=\"color: gold\">可视化折线图</span>的方式显示出来,",
|
||||
"从而你可以更为清晰地看出怪物减伤趋势。",
|
||||
"除了查看怪物伤害曲线,你还可以规划宝石。每个折线图下方都有一个滑动条,你可以拖动来模拟吃宝石。",
|
||||
"注意,拖动时,滑动条左边会显示当前的加攻或加防次数,这个数值指的是在勇士所在地图中需要吃的最弱的宝石数量。",
|
||||
"例如,当前勇士所在地图中最弱的宝石加2点攻击,加攻次数为3,那么勇士的攻击增加量就为6。",
|
||||
"勇士增加的攻击数值也会在下方显示。当加攻次数和加防次数改变时,折线图也会变化。",
|
||||
"当前状态下怪物的伤害以及减伤总量也会在下方显示。<span style=\"color: gold\">",
|
||||
"注意在此栏中无法通过点击屏幕回到怪物手册界面,更多信息请查看最后一段</span>。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"在特殊属性栏,点击下方的怪物更多信息可以进入更多信息栏。此栏中,你可以查看怪物描述。但这不是这一栏的核心功能。",
|
||||
"这一栏的核心功能是标记怪物。被标记的怪物会有一些非常方便的行为,这些行为可以在“",
|
||||
"<span style=\"color: gold\">标记怪物</span>”条目中查看。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"注意,在怪物详细信息中,除详细临界栏外均可以通过点击屏幕返回到怪物手册界面。",
|
||||
"如果你是电脑端,在任意栏目中<span style=\"color: gold\">按下X键</span>会退出怪物手册,返回游戏,",
|
||||
"<span style=\"color: gold\">按下回车(Enter)键</span>会回到怪物手册界面。"
|
||||
]
|
||||
},
|
||||
"fly": {
|
||||
"text": "楼层传送器",
|
||||
"condition": "true",
|
||||
"desc": [
|
||||
"楼传界面打开时会有一个0.6秒的动画,如果不想要可以在开头捡的系统设置里面关闭。(默认关闭)",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"本塔的楼层传送器是一个集<span style=\"color: gold\">分区、小地图、楼层传送、浏览地图</span>于一体的多功能楼传。",
|
||||
"<a href=\"https://unanmed.github.io/HumanBreak/maps/index.html\" target=\"_blank\">你也可以点击这里</a>查看所有区域的缩略图。",
|
||||
"下面是楼传的具体说明:",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"首先,对于电脑端,最左侧显示区域信息,手机端则在上方的左侧。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"然后,区域的右侧是小地图栏,这一栏会显示楼层的平面结构。你可以拖动,也可以使用滚轮或者双指放缩,当放缩到一定大小时,",
|
||||
"会显示地图的缩略图。直接点击地图也可以选中地图,再次点击会传送至目标地图。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"对于电脑端,最右侧是当前选中的地图的缩略图,手机则在下方,点击缩略图也可以传送。缩略图的下方是当前选中的地图名,",
|
||||
"左右各有两个按钮,表示后退10层、后退1层、前进1层、前进10层,与样板的楼传的按钮功能类似,对于小地图无法显示的单层,",
|
||||
"可以使用该功能到达。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"最下方是设置按钮,可以切换无边框模式,电脑端还可以切换传统按键模式,传统按键模式下按键遵循样板的楼传按键方式。",
|
||||
"对于非传统模式,<span style=\"color: gold\">上下左右</span>可以移动地图,",
|
||||
"<span style=\"color: gold\">PageUp和PageDown</span>可以前进1层或后退1层。"
|
||||
]
|
||||
},
|
||||
"tools": {
|
||||
"text": "道具栏与装备栏",
|
||||
"condition": "true",
|
||||
"desc": [
|
||||
"道具栏与装备栏打开时会有一个0.6秒的动画,如果不想要可以在开头捡的系统设置里面关闭。(默认关闭)",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"本塔的道具栏没有特别之处,这里不需要说明。主要是装备栏。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"本塔的装备栏手机和电脑端不同,电脑端比手机端多了一个勇士属性的显示。在装备栏的装备列表栏,",
|
||||
"<span style=\"color: gold\">上方有两个选择框与一个排序方式的选项</span>。",
|
||||
"这三个可以筛选你拥有的装备并进行排序,从而让你能够更清楚地知道哪个装备更强。",
|
||||
"第一个选择框可以筛选装备增加的属性,如果装备不增加选择的属性,那么会不显示。第二个选择框可以筛选增加的属性的方式,",
|
||||
"有数值增加和百分比增加两种。在这个选择框右边有一个图标,这个图标可以改变武器的排序方式,有升序和降序两种,默认为升序。",
|
||||
"例如,你拥有两个装备,分别增加10攻击和20攻击,三者你分别选择了攻击,数值,升序,那么增加10攻击的装备会排在上面,",
|
||||
"而增加20攻击的装备会排在下面。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"对于电脑端,如果你想装装备,<span style=\"color: gold\">可以直接拖动装备至装备孔</span>,",
|
||||
"也可以选中装备后再次点击。<span style=\"color: gold\">手机端暂时无法拖动装备</span>。当选中一个装备后,",
|
||||
"电脑端和手机端均会显示装备增加或减少的属性,注意有的装备可能<span style=\"color: gold\">不增加属性但是有特殊功能</span>。",
|
||||
"对于电脑端,还会直接在勇士属性栏显示增加或减少的属性。"
|
||||
]
|
||||
},
|
||||
"achievement": {
|
||||
"text": "成就",
|
||||
"condition": "true",
|
||||
"desc": [
|
||||
"成就系统是本塔的一个独立系统。它不会像勇士属性一样跟随存档变化,而是只要你完成了成就,那么就永远完成了,",
|
||||
"除非你清理了浏览器。每个成就都有成就点,<span style=\"color: gold\">成就点目前没有实际用途,",
|
||||
"只是一个收集要素,对游戏进程没有任何影响。</span>",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"成就分为三种,普通成就,挑战成就和探索成就。普通成就完成难度一般较低,挑战成就完成难度较高,",
|
||||
"而探索成就一般需要你自己探索如何完成。对于完成度类型的探索成就,它的完成度由到达过的地图与本章完成的成就数决定。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"<span style=\"color: gold\">调试模式下无法完成成就!</span>"
|
||||
]
|
||||
},
|
||||
"score": {
|
||||
"text": "计分方式",
|
||||
"condition": "true",
|
||||
"desc": [
|
||||
"第一章计分方式:血量 + 黄 * 5000 + 蓝 * 15000",
|
||||
"<br>",
|
||||
"第二章计分方式:血量 / 10 + 黄 * 2000 + 蓝 * 5000 + 红 * 10000"
|
||||
]
|
||||
},
|
||||
"skillTree": {
|
||||
"text": "技能树",
|
||||
"condition": "flags.chapter > 0",
|
||||
"desc": [
|
||||
"打开技能树可以点击状态栏的<span style=\"color: gold\">",
|
||||
"技能树按钮</span>(如果发现没有显示可以尝试上下滚动状态栏),还可以按",
|
||||
"<span style=\"color: gold\">快捷键J</span>打开。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"技能树是本塔的主要玩法之一。它可以让你使用智慧来学习技能,增加属性等。智慧在状态栏显示在防御的下一项,",
|
||||
"绿宝石可以增加勇士的智慧。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"打开技能树页面后,你可以在上方看到技能的名称与描述,下方会显示技能树,以及升级要求等。点击一个技能可以选中技能,",
|
||||
"再次点击可以升级技能。注意,前置技能栏可以上下滚动,因此如果发现显示不全,可以尝试上下滚动前置技能栏",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"注意,技能在点开之后是无法取消的,因此,加点时请慎重加点。注意,部分技能是必点技能,这些技能会在技能说明中明确指出,",
|
||||
"这些技能一般需要尽早点出。"
|
||||
]
|
||||
},
|
||||
"study": {
|
||||
"text": "学习",
|
||||
"condition": "Mota.Plugin.require('skillTree_g').getSkillLevel(11) > 0",
|
||||
"desc": [
|
||||
"本条目会详细说明学习的机制与所有可以被学习的技能被学习后的效果。当前已经学习的技能会以与状态栏类似的盒子展示出来。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"首先,学习技能消耗的智慧点会越来越多,初始消耗的智慧点为500,每学习一次增加250。",
|
||||
"学习的技能可以持续5场战斗,在技能树界面每升级一次增加3场,",
|
||||
"<span style=\"color: gold\">当前为${Mota.Plugin.require('skillTree_g').getSkillLevel(11) * 3 + 2}场</span>。",
|
||||
"学习后对应属性的值,例如抱团怪增加的属性百分比,会与被学习的怪物相同。学习界面可以使用背包中的道具或点击状态栏打开。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"下面会详细说明每一种可以被学习的技能被学习后的效果,没有列出的均不可学习。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"<span style=\"color: #fc3\">1. 致命一击</span>:勇士每5回合对怪物造成一次强力攻击。",
|
||||
"<br>",
|
||||
"<span style=\"color: #bbb0ff\">2. 恶毒</span>:勇士攻击无视怪物的防御。",
|
||||
"<br>",
|
||||
"<span style=\"color: #c0b088\">3. 坚固</span>:勇士防御不低于怪物的攻击-1。",
|
||||
"<br>",
|
||||
"<span style=\"color: #fe7\">4. n连击</span>:勇士每回合攻击n次",
|
||||
"<br>",
|
||||
"<span style=\"color: #b30000\">5. 饥渴</span>:勇士在战前吸取怪物一定量的攻击加载自己身上,",
|
||||
"同时减少怪物相应量的攻击,优先于怪物。",
|
||||
"<br>",
|
||||
"<span style=\"color: #fa4\">6. 抱团</span>:勇士周围每有一个拥有抱团属性的怪物,勇士的属性便增加一定值。",
|
||||
"相应地,拥有抱团属性的怪物也会受到勇士的加成。",
|
||||
"<br>",
|
||||
"<span style=\"color: #b0c0dd\">7. 勇气之刃</span>:勇士第一回合造成一定量的伤害,之后正常。",
|
||||
"<br>",
|
||||
"<span style=\"color: #ff00d2\">8. 勇气冲锋</span>:勇士首先发动冲锋,造成一定量的伤害,眩晕怪物5回合。",
|
||||
"学习该技能后,勇士无条件先手。",
|
||||
"<br>",
|
||||
"<span style=\"color: #bbb0ff\">9. 魔攻</span>:勇士攻击无视怪物的防御。",
|
||||
"<br>",
|
||||
"<span style=\"color: #b0b666\">10. 先攻</span>:勇士无条件先手。"
|
||||
]
|
||||
},
|
||||
"special1": {
|
||||
"text": "第一章怪物特技",
|
||||
"condition": "flags.chapter > 0",
|
||||
"desc": [
|
||||
"这里会展示第一章的怪物中需要特别说明的怪物特技。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"<span style=\"color: #c0b088\">1. 坚固</span>:",
|
||||
"在本塔中,额外攻击可以对坚固怪造成额外伤害。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"<span style=\"color: #80eed6\">2. 绝对防御</span>:",
|
||||
"该怪物一般可以用于刷血。该怪物可以使你每回合对怪物造成的伤害恰好为1,导致战斗回合数很高,因此可以刷血。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"<span style=\"color: #fc3\">3. 致命一击、勇气之刃、勇气冲锋</span>:",
|
||||
"造成的伤害为怪物每回合对勇士的伤害的一定倍数,而非攻击提高一定倍数。"
|
||||
]
|
||||
},
|
||||
"special2": {
|
||||
"text": "第二章怪物特技",
|
||||
"condition": "flags.chapter > 1",
|
||||
"desc": [
|
||||
"这里会展示第二章的怪物中需要特别说明的怪物特技。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"<span style=\"color: #f66\">1. 电摇嘲讽</span>:",
|
||||
"该特技会撞碎路上的所有地形和门,不需要消耗钥匙,拾取路上的所有道具,与路上的怪物战斗,最后与该怪物战斗。",
|
||||
"如果怪物所在位置可以被嘲讽,那么勇士会被继续嘲讽。如果在被嘲讽的路上可以被其他怪物嘲讽,则不会触发。",
|
||||
"如果一个点可以被多个怪物嘲讽,那么会优先选择最靠左上角的怪物。在地图上会标记出勇士的移动方向。",
|
||||
"<span style=\"color: gold\">在被嘲讽之前会自动存档。</span>",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"<span style=\"color: #d8a\">2. 永夜</span>、<span style=\"color: #ffd\">极昼</span>:",
|
||||
"战斗后会在本楼层中加减怪物与勇士的攻防,每个楼层会单独存储。例如你在1楼层增加了100点攻击,2楼层减少了100点攻击,",
|
||||
"那么当你从2楼层到1楼层时,攻击会增加200点,反之亦然。注意这里没有计算buff。"
|
||||
]
|
||||
}
|
||||
}
|
43
packages/legacy-ui/src/data/skill.json
Normal file
43
packages/legacy-ui/src/data/skill.json
Normal file
@ -0,0 +1,43 @@
|
||||
{
|
||||
"none": {
|
||||
"text": "无",
|
||||
"opened": "true",
|
||||
"desc": [
|
||||
"当前未选择技能"
|
||||
]
|
||||
},
|
||||
"blade": {
|
||||
"text": "1:断灭之刃",
|
||||
"opened": "true",
|
||||
"desc": [
|
||||
"<span style=\"color: gold\">快捷键1</span>,开启后勇士攻击增加${level:2 * 10}%,",
|
||||
"同时防御减少${level:2 * 10}%。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"当前等级:${level:2}"
|
||||
]
|
||||
},
|
||||
"jump": {
|
||||
"text": "2:跳跃",
|
||||
"opened": "true",
|
||||
"desc": [
|
||||
"<span style=\"color: gold\">快捷键2</span>,消耗200点生命值,困难消耗400点,一个地图只能使用3次,",
|
||||
"如果前方为可通行的地面,则不能使用该技能,如果前方为怪物,则将怪物移至勇士视线上第一个不能通行的方块后",
|
||||
"如果前方为障碍物,则直接跳到该障碍物的后方。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"进入第二章后不再消耗生命值。"
|
||||
]
|
||||
},
|
||||
"shield": {
|
||||
"text": "3:铸剑为盾",
|
||||
"opened": "true",
|
||||
"desc": [
|
||||
"<span style=\"color: gold\">快捷键3</span>,开启后勇士防御增加${level:10 * 10}%,",
|
||||
"同时攻击减少${level:10 * 10}%。",
|
||||
"<br>",
|
||||
"<br>",
|
||||
"当前等级:${level:10}"
|
||||
]
|
||||
}
|
||||
}
|
37
packages/legacy-ui/src/data/tips.json
Normal file
37
packages/legacy-ui/src/data/tips.json
Normal file
@ -0,0 +1,37 @@
|
||||
[
|
||||
"按下C可以查看鼠标位置怪物临界",
|
||||
"按下E可以查看鼠标位置怪物的详细属性",
|
||||
"将鼠标移动到光环怪上以查看其产生的光环",
|
||||
"字体太大?试试在背包的系统设置里面调整字体大小吧!",
|
||||
"字体太小?试试在背包的系统设置里面调整字体大小吧!",
|
||||
"按键不合心意?试试在背包的系统设置里面自定义快捷键",
|
||||
"拖动状态栏左上角可以移动状态栏哦!",
|
||||
"拖动状态栏右下角可以缩放状态栏哦!",
|
||||
"按下M键,鼠标位置的怪物的信息就会被你看光啦!",
|
||||
"咱就是说,要不要试一下工具栏的最后一个按钮?",
|
||||
"要不要试试工具栏倒数第二个按钮呢?",
|
||||
"想自定义工具栏?去背包的系统设置看看吧!",
|
||||
"冷知识:临界界面可以拖动滚动条来查看减伤情况",
|
||||
"可以用滚轮或者双指缩放小地图!",
|
||||
"楼传的最左侧一栏可以选择区域!",
|
||||
"冷知识:装备栏左栏最上面可以修改装备排序",
|
||||
"冷冷冷知识:装备栏左栏最上面右侧可以更改顺序或倒序",
|
||||
"第一章使用跳跃技能可是要扣血的!要注意!",
|
||||
"按H查看本游戏的百科全书",
|
||||
"给别人炫耀一下自己的成就点吧!虽然不能记榜(",
|
||||
"抱团属性会在怪物右上角显示加成数量!",
|
||||
"乾坤挪移属性会在怪物左上角显示“乾”字!",
|
||||
"电脑端可以试试按F11全屏游玩!",
|
||||
"手机端要不试试横屏玩?",
|
||||
"不在楼梯边也可以使用楼传!",
|
||||
"技能树的右下角可以切换章节!",
|
||||
"开启自动切换技能就会自动帮你选择最优技能了!",
|
||||
"魔塔不仅有撤回,还有恢复,按W或6就可以了!",
|
||||
"觉得卡顿?可以去试着设置里面关闭一些特性!",
|
||||
"从第二章开始,怪物负伤害量不会超过其生命的1/4",
|
||||
"生命回复不会超过防御的十分之一",
|
||||
"不想看小贴士?设置里面可以关掉!",
|
||||
"不小心进入了追猎范围?读取自动存档撤回到进入前吧!",
|
||||
"不小心进入了电摇嘲讽范围?读取自动存档撤回到进入前吧!",
|
||||
"小地图出现卡顿?试试在背包中系统设置里把小地图懒更新打开吧!"
|
||||
]
|
7
packages/legacy-ui/src/index.ts
Normal file
7
packages/legacy-ui/src/index.ts
Normal file
@ -0,0 +1,7 @@
|
||||
export * as UI from './ui';
|
||||
export * from './tools';
|
||||
|
||||
export * from './animateController';
|
||||
export * from './mark';
|
||||
export * from './use';
|
||||
export * from './utils';
|
@ -1,5 +1,5 @@
|
||||
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 { ref, Ref } from 'vue';
|
||||
|
@ -94,12 +94,13 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, onMounted, ref, watch } from 'vue';
|
||||
import { detailInfo, getCriticalDamage, getDefDamage } from '../plugin/ui/book';
|
||||
import { detailInfo, getCriticalDamage, getDefDamage } from '../tools/book';
|
||||
import Chart, { ChartConfiguration } from 'chart.js/auto';
|
||||
import { has, setCanvasSize } from '../plugin/utils';
|
||||
import { has, setCanvasSize } from '../utils';
|
||||
import { debounce } from 'lodash-es';
|
||||
import { isMobile } from '../plugin/use';
|
||||
import { createChangable } from '@/plugin/ui/common';
|
||||
import { isMobile } from '../use';
|
||||
import { createChangable } from '../tools/common';
|
||||
|
||||
const props = defineProps<{
|
||||
fromBook?: boolean;
|
||||
}>();
|
@ -28,8 +28,8 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { isMobile } from '../plugin/use';
|
||||
import { detailInfo, getSpecialHint } from '../plugin/ui/book';
|
||||
import { isMobile } from '../use';
|
||||
import { detailInfo, getSpecialHint } from '../tools/book';
|
||||
|
||||
const props = defineProps<{
|
||||
fromBook?: boolean;
|
@ -29,8 +29,8 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import Scroll from '../components/scroll.vue';
|
||||
import { detailInfo } from '../plugin/ui/book';
|
||||
import { hasMarkedEnemy, markEnemy } from '@/plugin/mark';
|
||||
import { detailInfo } from '../tools/book';
|
||||
import { hasMarkedEnemy, markEnemy } from '../mark';
|
||||
|
||||
const enemy = detailInfo.enemy!;
|
||||
const marked = ref(hasMarkedEnemy(enemy.enemy.id));
|
@ -24,7 +24,7 @@
|
||||
import { checkAssist } from '@/core/main/custom/hotkey';
|
||||
import { Keyboard } from '@/core/main/custom/keyboard';
|
||||
import { KeyboardEmits } from '@/core/main/custom/keyboard';
|
||||
import { KeyCodeUtils } from '@/plugin/keyCodes';
|
||||
import { KeyCodeUtils } from '@motajs/client';
|
||||
import { nextTick, onUnmounted, ref } from 'vue';
|
||||
|
||||
const props = defineProps<{
|
@ -1,6 +1,5 @@
|
||||
import { ref } from 'vue';
|
||||
import list from '../../data/achievement.json';
|
||||
import { achiDict, checkCompletionAchievement } from '../completion';
|
||||
import list from '../data/achievement.json';
|
||||
import { achiDict, checkCompletionAchievement } from './completion';
|
||||
import { changeLocalStorage, has } from '../utils';
|
||||
|
||||
type AchievementList = typeof list;
|
@ -1,4 +1,4 @@
|
||||
import type { CurrentEnemy } from '../../game/enemy/battle';
|
||||
import type { CurrentEnemy } from '@/game/enemy/battle';
|
||||
import { has } from '../utils';
|
||||
|
||||
export interface ToShowEnemy extends CurrentEnemy {
|
@ -2,8 +2,8 @@ import {
|
||||
AchievementType,
|
||||
completeAchievement,
|
||||
hasCompletedAchievement
|
||||
} from './ui/achievement';
|
||||
import { changeLocalStorage } from './utils';
|
||||
} from './achievement';
|
||||
import { changeLocalStorage } from '../utils';
|
||||
import list from '../data/achievement.json';
|
||||
|
||||
export const floors: Record<number, FloorIds[]> = {
|
@ -1,6 +1,6 @@
|
||||
import { getDamageColor } from '../utils';
|
||||
import { ToShowEnemy } from './book';
|
||||
import type { DamageEnemy, EnemyInfo } from '../../game/enemy/damage';
|
||||
import type { DamageEnemy, EnemyInfo } from '@/game/enemy/damage';
|
||||
import { isMobile } from '../use';
|
||||
|
||||
export function getLocFromMouseLoc(x: number, y: number): LocArr {
|
7
packages/legacy-ui/src/tools/index.ts
Normal file
7
packages/legacy-ui/src/tools/index.ts
Normal file
@ -0,0 +1,7 @@
|
||||
export * from './achievement';
|
||||
export * from './book';
|
||||
export * from './common';
|
||||
export * from './completion';
|
||||
export * from './equipbox';
|
||||
export * from './fixed';
|
||||
export * from './fly';
|
@ -1,5 +1,3 @@
|
||||
import { has } from '../utils';
|
||||
|
||||
interface ClsMap {
|
||||
tools: '消耗道具';
|
||||
constants: '永久道具';
|
@ -104,9 +104,9 @@ import {
|
||||
Achievement,
|
||||
getNowPoint,
|
||||
hasCompletedAchievement
|
||||
} from '../plugin/ui/achievement';
|
||||
} from '../tools/achievement';
|
||||
import Scroll from '../components/scroll.vue';
|
||||
import { isMobile } from '../plugin/use';
|
||||
import { isMobile } from '../use';
|
||||
|
||||
const props = defineProps<{
|
||||
num: number;
|
@ -38,20 +38,19 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="tsx">
|
||||
import { sleep } from 'mutate-animate';
|
||||
import { onMounted, onUnmounted, ref } from 'vue';
|
||||
import { onUnmounted, ref } from 'vue';
|
||||
import EnemyOne from '../components/enemyOne.vue';
|
||||
import Scroll from '../components/scroll.vue';
|
||||
import { getDamageColor, has, keycode } from '../plugin/utils';
|
||||
import { has } from '../utils';
|
||||
import BookDetail from './bookDetail.vue';
|
||||
import { LeftOutlined } from '@ant-design/icons-vue';
|
||||
import { ToShowEnemy, detailInfo } from '../plugin/ui/book';
|
||||
import { getDetailedEnemy } from '../plugin/ui/fixed';
|
||||
import { ToShowEnemy, detailInfo } from '../tools/book';
|
||||
import { getDetailedEnemy } from '../tools/fixed';
|
||||
import { GameUi } from '@/core/main/custom/ui';
|
||||
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';
|
||||
import { isMobile } from '../use';
|
||||
|
||||
const props = defineProps<{
|
||||
num: number;
|
@ -77,12 +77,12 @@
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, onUnmounted, ref } from 'vue';
|
||||
import EnemyOne from '../components/enemyOne.vue';
|
||||
import { useDrag } from '../plugin/use';
|
||||
import { useDrag } from '../use';
|
||||
import EnemySpecial from '../panel/enemySpecial.vue';
|
||||
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 { detailInfo } from '../tools/book';
|
||||
import { gameKey } from '@/core/main/custom/hotkey';
|
||||
|
||||
const props = defineProps<{
|
@ -8,7 +8,7 @@
|
||||
<script lang="ts" setup>
|
||||
import { Animation, hyper, sleep } from 'mutate-animate';
|
||||
import { onMounted } from 'vue';
|
||||
import { has } from '../plugin/utils';
|
||||
import { has } from '../utils';
|
||||
import { GameUi } from '@/core/main/custom/ui';
|
||||
import { fixedUi } from '@/core/main/init/ui';
|
||||
|
@ -22,11 +22,7 @@ import { sleep, Ticker } from 'mutate-animate';
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import Box from '../components/box.vue';
|
||||
import list from '../data/achievement.json';
|
||||
import {
|
||||
AchievementType,
|
||||
getNowPoint,
|
||||
totalPoint
|
||||
} from '../plugin/ui/achievement';
|
||||
import { AchievementType, getNowPoint, totalPoint } from '../tools/achievement';
|
||||
import { GameUi } from '@/core/main/custom/ui';
|
||||
import { fixedUi } from '@/core/main/init/ui';
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { nextTick, onUnmounted, reactive, watch } from 'vue';
|
||||
import { Danmaku } from '../core/main/custom/danmaku';
|
||||
import { Danmaku } from '@/core/main/custom/danmaku';
|
||||
import { LikeFilled } from '@ant-design/icons-vue';
|
||||
import { mainSetting } from '@/core/main/setting';
|
||||
import { debounce } from 'lodash-es';
|
||||
@ -205,7 +205,10 @@ onUnmounted(() => {});
|
||||
}
|
||||
|
||||
.danmaku-info {
|
||||
text-shadow: 1px 1px 1px black, 1px -1px 1px black, -1px 1px 1px black,
|
||||
text-shadow:
|
||||
1px 1px 1px black,
|
||||
1px -1px 1px black,
|
||||
-1px 1px 1px black,
|
||||
-1px -1px 1px black;
|
||||
}
|
||||
|
@ -162,10 +162,10 @@ import { Danmaku } from '@/core/main/custom/danmaku';
|
||||
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 { calStringSize, tip } from '../utils';
|
||||
import { gameKey } from '@/core/main/custom/hotkey';
|
||||
import { isNil } from 'lodash-es';
|
||||
import { stringifyCSS, parseCss, getIconHeight } from '@/plugin/utils';
|
||||
import { stringifyCSS, parseCss, getIconHeight } from '../utils';
|
||||
import { logger, LogLevel } from '@motajs/common';
|
||||
import Scroll from '@/components/scroll.vue';
|
||||
import BoxAnimate from '@/components/boxAnimate.vue';
|
@ -20,7 +20,7 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed, onUnmounted, ref } from 'vue';
|
||||
import desc from '../data/desc.json';
|
||||
import { splitText } from '../plugin/utils';
|
||||
import { splitText } from '../utils';
|
||||
import Colomn from '../components/colomn.vue';
|
||||
import { GameUi } from '@/core/main/custom/ui';
|
||||
import { gameKey } from '@/core/main/custom/hotkey';
|
@ -125,8 +125,8 @@
|
||||
<BoxAnimate
|
||||
:id="
|
||||
isCol
|
||||
? equiped[selected] ?? 'none'
|
||||
: toShow[selected]?.[0] ?? 'none'
|
||||
? (equiped[selected] ?? 'none')
|
||||
: (toShow[selected]?.[0] ?? 'none')
|
||||
"
|
||||
></BoxAnimate>
|
||||
<span>{{ equip.name }}</span>
|
||||
@ -179,24 +179,16 @@ import {
|
||||
SortAscendingOutlined,
|
||||
SortDescendingOutlined
|
||||
} from '@ant-design/icons-vue';
|
||||
import {
|
||||
computed,
|
||||
nextTick,
|
||||
onMounted,
|
||||
onUnmounted,
|
||||
reactive,
|
||||
ref,
|
||||
watch
|
||||
} from 'vue';
|
||||
import { computed, nextTick, onMounted, onUnmounted, ref, watch } from 'vue';
|
||||
import Scroll from '../components/scroll.vue';
|
||||
import { getAddStatus, getEquips, getNowStatus } from '../plugin/ui/equipbox';
|
||||
import { getAddStatus, getEquips, getNowStatus } from '../tools/equipbox';
|
||||
import BoxAnimate from '../components/boxAnimate.vue';
|
||||
import { has, tip, type } from '../plugin/utils';
|
||||
import { cancelGlobalDrag, isMobile, useDrag } from '../plugin/use';
|
||||
import { has, tip, type } from '../utils';
|
||||
import { cancelGlobalDrag, isMobile, useDrag } from '../use';
|
||||
import { hyper } from 'mutate-animate';
|
||||
import { GameUi } from '@/core/main/custom/ui';
|
||||
import { gameKey } from '@/core/main/custom/hotkey';
|
||||
import { getStatusLabel } from '../plugin/utils';
|
||||
import { getStatusLabel } from '../utils';
|
||||
import { mainUi } from '@/core/main/init/ui';
|
||||
|
||||
const props = defineProps<{
|
@ -33,7 +33,7 @@ import { onMounted, onUpdated, Ref, ref, watch } from 'vue';
|
||||
import Box from '../components/box.vue';
|
||||
import { GameUi } from '@/core/main/custom/ui';
|
||||
import type { DamageEnemy, EnemyInfo } from '@/game/enemy/damage';
|
||||
import { nextFrame } from '@/plugin/utils';
|
||||
import { nextFrame } from '../utils';
|
||||
|
||||
const props = defineProps<{
|
||||
num: number;
|
@ -9,9 +9,9 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { getDetailedEnemy } from '../plugin/ui/fixed';
|
||||
import { getDetailedEnemy } from '../tools/fixed';
|
||||
import BookDetail from './bookDetail.vue';
|
||||
import { detailInfo } from '../plugin/ui/book';
|
||||
import { detailInfo } from '../tools/book';
|
||||
import { hovered } from '@/core/main/init/fixed';
|
||||
import { GameUi } from '@/core/main/custom/ui';
|
||||
import { mainUi } from '@/core/main/init/ui';
|
@ -89,8 +89,8 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed, onMounted, onUnmounted, ref, watch } from 'vue';
|
||||
import Scroll from '../components/scroll.vue';
|
||||
import { getArea, getMapData, MinimapDrawer } from '../plugin/ui/fly';
|
||||
import { cancelGlobalDrag, isMobile, useDrag, useWheel } from '../plugin/use';
|
||||
import { getArea, getMapData, MinimapDrawer } from '../tools/fly';
|
||||
import { cancelGlobalDrag, isMobile, useDrag, useWheel } from '../use';
|
||||
import {
|
||||
LeftOutlined,
|
||||
DoubleLeftOutlined,
|
||||
@ -98,10 +98,10 @@ import {
|
||||
DoubleRightOutlined
|
||||
} from '@ant-design/icons-vue';
|
||||
import { debounce } from 'lodash-es';
|
||||
import { tip } from '../plugin/utils';
|
||||
import { tip } from '../utils';
|
||||
import { GameUi } from '@/core/main/custom/ui';
|
||||
import { gameKey } from '@/core/main/custom/hotkey';
|
||||
import { createChangable } from '@/plugin/ui/common';
|
||||
import { createChangable } from '../tools/common';
|
||||
import { mainUi } from '@/core/main/init/ui';
|
||||
import { mainSetting } from '@/core/main/setting';
|
||||
import { GameStorage } from '@/core/main/storage';
|
||||
@ -584,7 +584,10 @@ onUnmounted(() => {
|
||||
max-width: 50%;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
text-shadow: 1px 1px 1px black, 1px -1px 1px black, -1px 1px 1px black,
|
||||
text-shadow:
|
||||
1px 1px 1px black,
|
||||
1px -1px 1px black,
|
||||
-1px 1px 1px black,
|
||||
-1px -1px 1px black;
|
||||
}
|
||||
|
@ -38,11 +38,11 @@
|
||||
<script lang="ts" setup>
|
||||
import { Hotkey } from '@/core/main/custom/hotkey';
|
||||
import { GameUi } from '@/core/main/custom/ui';
|
||||
import Column from '@/components/colomn.vue';
|
||||
import Column from '../components/colomn.vue';
|
||||
import { mainUi } from '@/core/main/init/ui';
|
||||
import { computed, onMounted, onUnmounted, reactive, ref } from 'vue';
|
||||
import { KeyCode, KeyCodeUtils } from '@/plugin/keyCodes';
|
||||
import { generateBinary, keycode } from '@/plugin/utils';
|
||||
import { KeyCode, KeyCodeUtils } from '@motajs/client';
|
||||
import { generateBinary, keycode } from '../utils';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { gameKey } from '@/core/main/custom/hotkey';
|
||||
|
@ -15,7 +15,6 @@ 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 Toolbox } from './toolbox.vue';
|
||||
export { default as Hotkey } from './hotkey.vue';
|
||||
export { default as Toolbar } from './toolbar.vue';
|
@ -32,7 +32,7 @@ import {
|
||||
LoadTask
|
||||
} from '@motajs/legacy-common';
|
||||
import { GameUi } from '@/core/main/custom/ui';
|
||||
import { formatSize } from '@/plugin/utils';
|
||||
import { formatSize } from '../utils';
|
||||
import { logger } from '@motajs/common';
|
||||
import { fixedUi } from '@/core/main/init/ui';
|
||||
import { sleep } from 'mutate-animate';
|
@ -52,7 +52,7 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref, watch } from 'vue';
|
||||
import { MarkInfo, unmarkEnemy } from '../plugin/mark';
|
||||
import { MarkInfo, unmarkEnemy } from '../mark';
|
||||
import Box from '../components/box.vue';
|
||||
import Scroll from '../components/scroll.vue';
|
||||
import BoxAnimate from '../components/boxAnimate.vue';
|
@ -58,7 +58,7 @@
|
||||
<div class="info-editor" v-if="!!selectedItem">
|
||||
<div class="editor-custom">
|
||||
<component
|
||||
:is="(selectedItem.controller as any)"
|
||||
:is="selectedItem.controller as any"
|
||||
:item="selectedItem"
|
||||
:displayer="displayer"
|
||||
:setting="setting"
|
||||
@ -79,11 +79,11 @@ import {
|
||||
MotaSettingItem,
|
||||
SettingDisplayer,
|
||||
SettingDisplayInfo
|
||||
} from '../core/main/setting';
|
||||
} from '@/core/main/setting';
|
||||
import { RightOutlined, LeftOutlined } from '@ant-design/icons-vue';
|
||||
import { splitText } from '../plugin/utils';
|
||||
import { splitText } from '../utils';
|
||||
import Scroll from '../components/scroll.vue';
|
||||
import { isMobile } from '../plugin/use';
|
||||
import { isMobile } from '../use';
|
||||
import { gameKey } from '@/core/main/custom/hotkey';
|
||||
import { GameUi } from '@/core/main/custom/ui';
|
||||
import { mainUi } from '@/core/main/init/ui';
|
@ -169,7 +169,7 @@ import {
|
||||
RightOutlined,
|
||||
DoubleRightOutlined
|
||||
} from '@ant-design/icons-vue';
|
||||
import { splitText, tip } from '../plugin/utils';
|
||||
import { splitText, tip } from '../utils';
|
||||
import Scroll from '../components/scroll.vue';
|
||||
import BoxAnimate from '../components/boxAnimate.vue';
|
||||
import { GameUi } from '@/core/main/custom/ui';
|
@ -19,7 +19,7 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref } from 'vue';
|
||||
import skills from '../data/skill.json';
|
||||
import { has } from '../plugin/utils';
|
||||
import { has } from '../utils';
|
||||
import Column from '../components/colomn.vue';
|
||||
import { mainUi } from '@/core/main/init/ui';
|
||||
|
@ -81,8 +81,8 @@
|
||||
import { computed, onMounted, onUnmounted, ref, watch } from 'vue';
|
||||
import { LeftOutlined, RightOutlined } from '@ant-design/icons-vue';
|
||||
import Scroll from '../components/scroll.vue';
|
||||
import { has, splitText, tip } from '../plugin/utils';
|
||||
import { isMobile } from '../plugin/use';
|
||||
import { has, splitText, tip } from '../utils';
|
||||
import { isMobile } from '../use';
|
||||
import { sleep } from 'mutate-animate';
|
||||
import { gameKey } from '@/core/main/custom/hotkey';
|
||||
import { GameUi } from '@/core/main/custom/ui';
|
@ -64,15 +64,16 @@ import {
|
||||
FullscreenExitOutlined
|
||||
} from '@ant-design/icons-vue';
|
||||
import { sleep } from 'mutate-animate';
|
||||
import { doByInterval, keycode } from '../plugin/utils';
|
||||
import { triggerFullscreen } from '../plugin/utils';
|
||||
import { isMobile } from '../plugin/use';
|
||||
import { doByInterval } from '../utils';
|
||||
import { triggerFullscreen } from '../utils';
|
||||
import { isMobile } from '../use';
|
||||
import { GameUi } from '@/core/main/custom/ui';
|
||||
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';
|
||||
import { mat4 } from 'gl-matrix';
|
||||
// todo: 改了
|
||||
import { bgmController } from '@/module';
|
||||
|
||||
const props = defineProps<{
|
@ -4,7 +4,7 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, onUnmounted, ref } from 'vue';
|
||||
import tips from '@/data/tips.json';
|
||||
import tips from '../data/tips.json';
|
||||
|
||||
const span = ref<HTMLSpanElement>();
|
||||
const nowTip = ref<string>();
|
@ -200,9 +200,9 @@ import {
|
||||
LeftOutlined
|
||||
} from '@ant-design/icons-vue';
|
||||
import { mainUi } from '@/core/main/init/ui';
|
||||
import { isMobile } from '@/plugin/use';
|
||||
import Scroll from '@/components/scroll.vue';
|
||||
import { deleteWith, tip } from '@/plugin/utils';
|
||||
import { isMobile } from '../use';
|
||||
import Scroll from '../components/scroll.vue';
|
||||
import { deleteWith, tip } from '../utils';
|
||||
import { Modal } from 'ant-design-vue';
|
||||
import { mainSetting } from '@/core/main/setting';
|
||||
import { ToolbarItemType } from '@/core/main/init/toolbar';
|
@ -17,7 +17,7 @@
|
||||
:noaction="!!item.noDefaultAction"
|
||||
>
|
||||
<component
|
||||
:is="(CustomToolbar.info[item.type].show as any)"
|
||||
:is="CustomToolbar.info[item.type].show as any"
|
||||
:item="item"
|
||||
:toolbar="bar"
|
||||
></component>
|
||||
@ -27,7 +27,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import Box from '@/components/box.vue';
|
||||
import Box from '../components/box.vue';
|
||||
import { CustomToolbar } from '@/core/main/custom/toolbar';
|
||||
import { GameUi } from '@/core/main/custom/ui';
|
||||
import { mainSetting } from '@/core/main/setting';
|
@ -85,8 +85,8 @@
|
||||
<span>{{
|
||||
selected === 'none'
|
||||
? '永久道具'
|
||||
: getClsName(all[selected].cls as ItemMode) ??
|
||||
'永久道具'
|
||||
: (getClsName(all[selected].cls as ItemMode) ??
|
||||
'永久道具')
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -108,13 +108,13 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { LeftOutlined, RightOutlined } from '@ant-design/icons-vue';
|
||||
import { computed, nextTick, onMounted, onUnmounted, ref, watch } from 'vue';
|
||||
import { computed, nextTick, onUnmounted, ref, watch } from 'vue';
|
||||
import Scroll from '../components/scroll.vue';
|
||||
import BoxAnimate from '../components/boxAnimate.vue';
|
||||
import { getClsName, getItems } from '../plugin/ui/toolbox';
|
||||
import { isMobile } from '../plugin/use';
|
||||
import { type, keycode, has } from '../plugin/utils';
|
||||
import { hyper, sleep } from 'mutate-animate';
|
||||
import { getClsName, getItems } from '../tools/toolbox';
|
||||
import { isMobile } from '../use';
|
||||
import { type, has } from '../utils';
|
||||
import { hyper } from 'mutate-animate';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { GameUi } from '@/core/main/custom/ui';
|
||||
import { gameKey } from '@/core/main/custom/hotkey';
|
@ -73,7 +73,7 @@ export function useDrag(
|
||||
if (ele) {
|
||||
(ele as HTMLElement).removeEventListener('mousemove', mouseFn);
|
||||
}
|
||||
onup && onup(e);
|
||||
onup?.(e);
|
||||
};
|
||||
|
||||
const touchUp = (e: TouchEvent) => {
|
||||
@ -81,7 +81,7 @@ export function useDrag(
|
||||
if (ele) {
|
||||
(ele as HTMLElement).removeEventListener('touchmove', touchFn);
|
||||
}
|
||||
onup && onup(e);
|
||||
onup?.(e);
|
||||
};
|
||||
|
||||
const md = (e: MouseEvent) => {
|
@ -3,7 +3,7 @@ import { MessageApi } from 'ant-design-vue/lib/message';
|
||||
import { isNil } from 'lodash-es';
|
||||
import { Animation, sleep, TimingFn } from 'mutate-animate';
|
||||
import { Ref, ref } from 'vue';
|
||||
import { EVENT_KEY_CODE_MAP, KeyCode } from './keyCodes';
|
||||
import { EVENT_KEY_CODE_MAP, KeyCode } from '@motajs/client';
|
||||
import axios from 'axios';
|
||||
import { decompressFromBase64 } from 'lz-string';
|
||||
import { Keyboard, KeyboardEmits } from '@/core/main/custom/keyboard';
|
||||
@ -336,7 +336,7 @@ export async function swapChapter(chapter: number, hard: number) {
|
||||
}
|
||||
|
||||
export function ensureArray<T>(arr: T): T extends any[] ? T : T[] {
|
||||
// @ts-ignore
|
||||
// @ts-expect-error 暂时无法推导
|
||||
return arr instanceof Array ? arr : [arr];
|
||||
}
|
||||
|
||||
@ -447,7 +447,7 @@ export function getVitualKeyOnce(
|
||||
const key = Keyboard.get('full')!;
|
||||
key.withAssist(assist);
|
||||
const id = mainUi.open('virtualKey', { keyboard: key });
|
||||
key.on('emit', (item, assist, index, ev) => {
|
||||
key.on('emit', (item, assist, _index, ev) => {
|
||||
ev.preventDefault();
|
||||
if (emitAssist) {
|
||||
if (emittable.length === 0 || emittable.includes(item.key)) {
|
@ -195,6 +195,36 @@ importers:
|
||||
|
||||
packages/common: {}
|
||||
|
||||
packages/legacy-client:
|
||||
dependencies:
|
||||
'@motajs/common':
|
||||
specifier: workspace:*
|
||||
version: link:../common
|
||||
|
||||
packages/legacy-common:
|
||||
dependencies:
|
||||
'@motajs/common':
|
||||
specifier: workspace:*
|
||||
version: link:../common
|
||||
|
||||
packages/legacy-data:
|
||||
dependencies:
|
||||
'@motajs/common':
|
||||
specifier: workspace:*
|
||||
version: link:../common
|
||||
|
||||
packages/legacy-ui:
|
||||
dependencies:
|
||||
'@motajs/client':
|
||||
specifier: workspace:*
|
||||
version: link:../client
|
||||
'@motajs/common':
|
||||
specifier: workspace:*
|
||||
version: link:../common
|
||||
'@motajs/render':
|
||||
specifier: workspace:*
|
||||
version: link:../render
|
||||
|
||||
packages/render:
|
||||
dependencies:
|
||||
'@motajs/render-core':
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { ensureArray, tip } from '@/plugin/utils';
|
||||
import { ensureArray, tip } from '@motajs/legacy-ui';
|
||||
import { sleep } from 'mutate-animate';
|
||||
import { logger } from '@motajs/common';
|
||||
|
||||
|
@ -11,8 +11,7 @@ import {
|
||||
mainSetting,
|
||||
settingStorage
|
||||
} from './main/setting';
|
||||
import { KeyCode } from '@/plugin/keyCodes';
|
||||
import { status } from '@/plugin/ui/statusBar';
|
||||
import { KeyCode } from '@motajs/client';
|
||||
import '@/plugin';
|
||||
import './package';
|
||||
import { CustomToolbar } from './main/custom/toolbar';
|
||||
@ -25,26 +24,13 @@ import {
|
||||
} from './main/custom/hotkey';
|
||||
import { Keyboard, generateKeyboardEvent } from './main/custom/keyboard';
|
||||
import './main/layout';
|
||||
import { MComponent, m } from './main/layout';
|
||||
import { createSettingComponents } from './main/init/settings';
|
||||
import {
|
||||
createToolbarComponents,
|
||||
createToolbarEditorComponents
|
||||
} from './main/init/toolbar';
|
||||
import { VirtualKey } from './main/init/misc';
|
||||
import * as utils from '@/plugin/utils';
|
||||
import * as use from '@/plugin/use';
|
||||
import * as mark from '@/plugin/mark';
|
||||
import * as keyCodes from '@/plugin/keyCodes';
|
||||
import { addAnimate, removeAnimate } from '@/plugin/animateController';
|
||||
import * as bookTools from '@/plugin/ui/book';
|
||||
import * as commonTools from '@/plugin/ui/common';
|
||||
import * as equipboxTools from '@/plugin/ui/equipbox';
|
||||
import * as fixedTools from '@/plugin/ui/fixed';
|
||||
import * as flyTools from '@/plugin/ui/fly';
|
||||
import * as statusBarTools from '@/plugin/ui/statusBar';
|
||||
import * as toolboxTools from '@/plugin/ui/toolbox';
|
||||
import * as UI from '@ui/index';
|
||||
import { UI } from '@motajs/legacy-ui';
|
||||
import Box from '@/components/box.vue';
|
||||
import BoxAnimate from '@/components/boxAnimate.vue';
|
||||
import Colomn from '@/components/colomn.vue';
|
||||
@ -54,7 +40,6 @@ import EnemyCritical from '@/panel/enemyCritical.vue';
|
||||
import EnemySpecial from '@/panel/enemySpecial.vue';
|
||||
import EnemyTarget from '@/panel/enemyTarget.vue';
|
||||
import KeyboardPanel from '@/panel/keyboard.vue';
|
||||
import { MCGenerator } from './main/layout';
|
||||
import { logger } from '@motajs/common';
|
||||
import { Danmaku } from './main/custom/danmaku';
|
||||
import * as Shadow from './fx/shadow';
|
||||
@ -73,16 +58,12 @@ Mota.register('class', 'Keyboard', Keyboard);
|
||||
Mota.register('class', 'MotaSetting', MotaSetting);
|
||||
Mota.register('class', 'SettingDisplayer', SettingDisplayer);
|
||||
Mota.register('class', 'UiController', UiController);
|
||||
Mota.register('class', 'MComponent', MComponent);
|
||||
Mota.register('class', 'Danmaku', Danmaku);
|
||||
// ----- 函数注册
|
||||
Mota.register('fn', 'm', m);
|
||||
Mota.register('fn', 'unwrapBinary', unwarpBinary);
|
||||
Mota.register('fn', 'checkAssist', checkAssist);
|
||||
Mota.register('fn', 'isAssist', isAssist);
|
||||
Mota.register('fn', 'generateKeyboardEvent', generateKeyboardEvent);
|
||||
Mota.register('fn', 'addAnimate', addAnimate);
|
||||
Mota.register('fn', 'removeAnimate', removeAnimate);
|
||||
// ----- 变量注册
|
||||
Mota.register('var', 'mainUi', mainUi);
|
||||
Mota.register('var', 'fixedUi', fixedUi);
|
||||
@ -102,18 +83,6 @@ Mota.register('module', 'MiscComponents', {
|
||||
VirtualKey
|
||||
});
|
||||
Mota.register('module', 'RenderUtils', utils);
|
||||
Mota.register('module', 'Use', use);
|
||||
Mota.register('module', 'Mark', mark);
|
||||
Mota.register('module', 'KeyCodes', keyCodes);
|
||||
Mota.register('module', 'UITools', {
|
||||
book: bookTools,
|
||||
common: commonTools,
|
||||
equipbox: equipboxTools,
|
||||
fixed: fixedTools,
|
||||
fly: flyTools,
|
||||
statusBar: statusBarTools,
|
||||
toolbox: toolboxTools
|
||||
});
|
||||
Mota.register('module', 'UI', UI);
|
||||
Mota.register('module', 'UIComponents', {
|
||||
Box,
|
||||
@ -126,7 +95,6 @@ Mota.register('module', 'UIComponents', {
|
||||
EnemyTarget,
|
||||
Keyboard: KeyboardPanel
|
||||
});
|
||||
Mota.register('module', 'MCGenerator', MCGenerator);
|
||||
Mota.register('module', 'Shadow', Shadow);
|
||||
Mota.register('module', 'Effect', {});
|
||||
Mota.register('module', 'Render', Render);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { KeyCode } from '@/plugin/keyCodes';
|
||||
import { KeyCode } from '@motajs/client';
|
||||
import { Hotkey, HotkeyData } from '../custom/hotkey';
|
||||
import type { HeroMover, IMoveController } from '@/game/state/move';
|
||||
import { Ticker } from 'mutate-animate';
|
||||
|
@ -8,7 +8,7 @@ import {
|
||||
getIconHeight,
|
||||
parseCss,
|
||||
tip
|
||||
} from '@/plugin/utils';
|
||||
} from '@motajs/legacy-ui';
|
||||
import axios, { AxiosResponse, toFormData } from 'axios';
|
||||
import { Component, VNode, h, shallowReactive } from 'vue';
|
||||
// /* @__PURE__ */ import { id, password } from '../../../../user';
|
||||
|
@ -1,5 +1,10 @@
|
||||
import { KeyCode } from '@/plugin/keyCodes';
|
||||
import { deleteWith, generateBinary, keycode, spliceBy } from '@/plugin/utils';
|
||||
import { KeyCode } from '@motajs/client';
|
||||
import {
|
||||
deleteWith,
|
||||
generateBinary,
|
||||
keycode,
|
||||
spliceBy
|
||||
} from '@motajs/legacy-ui';
|
||||
import { EventEmitter } from 'eventemitter3';
|
||||
import { isNil } from 'lodash-es';
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { EventEmitter, Listener } from '@motajs/legacy-common';
|
||||
import { KeyCode } from '@/plugin/keyCodes';
|
||||
import { KeyCode } from '@motajs/client';
|
||||
import { gameKey } from './hotkey';
|
||||
import { unwarpBinary } from './hotkey';
|
||||
import { deleteWith, flipBinary } from '@/plugin/utils';
|
||||
import { deleteWith, flipBinary } from '@motajs/legacy-ui';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { shallowReactive } from 'vue';
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { EventEmitter } from '@motajs/legacy-common';
|
||||
import { deleteWith, has } from '@/plugin/utils';
|
||||
import { deleteWith, has } from '@motajs/legacy-ui';
|
||||
import { Component, nextTick, reactive, shallowReactive } from 'vue';
|
||||
import { fixedUi } from '../init/ui';
|
||||
import { GameStorage } from '../storage';
|
||||
@ -126,48 +126,6 @@ const misc: Misc = {
|
||||
}
|
||||
};
|
||||
|
||||
const playingDefaultTool: MiscToolbar = {
|
||||
id: '@defaults_misc',
|
||||
type: 'misc',
|
||||
folded: false,
|
||||
noDefaultAction: true,
|
||||
items: [
|
||||
'book',
|
||||
'fly',
|
||||
'save',
|
||||
'load',
|
||||
'toolbox',
|
||||
'equipbox',
|
||||
'shop',
|
||||
'virtualKey',
|
||||
'setting',
|
||||
'undo',
|
||||
'redo',
|
||||
'viewMap',
|
||||
'danmaku',
|
||||
'minimap'
|
||||
]
|
||||
};
|
||||
const replayingDefaultTool: MiscToolbar = {
|
||||
id: '@defaults_misc',
|
||||
type: 'misc',
|
||||
folded: false,
|
||||
noDefaultAction: true,
|
||||
items: [
|
||||
'startReplay',
|
||||
'stopReplay',
|
||||
'rewindReplay',
|
||||
'stepReplay',
|
||||
'book',
|
||||
'speedDownReplay',
|
||||
'speedUpReplay',
|
||||
'save',
|
||||
'viewMap',
|
||||
'danmaku',
|
||||
'minimap'
|
||||
]
|
||||
};
|
||||
|
||||
export class CustomToolbar extends EventEmitter<CustomToolbarEvent> {
|
||||
static num: number = 0;
|
||||
static list: CustomToolbar[] = shallowReactive([]);
|
||||
@ -389,11 +347,11 @@ export class CustomToolbar extends EventEmitter<CustomToolbarEvent> {
|
||||
toolbarStorage.read();
|
||||
for (const [key, value] of Object.entries(toolbarStorage.data)) {
|
||||
const bar = this.get(key) ?? new CustomToolbar(key);
|
||||
bar.x = value.x;
|
||||
bar.y = value.y;
|
||||
bar.width = value.w;
|
||||
bar.height = value.h;
|
||||
for (const item of value.items) {
|
||||
bar.x = value!.x;
|
||||
bar.y = value!.y;
|
||||
bar.width = value!.w;
|
||||
bar.height = value!.h;
|
||||
for (const item of value!.items) {
|
||||
bar.add(item);
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,13 @@
|
||||
import { KeyCode } from '@/plugin/keyCodes';
|
||||
import { KeyCode } from '@motajs/client';
|
||||
import { gameKey, HotkeyJSON } from '../custom/hotkey';
|
||||
import { openDanmakuPoster, tip } from '@/plugin/utils';
|
||||
import {
|
||||
openDanmakuPoster,
|
||||
tip,
|
||||
hasMarkedEnemy,
|
||||
markEnemy,
|
||||
unmarkEnemy
|
||||
} from '@motajs/legacy-ui';
|
||||
import { hovered } from './fixed';
|
||||
import { hasMarkedEnemy, markEnemy, unmarkEnemy } from '@/plugin/mark';
|
||||
import { mainUi } from './ui';
|
||||
import { GameStorage } from '../storage';
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { KeyCode } from '@/plugin/keyCodes';
|
||||
import { KeyCode } from '@motajs/client';
|
||||
import { Keyboard } from '../custom/keyboard';
|
||||
|
||||
const qweKey = new Keyboard('qwe'); // 字母键盘,A-Z
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { KeyCode, KeyCodeUtils } from '@/plugin/keyCodes';
|
||||
import { KeyCode, KeyCodeUtils } from '@motajs/client';
|
||||
import { CustomToolbar } from '../custom/toolbar';
|
||||
import BoxAnimate from '@/components/boxAnimate.vue';
|
||||
import { checkAssist, unwarpBinary } from '../custom/hotkey';
|
||||
@ -6,7 +6,7 @@ import {
|
||||
flipBinary,
|
||||
getVitualKeyOnce,
|
||||
openDanmakuPoster
|
||||
} from '@/plugin/utils';
|
||||
} from '@motajs/legacy-ui';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import {
|
||||
Button,
|
||||
@ -18,11 +18,10 @@ import {
|
||||
import { MotaSettingItem, mainSetting } from '../setting';
|
||||
import Minimap from '@/components/minimap.vue';
|
||||
import { gameKey } from '../custom/hotkey';
|
||||
import { FunctionalComponent, StyleValue, h, ref } from 'vue';
|
||||
import { FunctionalComponent, h, ref } from 'vue';
|
||||
import { mainUi } from './ui';
|
||||
import { isMobile } from '@/plugin/use';
|
||||
import { isMobile } from '@motajs/legacy-ui';
|
||||
import {
|
||||
BackwardFilled,
|
||||
BackwardOutlined,
|
||||
BorderOuterOutlined,
|
||||
CaretRightOutlined,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import * as UI from '@ui/.';
|
||||
import { UI } from '@motajs/legacy-ui';
|
||||
import * as MiscUI from './misc';
|
||||
import { GameUi, UiController } from '../custom/ui';
|
||||
import { mainSetting } from '../setting';
|
||||
@ -26,7 +26,6 @@ mainUi.showAll();
|
||||
|
||||
export const fixedUi = new UiController(true);
|
||||
fixedUi.register(
|
||||
new GameUi('statusBar', UI.StatusBar),
|
||||
new GameUi('markedEnemy', UI.Marked),
|
||||
new GameUi('fixed', UI.Fixed),
|
||||
new GameUi('chapter', UI.Chapter),
|
||||
|
@ -1,509 +0,0 @@
|
||||
import {
|
||||
Component,
|
||||
RenderFunction,
|
||||
SetupContext,
|
||||
VNode,
|
||||
VNodeChild,
|
||||
defineComponent,
|
||||
h as hVue,
|
||||
isVNode,
|
||||
onMounted
|
||||
} from 'vue';
|
||||
import BoxAnimate from '@/components/boxAnimate.vue';
|
||||
import { ensureArray } from '@/plugin/utils';
|
||||
|
||||
interface VForRenderer {
|
||||
type: '@v-for';
|
||||
items: any[] | (() => any[]);
|
||||
map: (value: any, index: number) => VNode;
|
||||
}
|
||||
|
||||
interface MotaComponent extends MotaComponentConfig {
|
||||
type: string;
|
||||
children: (MComponent | MotaComponent | VNode)[];
|
||||
}
|
||||
|
||||
interface MotaComponentConfig {
|
||||
innerText?: string | (() => string);
|
||||
props?: Record<string, () => any>;
|
||||
component?: Component | MComponent;
|
||||
dComponent?: () => Component;
|
||||
/** 传递插槽 */
|
||||
slots?: Record<string, (props: Record<string, any>) => VNode | VNode[]>;
|
||||
vif?: () => boolean;
|
||||
velse?: boolean;
|
||||
}
|
||||
|
||||
type OnSetupFunction = (props: Record<string, any>, ctx: SetupContext) => void;
|
||||
type SetupFunction = (
|
||||
props: Record<string, any>,
|
||||
ctx: SetupContext
|
||||
) => RenderFunction | Promise<RenderFunction>;
|
||||
type RetFunction = (
|
||||
props: Record<string, any>,
|
||||
ctx: SetupContext
|
||||
) => VNodeChild | VNodeChild[];
|
||||
type OnMountedFunction = (
|
||||
props: Record<string, any>,
|
||||
ctx: SetupContext,
|
||||
canvas: HTMLCanvasElement[]
|
||||
) => void;
|
||||
|
||||
type NonComponentConfig = Omit<
|
||||
MotaComponentConfig,
|
||||
'innerText' | 'component' | 'slots' | 'dComponent'
|
||||
>;
|
||||
|
||||
type MComponentChildren =
|
||||
| (MComponent | MotaComponent | VNode)[]
|
||||
| MComponent
|
||||
| MotaComponent
|
||||
| VNode;
|
||||
|
||||
export class MComponent {
|
||||
static mountNum: number = 0;
|
||||
|
||||
content: (MotaComponent | VForRenderer)[] = [];
|
||||
|
||||
private onSetupFn?: OnSetupFunction;
|
||||
private setupFn?: SetupFunction;
|
||||
private onMountedFn?: OnMountedFunction;
|
||||
private retFn?: RetFunction;
|
||||
|
||||
private propsDef: Record<string, any> = {};
|
||||
private emitsDef: string[] = [];
|
||||
|
||||
/**
|
||||
* 定义一个props,是一个对象,键表示props名称,值表示类型,例如num: Number
|
||||
* 对于直接通过`UiController.open`方法打开的ui,应当包含以下两项
|
||||
* - num: ui的唯一标识符,类型为Number
|
||||
* - ui: 对于的GameUi实例,类型为GameUi
|
||||
* @param props 被定义的props
|
||||
*/
|
||||
defineProps(props: Record<string, any>) {
|
||||
this.propsDef = props;
|
||||
}
|
||||
|
||||
/**
|
||||
* 定义这个组件的emits,是一个字符串数组,表示emits的名称
|
||||
* @param emits 被定义的emits
|
||||
*/
|
||||
defineEmits(emits: string[]) {
|
||||
this.emitsDef = emits;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加一个div渲染内容
|
||||
* @param children 渲染内容的子内容
|
||||
* @param config 渲染内容的配置信息,参考 {@link MComponent.h}
|
||||
*/
|
||||
div(children?: MComponentChildren, config?: NonComponentConfig) {
|
||||
return this.h('div', children, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加一个span渲染内容
|
||||
* @param children 渲染内容的子内容
|
||||
* @param config 渲染内容的配置信息,参考 {@link MComponent.h}
|
||||
*/
|
||||
span(children?: MComponentChildren, config?: NonComponentConfig) {
|
||||
return this.h('span', children, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加一个canvas渲染内容
|
||||
* @param config 渲染内容的配置信息,参考 {@link MComponent.h}
|
||||
*/
|
||||
canvas(config?: NonComponentConfig) {
|
||||
return this.h('canvas', [], config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加一个文字渲染内容
|
||||
* @param text 要渲染的文字内容
|
||||
*/
|
||||
text(text: string | (() => string), config: NonComponentConfig = {}) {
|
||||
return this.h('text', [], { ...config, innerText: text });
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加一个组件渲染内容
|
||||
* @param component 要添加的组件
|
||||
* @param config 渲染内容的配置信息,参考 {@link MComponent.h}
|
||||
*/
|
||||
com(
|
||||
component: Component | MComponent,
|
||||
config?: Omit<MotaComponentConfig, 'innerText' | 'component'>
|
||||
) {
|
||||
return this.h(component, [], config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表渲染一系列内容
|
||||
* @param items 要遍历的列表,可以是一个数组,也可以是一个返回数组的函数
|
||||
* @param map 遍历函数,接收列表的每一项的值和索引,并返回一个VNode,VNode可以通过Vue.h函数,
|
||||
* 或者MComponent.vNode函数生成。
|
||||
*/
|
||||
vfor<T>(items: T[] | (() => T[]), map: (value: T, index: number) => VNode) {
|
||||
this.content.push(MCGenerator.vfor(items, map));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加渲染内容,注意区分组件和`MComponent`的区别,组件是经由`MComponent`的`export`函数输出的内容。
|
||||
* 该函数是对`Vue`的`h`函数的高度包装,将`h`函数抽象成为了一个模板,然后经由`export`函数导出后直接输出成为一个组件。
|
||||
* 而因此,几乎所有内容都要求传入一个函数,一般这个函数会在真正渲染的时候执行,并将返回值作为真正值传入。
|
||||
* 不过对于部分内容,例如`slots`和`vfor.map`,并不是这样的。具体用法请参考参数注释。
|
||||
* 注意如果使用了该包装,那么是无法实现响应式布局的,如果想要使用响应式布局,就必须调用`setup`方法,
|
||||
* 手写全部的`setup`函数。
|
||||
* @param type 要添加的渲染内容。
|
||||
* - 可以是一个字符串,表示dom元素,例如`div` `span`等,
|
||||
* - 可以是一个组件,也可以是一个`MComponent`,表示将其的导出作为组件。
|
||||
* - 除此之外,还可以填`text`,表示这个渲染内容是一个单独的文字,同时`children`会无效,
|
||||
* 必须填写`config`的`innerText`参数。
|
||||
* - 该值还可以是字符串`component`,表示动态组件,同时必须填入`config`的`component`参数,
|
||||
* 同时`children`会无效
|
||||
* - 该值不能填`@v-for`
|
||||
* @param children 该渲染内容的子内容。
|
||||
* - 可以是一个`MComponent`数组,数组内容即是子内容
|
||||
* - 也可以是一个`MComponent`,表示这个组件内容为子内容
|
||||
* @param config 渲染内容的配置内容,包含下列内容,均为可选。
|
||||
* - `innerText`: 当渲染内容为字符串时显示的内容,可以是字符串,或是返回字符串的函数
|
||||
* - `props`: 传入渲染内容的`props`,是一个对象,每个值都是一个函数,其返回值是真正传入的`props`
|
||||
* 对象的键是`prop`名称,如果是如`class` `id`这样的html属性,那么会视为其`attribute`,
|
||||
* 会符合`Vue`的`attribute`透传。对于以on开头,然后紧接着大写字母的属性,会被视为事件监听,
|
||||
* 即v-on
|
||||
* - `component`: 当为动态组件时,该项与`dComponent`必填其中之一,该项表示动态组件的内容
|
||||
* - `dComponent`: 当为动态组件时,该项与`component`必填其中之一,该项是一个函数,返回值表示动态组件的内容
|
||||
* 当`component`也填时,优先使用该项
|
||||
* - `slots`: 传递插槽,将内容传入渲染内容的插槽,是一个对象,每个对象都是一个函数,
|
||||
* 要求函数返回一个渲染VNode或数组,可以通过`MComponent.vNode`函数将组件转换成VNode数组,
|
||||
* 返回值直接作为插槽内容
|
||||
* - `vif`: 条件渲染,是一个函数,返回一个布尔值,表示条件是否满足,当`velse`为`true`时,
|
||||
* 条件渲染将会变成 `else-if`
|
||||
* - `velse`: 条件渲染,当前一个条件不满足时渲染该内容
|
||||
*/
|
||||
h(
|
||||
type: string | Component | MComponent,
|
||||
children?: MComponentChildren,
|
||||
config: MotaComponentConfig = {}
|
||||
): this {
|
||||
this.content.push(MCGenerator.h(type, children, config));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 当setup被执行时,要执行的函数,接受props,没有返回值,可以不设置
|
||||
*/
|
||||
onSetup(fn: OnSetupFunction) {
|
||||
this.onSetupFn = fn;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 当组件被挂载完毕后执行函数
|
||||
* @param fn 当组件被挂载完毕后执行的函数,接收props和当前级组件(不包含子组件)的所有画布作为参数
|
||||
* 当前级组件表示直接在当前组件中渲染的内容,不包括子组件,子组件的画布需要在其对应的函数中获取
|
||||
* 例如我在A组件中调用了B组件,那么我只能获取A组件的画布,而不能获取B组件的画布
|
||||
*/
|
||||
onMounted(fn: OnMountedFunction) {
|
||||
this.onMountedFn = fn;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 完全设置setup执行函数,接收props, slots,并返回一个函数,函数返回VNode,可以不设置
|
||||
*/
|
||||
setup(fn: SetupFunction) {
|
||||
this.setupFn = fn;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 完全设置setup返回的函数,可以不设置
|
||||
* @param fn setup返回的函数
|
||||
*/
|
||||
ret(fn: RetFunction) {
|
||||
this.retFn = fn;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将这个MComponent实例导出成为一个组件
|
||||
*/
|
||||
export() {
|
||||
if (!this.setupFn) {
|
||||
return defineComponent(
|
||||
(props, ctx) => {
|
||||
const mountNum = MComponent.mountNum++;
|
||||
this.onSetupFn?.(props, ctx);
|
||||
|
||||
onMounted(() => {
|
||||
this.onMountedFn?.(
|
||||
props,
|
||||
ctx,
|
||||
Array.from(
|
||||
document.getElementsByClassName(
|
||||
`--mota-component-canvas-${mountNum}`
|
||||
) as HTMLCollectionOf<HTMLCanvasElement>
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
if (this.retFn) return () => this.retFn!(props, ctx);
|
||||
else {
|
||||
return () => {
|
||||
const vNodes = MComponent.vNode(
|
||||
this.content,
|
||||
mountNum
|
||||
);
|
||||
return vNodes;
|
||||
};
|
||||
}
|
||||
},
|
||||
{
|
||||
emits: this.emitsDef,
|
||||
props: this.propsDef
|
||||
}
|
||||
);
|
||||
} else {
|
||||
return defineComponent((props, ctx) => this.setupFn!(props, ctx));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将单个渲染内容生成为一个单个的VNode
|
||||
* @param child 要生成的单个渲染内容
|
||||
* @param mount 组件生成时的挂载id,一般不需要填,用于画布获取
|
||||
*/
|
||||
static vNodeS(child: MotaComponent, mount?: number) {
|
||||
return this.vNode([child], mount)[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* 将一个MComponent实例生成为一个VNode列表
|
||||
* @param mc 要生成VNode的组件
|
||||
* @param mount 组件生成时的挂载id,一般不需要填,用于画布获取
|
||||
*/
|
||||
static vNodeM(mc: MComponent, mount?: number) {
|
||||
return this.vNode(mc.content, mount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将一系列MComponent内容生成为一个VNode列表
|
||||
* @param children 要生成VNode的内容列表
|
||||
* @param mount 组件生成时的挂载id,一般不需要填,用于画布获取
|
||||
*/
|
||||
static vNode(
|
||||
children: (MotaComponent | VForRenderer | VNode)[],
|
||||
mount?: number
|
||||
) {
|
||||
const mountNum = mount ?? this.mountNum++;
|
||||
|
||||
const res: VNode[] = [];
|
||||
const vifRes: Map<number, boolean> = new Map();
|
||||
children.forEach((v, i) => {
|
||||
if (isVNode(v)) {
|
||||
res.push(v);
|
||||
return;
|
||||
}
|
||||
if (v.type === '@v-for') {
|
||||
const node = v as VForRenderer;
|
||||
const items =
|
||||
typeof node.items === 'function'
|
||||
? node.items()
|
||||
: node.items;
|
||||
items.forEach((v, i) => {
|
||||
res.push(node.map(v, i));
|
||||
});
|
||||
} else {
|
||||
const node = v as MotaComponent;
|
||||
if (node.velse && vifRes.get(i - 1)) {
|
||||
vifRes.set(i, true);
|
||||
return;
|
||||
}
|
||||
let vif = true;
|
||||
if (node.vif) {
|
||||
vifRes.set(i, (vif = node.vif()));
|
||||
}
|
||||
if (!vif) return;
|
||||
const props = this.unwrapProps(node.props);
|
||||
if (v.type === 'component') {
|
||||
if (!v.component && !v.dComponent) {
|
||||
throw new Error(
|
||||
`Using dynamic component must provide component property.`
|
||||
);
|
||||
}
|
||||
if (v.dComponent) {
|
||||
res.push(hVue(v.dComponent(), props, v.slots));
|
||||
} else {
|
||||
if (v.component instanceof MComponent) {
|
||||
res.push(
|
||||
...MComponent.vNode(
|
||||
v.component.content,
|
||||
mountNum
|
||||
)
|
||||
);
|
||||
} else {
|
||||
res.push(hVue(v.component!, props, v.slots));
|
||||
}
|
||||
}
|
||||
} else if (v.type === 'text') {
|
||||
res.push(
|
||||
hVue(
|
||||
'span',
|
||||
typeof v.innerText === 'function'
|
||||
? v.innerText()
|
||||
: v.innerText
|
||||
)
|
||||
);
|
||||
} else if (v.type === 'canvas') {
|
||||
const cls = `--mota-component-canvas-${mountNum}`;
|
||||
const mix = !!props.class ? cls + ' ' + props.class : cls;
|
||||
props.class = mix;
|
||||
res.push(hVue('canvas', props, node.slots));
|
||||
} else {
|
||||
// 这个时候不可能会有插槽,只会有子内容,因此直接渲染子内容
|
||||
const content = node.children;
|
||||
const vn = this.vNode(
|
||||
content
|
||||
.map(v => (v instanceof MComponent ? v.content : v))
|
||||
.flat(),
|
||||
mountNum
|
||||
);
|
||||
res.push(hVue(v.type, props, vn));
|
||||
}
|
||||
}
|
||||
});
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取props的真实值。因为传入渲染内容的props是一个函数,因此需要一层调用
|
||||
* @param props 要获取的props
|
||||
*/
|
||||
static unwrapProps(props?: Record<string, () => any>): Record<string, any> {
|
||||
if (!props) return {};
|
||||
const res: Record<string, any> = {};
|
||||
for (const [key, value] of Object.entries(props)) {
|
||||
res[key] = value();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在渲染时给一个组件传递props。实际效果为在调用后并不会传递,当被传递的组件被渲染时,将会传递props。
|
||||
* @param component 要传递props的组件
|
||||
* @param props 要传递的props
|
||||
*/
|
||||
static prop(component: Component, props: Record<string, any>) {
|
||||
return hVue(component, props);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个MComponent实例,由于该函数在创建ui时会频繁使用,因此使用m这个简单的名字作为函数名
|
||||
* @returns 一个新的MComponent实例
|
||||
*/
|
||||
export function m() {
|
||||
return new MComponent();
|
||||
}
|
||||
|
||||
export namespace MCGenerator {
|
||||
export function h(
|
||||
type: string | Component | MComponent,
|
||||
children?: MComponentChildren,
|
||||
config: MotaComponentConfig = {}
|
||||
): MotaComponent {
|
||||
if (typeof type === 'string') {
|
||||
return {
|
||||
type,
|
||||
children: ensureArray(children ?? []),
|
||||
props: config.props,
|
||||
innerText: config.innerText,
|
||||
slots: config.slots,
|
||||
vif: config.vif,
|
||||
velse: config.velse,
|
||||
component: config.component
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
type: 'component',
|
||||
children: ensureArray(children ?? []),
|
||||
props: config.props,
|
||||
innerText: config.innerText,
|
||||
slots: config.slots,
|
||||
vif: config.vif,
|
||||
velse: config.velse,
|
||||
component: type
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export function div(
|
||||
children?: MComponentChildren,
|
||||
config?: NonComponentConfig
|
||||
): MotaComponent {
|
||||
return h('div', children, config);
|
||||
}
|
||||
|
||||
export function span(
|
||||
children?: MComponentChildren,
|
||||
config?: NonComponentConfig
|
||||
): MotaComponent {
|
||||
return h('span', children, config);
|
||||
}
|
||||
|
||||
export function canvas(config?: NonComponentConfig): MotaComponent {
|
||||
return h('canvas', [], config);
|
||||
}
|
||||
|
||||
export function text(
|
||||
text: string | (() => string),
|
||||
config: NonComponentConfig = {}
|
||||
): MotaComponent {
|
||||
return h('text', [], { ...config, innerText: text });
|
||||
}
|
||||
|
||||
export function com(
|
||||
component: Component | MComponent,
|
||||
config: Omit<MotaComponentConfig, 'innerText' | 'component'>
|
||||
): MotaComponent {
|
||||
return h(component, [], config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成一个图标的VNode
|
||||
* @param id 图标的id
|
||||
* @param width 显示宽度,单位像素
|
||||
* @param height 显示高度,单位像素
|
||||
* @param noBoarder 显示的时候是否没有边框和背景
|
||||
*/
|
||||
export function icon(
|
||||
id: AllIds,
|
||||
width?: number,
|
||||
height?: number,
|
||||
noBoarder?: number
|
||||
): VNode {
|
||||
return hVue(BoxAnimate, { id, width, height, noBoarder });
|
||||
}
|
||||
|
||||
export function vfor<T>(
|
||||
items: T[] | (() => T[]),
|
||||
map: (value: T, index: number) => VNode
|
||||
): VForRenderer {
|
||||
return {
|
||||
type: '@v-for',
|
||||
items,
|
||||
map
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 为一个常量创建为一个函数
|
||||
* @param value 要创建成函数的值
|
||||
*/
|
||||
export function f<T>(value: T): () => T {
|
||||
return () => value;
|
||||
}
|
||||
}
|
@ -1,11 +1,9 @@
|
||||
import { FunctionalComponent, reactive } from 'vue';
|
||||
import { EventEmitter } from '@motajs/legacy-common';
|
||||
import { GameStorage } from './storage';
|
||||
import { has, triggerFullscreen } from '@/plugin/utils';
|
||||
import { has, triggerFullscreen, isMobile } from '@motajs/legacy-ui';
|
||||
import { createSettingComponents } from './init/settings';
|
||||
import settingsText from '@/data/settings.json';
|
||||
import { isMobile } from '@/plugin/use';
|
||||
import { fontSize } from '@/plugin/ui/statusBar';
|
||||
import { CustomToolbar } from './custom/toolbar';
|
||||
import { fixedUi } from './init/ui';
|
||||
import { bgmController, soundPlayer } from '@/module';
|
||||
@ -361,7 +359,7 @@ function handleScreenSetting<T extends number | boolean>(
|
||||
storage.setValue('@@absoluteFontSize', absoluteSize);
|
||||
storage.write();
|
||||
} else if (key === 'fontSizeStatus') {
|
||||
fontSize.value = n as number;
|
||||
// fontSize.value = n as number;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { has } from '@/plugin/utils';
|
||||
import { isNil } from 'lodash-es';
|
||||
|
||||
export class GameStorage<T extends object = any> {
|
||||
static list: GameStorage<any>[] = [];
|
||||
|
||||
key: string;
|
||||
data!: T;
|
||||
data!: Partial<T>;
|
||||
|
||||
constructor(key: string) {
|
||||
this.key = key;
|
||||
@ -42,7 +42,7 @@ export class GameStorage<T extends object = any> {
|
||||
getValue<K extends keyof T>(key: K, defaults: T[K]): T[K];
|
||||
getValue<T>(key: string, defaults?: T): T;
|
||||
getValue<K extends keyof T>(key: K, defaults?: T[K]) {
|
||||
if (has(this.data[key])) return this.data[key];
|
||||
if (!isNil(this.data[key])) return this.data[key];
|
||||
else {
|
||||
if (defaults !== void 0) {
|
||||
this.data[key] = defaults;
|
||||
@ -57,7 +57,6 @@ export class GameStorage<T extends object = any> {
|
||||
}
|
||||
|
||||
clear() {
|
||||
// @ts-ignore
|
||||
this.data = {};
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@ import type { MotaSetting, SettingDisplayer } from '@/core/main/setting';
|
||||
import type { GameStorage } from '@/core/main/storage';
|
||||
import type { DamageEnemy, EnemyCollection } from './enemy/damage';
|
||||
import type { specials } from './enemy/special';
|
||||
import type { KeyCode } from '@/plugin/keyCodes';
|
||||
import type { KeyCode } from '@motajs/client';
|
||||
import type { Ref } from 'vue';
|
||||
import type * as battle from './enemy/battle';
|
||||
import type * as hero from './state/hero';
|
||||
@ -121,10 +121,7 @@ type InterfaceType = keyof SystemInterfaceMap;
|
||||
|
||||
interface PluginInterface {
|
||||
// 渲染进程定义的插件
|
||||
use_r: typeof import('../plugin/use');
|
||||
fly_r: typeof import('../plugin/ui/fly');
|
||||
chase_r: typeof import('../plugin/chase');
|
||||
completion_r: typeof import('../plugin/completion');
|
||||
gameCanvas_r: typeof import('../plugin/fx/gameCanvas');
|
||||
frag_r: typeof import('../plugin/fx/frag');
|
||||
boss_r: typeof import('../plugin/boss');
|
||||
|
@ -13,7 +13,7 @@ import {
|
||||
import { mainUi } from '@/core/main/init/ui';
|
||||
import { gameKey } from '@/core/main/custom/hotkey';
|
||||
import { generateKeyboardEvent } from '@/core/main/custom/keyboard';
|
||||
import { getVitualKeyOnce } from '@/plugin/utils';
|
||||
import { getVitualKeyOnce } from '@motajs/legacy-ui';
|
||||
import { getAllSavesData, getSaveData } from '@/module/utils';
|
||||
|
||||
export interface SettingsProps extends Partial<ChoicesProps>, UIComponentProps {
|
||||
|
@ -11,7 +11,7 @@ import {
|
||||
import { transitionedColor } from '../use';
|
||||
import { linear } from 'mutate-animate';
|
||||
import { Scroll } from '../components/scroll';
|
||||
import { getArea, MinimapDrawer } from '@/plugin/ui/fly';
|
||||
import { getArea, MinimapDrawer } from '@motajs/legacy-ui';
|
||||
import {
|
||||
NumpadToolbar,
|
||||
PlayingToolbar,
|
||||
|
@ -17,12 +17,12 @@ import {
|
||||
generateBinary,
|
||||
getVitualKeyOnce,
|
||||
openDanmakuPoster
|
||||
} from '@/plugin/utils';
|
||||
} from '@motajs/legacy-ui';
|
||||
import { gameKey } from '@/core/main/custom/hotkey';
|
||||
import { generateKeyboardEvent } from '@/core/main/custom/keyboard';
|
||||
import { transitioned } from '../use';
|
||||
import { linear } from 'mutate-animate';
|
||||
import { KeyCode } from '@/plugin/keyCodes';
|
||||
import { KeyCode } from '@motajs/client';
|
||||
import { Progress } from '../components/misc';
|
||||
|
||||
interface ToolbarProps extends DefaultProps {
|
||||
|
@ -8,6 +8,7 @@
|
||||
"@motajs/system-ui": "workspace:*",
|
||||
"@motajs/legacy-common": "workspace:*",
|
||||
"@motajs/legacy-client": "workspace:*",
|
||||
"@motajs/legacy-data": "workspace:*"
|
||||
"@motajs/legacy-data": "workspace:*",
|
||||
"@motajs/legacy-ui": "workspacee:*"
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@ import { Transform, MotaOffscreenCanvas2D } from '@motajs/render';
|
||||
import { IStateDamageable } from '@/game/state/interface';
|
||||
import { Hitbox, Projectile } from './barrage';
|
||||
import type { PalaceBoss } from './palaceBoss';
|
||||
import { clamp } from '../utils';
|
||||
import { clamp } from '@motajs/legacy-ui';
|
||||
|
||||
function popDamage(damage: number, boss: PalaceBoss, color: string) {
|
||||
const { x, y } = core.status.hero.loc;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Animation, hyper, linear, power, sleep } from 'mutate-animate';
|
||||
import { Chase, ChaseData, IChaseController } from './chase';
|
||||
import { completeAchievement } from '../ui/achievement';
|
||||
import { completeAchievement } from '@motajs/legacy-ui';
|
||||
import {
|
||||
Camera,
|
||||
CameraAnimation,
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Animation, linear, sleep } from 'mutate-animate';
|
||||
import { has } from '../utils';
|
||||
import { has } from '@motajs/legacy-ui';
|
||||
|
||||
// todo: 移植到渲染树
|
||||
|
||||
|
@ -1,25 +1,10 @@
|
||||
import * as fly from './ui/fly';
|
||||
import * as chase from './chase';
|
||||
import * as completion from './completion';
|
||||
import * as use from './use';
|
||||
import * as gameCanvas from './fx/gameCanvas';
|
||||
import * as animateController from './animateController';
|
||||
import * as achievement from './ui/achievement';
|
||||
import * as boss from './boss';
|
||||
import * as utils from './utils';
|
||||
import './loopMap';
|
||||
|
||||
Mota.Plugin.register('fly_r', fly);
|
||||
Mota.Plugin.register('chase_r', chase);
|
||||
Mota.Plugin.register('completion_r', completion, completion.init);
|
||||
Mota.Plugin.register('use_r', use);
|
||||
Mota.Plugin.register('gameCanvas_r', gameCanvas);
|
||||
Mota.Plugin.register(
|
||||
'animateController_r',
|
||||
animateController,
|
||||
animateController.default
|
||||
);
|
||||
Mota.Plugin.register('chase_r', chase);
|
||||
Mota.Plugin.register('achievement_r', achievement);
|
||||
Mota.Plugin.register('boss_r', boss);
|
||||
Mota.Plugin.register('utils_r', utils);
|
||||
|
@ -1,4 +0,0 @@
|
||||
import { ref } from 'vue';
|
||||
|
||||
export const status = ref(false);
|
||||
export const fontSize = ref(100);
|
@ -1,90 +0,0 @@
|
||||
<template>
|
||||
<Colomn @close="exit" :width="60" :height="80" :left="30" :right="70"
|
||||
><template #left>
|
||||
<div id="bgm-list">
|
||||
<span
|
||||
v-for="(bgm, i) of list"
|
||||
class="selectable"
|
||||
:selected="selected === i"
|
||||
@click="select(i)"
|
||||
>
|
||||
{{ bgm!.area }}
|
||||
</span>
|
||||
</div></template
|
||||
>
|
||||
<template #right
|
||||
><div>
|
||||
<div id="bgm-name">
|
||||
<img id="bgm-image" :src="list[selected]!.img" />
|
||||
<span>{{ name }}</span>
|
||||
<span v-if="list[selected]!.from"
|
||||
>出自 {{
|
||||
list[selected]!.from
|
||||
}}</span
|
||||
>
|
||||
</div>
|
||||
<span v-html="content"></span></div></template
|
||||
></Colomn>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import Colomn from '../components/colomn.vue';
|
||||
import bgm from '../data/bgm.json';
|
||||
import { splitText } from '../plugin/utils';
|
||||
import { mainUi } from '@/core/main/init/ui';
|
||||
|
||||
const props = defineProps<{
|
||||
num: number;
|
||||
}>();
|
||||
|
||||
interface Bgm {
|
||||
img: string;
|
||||
area: string;
|
||||
name: string;
|
||||
desc: string[];
|
||||
from?: string;
|
||||
}
|
||||
|
||||
const list = bgm as Partial<Record<BgmIds, Bgm>>;
|
||||
|
||||
const selected = ref<BgmIds>('title.opus');
|
||||
|
||||
const content = computed(() => {
|
||||
return eval('`' + splitText(list[selected.value]!.desc) + '`');
|
||||
});
|
||||
const name = computed(() => list[selected.value]!.name);
|
||||
|
||||
function exit() {
|
||||
mainUi.close(props.num);
|
||||
}
|
||||
|
||||
function select(id: BgmIds) {
|
||||
selected.value = id;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
#bgm-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#bgm-name {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#bgm-image {
|
||||
margin-top: 5%;
|
||||
border: 1px solid #fff;
|
||||
width: 33vw;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
#bgm-image {
|
||||
width: 70vw;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,393 +0,0 @@
|
||||
<template>
|
||||
<div id="status-bar">
|
||||
<Box
|
||||
:resizable="true"
|
||||
:dragable="true"
|
||||
v-model:width="width"
|
||||
v-model:height="height"
|
||||
>
|
||||
<Scroll
|
||||
id="status-main"
|
||||
v-model:update="updateStatus"
|
||||
:no-scroll="true"
|
||||
>
|
||||
<div id="status-div">
|
||||
<span
|
||||
id="status-floor"
|
||||
@click.stop="viewMap"
|
||||
class="button-text"
|
||||
>{{ floor }}</span
|
||||
>
|
||||
<span id="status-lv">{{ lvName }}</span>
|
||||
<div id="status-skill" class="status-item">
|
||||
<img :src="imgs['skill.png'].src" class="status-icon" />
|
||||
<span>{{ skill }}</span>
|
||||
<span
|
||||
v-if="has(spring)"
|
||||
id="status-spring"
|
||||
class="status-extra"
|
||||
>剩余{{ spring }}</span
|
||||
>
|
||||
</div>
|
||||
<div id="status-hp" class="status-item">
|
||||
<img :src="imgs['hp.png'].src" class="status-icon" />
|
||||
<span class="status-item-bold">{{
|
||||
format(hero.hp!)
|
||||
}}</span>
|
||||
<span
|
||||
id="status-hpmax"
|
||||
class="status-extra status-item-bold"
|
||||
>+{{
|
||||
format(Math.min(hero.hpmax!, hero.def! / 10))
|
||||
}}/t</span
|
||||
>
|
||||
<span
|
||||
v-if="jumpCnt !== -1"
|
||||
id="status-jump"
|
||||
class="status-extra"
|
||||
>跳跃剩余{{ jumpCnt }}</span
|
||||
>
|
||||
</div>
|
||||
<div id="status-atk" class="status-item">
|
||||
<img :src="imgs['atk.png'].src" class="status-icon" />
|
||||
<span class="status-item-bold">{{
|
||||
format(hero.atk!)
|
||||
}}</span>
|
||||
<span
|
||||
id="status-mana"
|
||||
class="status-extra status-item-bold"
|
||||
>+{{ format(hero.mana!) }}</span
|
||||
>
|
||||
</div>
|
||||
<div id="status-def" class="status-item status-item-bold">
|
||||
<img :src="imgs['def.png'].src" class="status-icon" />
|
||||
<span>{{ format(hero.def!) }}</span>
|
||||
<span
|
||||
v-if="hero.magicDef! > 0"
|
||||
id="status-magic-def"
|
||||
class="status-extra status-item-bold"
|
||||
>+{{ format(hero.magicDef!) }}</span
|
||||
>
|
||||
</div>
|
||||
<div id="status-mdef" class="status-item status-item-bold">
|
||||
<img :src="imgs['IQ.png'].src" class="status-icon" />
|
||||
<span>{{ format(hero.mdef!) }}</span>
|
||||
</div>
|
||||
<div id="status-money" class="status-item status-item-bold">
|
||||
<img :src="imgs['money.png'].src" class="status-icon" />
|
||||
<span>{{ format(hero.money!) }}</span>
|
||||
</div>
|
||||
<div id="status-exp" class="status-item status-item-bold">
|
||||
<img :src="imgs['exp.png'].src" class="status-icon" />
|
||||
<span>{{ format(up) }}</span>
|
||||
</div>
|
||||
<div id="status-key" class="status-item status-item-bold">
|
||||
<span style="color: #fca; padding-left: 10%">{{
|
||||
keys[0]?.toString().padStart(2, '0')
|
||||
}}</span>
|
||||
<span style="color: #aad">{{
|
||||
keys[1]?.toString().padStart(2, '0')
|
||||
}}</span>
|
||||
<span style="color: #f88; padding-right: 10%">{{
|
||||
keys[2]?.toString().padStart(2, '0')
|
||||
}}</span>
|
||||
</div>
|
||||
<div v-if="skillOpened" class="status-item">
|
||||
<span
|
||||
id="skill-tree"
|
||||
class="button-text"
|
||||
@click.stop="openSkillTree"
|
||||
>技能树</span
|
||||
>
|
||||
</div>
|
||||
<div v-if="skillOpened" class="status-item">
|
||||
<span
|
||||
id="status-skill"
|
||||
class="button-text"
|
||||
@click.stop="openSkill"
|
||||
>查看技能</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</Scroll>
|
||||
</Box>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, onUnmounted, ref, shallowReactive, watch } from 'vue';
|
||||
import Box from '../components/box.vue';
|
||||
import Scroll from '../components/scroll.vue';
|
||||
import { status } from '../plugin/ui/statusBar';
|
||||
import { isMobile } from '../plugin/use';
|
||||
import { fontSize } from '../plugin/ui/statusBar';
|
||||
import { has } from '@/plugin/utils';
|
||||
|
||||
let main: HTMLDivElement;
|
||||
|
||||
const imgs = core.material.images.images;
|
||||
|
||||
const width = ref(
|
||||
isMobile ? window.innerWidth - 60 : window.innerWidth * 0.175
|
||||
);
|
||||
const height = ref(isMobile ? 250 : window.innerHeight - 100);
|
||||
const updateStatus = ref(false);
|
||||
const format = core.formatBigNumber;
|
||||
|
||||
watch(width, n => (updateStatus.value = !updateStatus.value));
|
||||
watch(height, n => (updateStatus.value = !updateStatus.value));
|
||||
watch(fontSize, n => (main.style.fontSize = `${isMobile ? n * 1.5 : n}%`));
|
||||
|
||||
const HeroSkill = Mota.require('module', 'Mechanism').HeroSkill;
|
||||
|
||||
const hero = shallowReactive<Partial<HeroStatus>>({});
|
||||
const keys = shallowReactive<number[]>([]);
|
||||
const floor = ref<string>();
|
||||
const lvName = ref<string>();
|
||||
const skill = ref<string>(HeroSkill.getAutoSkill() ? '自动切换' : '无');
|
||||
const up = ref(0);
|
||||
const spring = ref<number>();
|
||||
const skillOpened = ref(core.getFlag('chapter', 0) > 0);
|
||||
const jumpCnt = ref<number>();
|
||||
/**
|
||||
* 要展示的勇士属性
|
||||
*/
|
||||
const toShow: (keyof HeroStatus)[] = [
|
||||
'hp', // 生命
|
||||
'atk', // 攻击
|
||||
'def', // 防御
|
||||
'mdef', // 智力
|
||||
'hpmax', // 生命回复
|
||||
'mana', // 额外攻击
|
||||
'money', // 金币
|
||||
'exp', // 经验
|
||||
'lv', // 等级
|
||||
'magicDef' // 魔法防御
|
||||
];
|
||||
|
||||
watch(status, update);
|
||||
|
||||
/**
|
||||
* 更新显示内容
|
||||
*/
|
||||
function update() {
|
||||
toShow.forEach(v => {
|
||||
hero[v] = Mota.requireAll('fn').getHeroStatusOn(v);
|
||||
});
|
||||
keys[0] = core.itemCount('yellowKey');
|
||||
keys[1] = core.itemCount('blueKey');
|
||||
keys[2] = core.itemCount('redKey');
|
||||
floor.value = core.status.thisMap?.title;
|
||||
lvName.value = core.getLvName(hero.lv);
|
||||
|
||||
if (HeroSkill.getAutoSkill()) {
|
||||
skill.value = '自动切换';
|
||||
} else {
|
||||
const enabled = HeroSkill.getEnabled();
|
||||
switch (enabled) {
|
||||
case HeroSkill.Blade:
|
||||
skill.value = '断灭之刃';
|
||||
break;
|
||||
case HeroSkill.Shield:
|
||||
skill.value = '铸剑为盾';
|
||||
break;
|
||||
default:
|
||||
skill.value = '无';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
up.value = core.getNextLvUpNeed() ?? 0;
|
||||
if (core.hasFlag('spring')) {
|
||||
spring.value = 50 - (flags.springCount ?? 0);
|
||||
} else {
|
||||
spring.value = void 0;
|
||||
}
|
||||
skillOpened.value = core.getFlag('chapter', 0) > 0;
|
||||
|
||||
jumpCnt.value =
|
||||
!HeroSkill.learnedSkill(HeroSkill.Jump) ||
|
||||
Mota.Plugin.require('skill_g').jumpIgnoreFloor.has(core.status.floorId)
|
||||
? -1
|
||||
: 3 - (flags[`jump_${core.status.floorId}`] ?? 0);
|
||||
}
|
||||
|
||||
function openSkillTree() {
|
||||
core.useItem('skill1');
|
||||
}
|
||||
|
||||
function openSkill() {
|
||||
core.useItem('cross');
|
||||
}
|
||||
|
||||
function viewMap() {
|
||||
core.ui._drawViewMaps();
|
||||
}
|
||||
|
||||
function openStudy() {}
|
||||
|
||||
function resize() {
|
||||
requestAnimationFrame(() => {
|
||||
main.style.fontSize = `${
|
||||
isMobile ? fontSize.value * 1.5 : fontSize.value
|
||||
}%`;
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
update();
|
||||
main = document.getElementById('status-main') as HTMLDivElement;
|
||||
|
||||
window.addEventListener('resize', resize);
|
||||
resize();
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('resize', resize);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
#status-main {
|
||||
background-color: #0009;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 1vh 0;
|
||||
font-size: v-bind(fontSize);
|
||||
}
|
||||
|
||||
.status-item {
|
||||
position: relative;
|
||||
max-width: 17.5vw;
|
||||
font-size: 200%;
|
||||
width: 100%;
|
||||
margin-bottom: 14px;
|
||||
text-shadow:
|
||||
3px 2px 3px #000,
|
||||
0px 0px 3px #111;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.status-item-bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.status-icon {
|
||||
width: 2.8vw;
|
||||
height: 2.8vw;
|
||||
margin-right: 10%;
|
||||
margin-left: 10%;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.status-value {
|
||||
transform: translateY(2px);
|
||||
}
|
||||
|
||||
#status-header {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#status-div {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#status-floor {
|
||||
max-width: 17.5vw;
|
||||
font-size: 200%;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
text-shadow:
|
||||
3px 2px 3px #000,
|
||||
0px 0px 3px #111;
|
||||
}
|
||||
|
||||
#status-lv {
|
||||
max-width: 17.5vw;
|
||||
font-size: 200%;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
text-shadow:
|
||||
3px 2px 3px #000,
|
||||
0px 0px 3px #111;
|
||||
}
|
||||
|
||||
.status-extra {
|
||||
position: absolute;
|
||||
right: 10%;
|
||||
bottom: 0;
|
||||
font-size: 75%;
|
||||
}
|
||||
|
||||
#status-mana {
|
||||
line-height: 0;
|
||||
color: rgb(255, 211, 211);
|
||||
}
|
||||
|
||||
#status-magic-def {
|
||||
line-height: 0;
|
||||
color: rgb(176, 189, 255);
|
||||
}
|
||||
|
||||
#status-hpmax {
|
||||
line-height: 0;
|
||||
color: rgb(167, 255, 167);
|
||||
}
|
||||
|
||||
#status-spring {
|
||||
line-height: 0;
|
||||
color: rgb(167, 255, 167);
|
||||
top: 0;
|
||||
font-size: 75%;
|
||||
}
|
||||
|
||||
#status-jump {
|
||||
line-height: 0;
|
||||
top: 0;
|
||||
font-size: 75%;
|
||||
}
|
||||
|
||||
#status-key {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
#skill-tree,
|
||||
#status-skill {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
.status-item {
|
||||
max-width: 40vw;
|
||||
font-size: 120%;
|
||||
}
|
||||
|
||||
#status-floor {
|
||||
max-width: 40vw;
|
||||
font-size: 120%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#status-lv {
|
||||
max-width: 40vw;
|
||||
font-size: 120%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.status-icon {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue
Block a user