2022-11-14 17:11:23 +08:00
|
|
|
|
<!-- 怪物手册ui -->
|
|
|
|
|
<template>
|
2022-11-16 23:01:23 +08:00
|
|
|
|
<div id="book">
|
2022-11-19 13:07:42 +08:00
|
|
|
|
<div id="tools">
|
2022-11-30 16:42:44 +08:00
|
|
|
|
<span id="back" class="button-text tools" @click="exit"
|
2022-11-19 13:07:42 +08:00
|
|
|
|
><left-outlined />返回游戏</span
|
|
|
|
|
>
|
|
|
|
|
</div>
|
2022-11-16 23:01:23 +08:00
|
|
|
|
<div v-if="enemy.length === 0" id="none">
|
|
|
|
|
<div>本层无怪物</div>
|
|
|
|
|
</div>
|
2022-11-19 11:30:14 +08:00
|
|
|
|
<Scroll
|
|
|
|
|
v-else
|
2022-11-30 16:42:44 +08:00
|
|
|
|
style="width: 100%; height: 94%; font-family: normal"
|
2022-11-19 11:30:14 +08:00
|
|
|
|
v-model:now="scroll"
|
|
|
|
|
v-model:drag="drag"
|
|
|
|
|
>
|
2023-07-31 16:49:04 +08:00
|
|
|
|
<div v-for="(e, i) of toShow" class="enemy">
|
2022-11-19 18:15:42 +08:00
|
|
|
|
<EnemyOne
|
|
|
|
|
:selected="i === selected"
|
|
|
|
|
:enemy="e"
|
|
|
|
|
:key="i"
|
|
|
|
|
@select="select(e, i)"
|
|
|
|
|
@hover="selected = i"
|
|
|
|
|
></EnemyOne>
|
2022-11-16 23:01:23 +08:00
|
|
|
|
<a-divider
|
|
|
|
|
dashed
|
|
|
|
|
style="width: 100%; border-color: #ddd4"
|
|
|
|
|
></a-divider>
|
|
|
|
|
</div>
|
|
|
|
|
</Scroll>
|
|
|
|
|
</div>
|
2023-01-06 22:18:33 +08:00
|
|
|
|
<BookDetail
|
|
|
|
|
v-if="detail"
|
|
|
|
|
:from-book="true"
|
|
|
|
|
@close="closeDetail()"
|
|
|
|
|
></BookDetail>
|
2022-11-14 17:11:23 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup lang="tsx">
|
2022-11-19 11:30:14 +08:00
|
|
|
|
import { sleep } from 'mutate-animate';
|
2022-11-19 18:15:42 +08:00
|
|
|
|
import { onMounted, onUnmounted, ref } from 'vue';
|
2022-11-16 23:01:23 +08:00
|
|
|
|
import EnemyOne from '../components/enemyOne.vue';
|
2022-11-14 17:11:23 +08:00
|
|
|
|
import Scroll from '../components/scroll.vue';
|
2022-12-28 12:13:52 +08:00
|
|
|
|
import { getDamageColor, has, keycode } from '../plugin/utils';
|
2022-11-19 11:30:14 +08:00
|
|
|
|
import BookDetail from './bookDetail.vue';
|
2022-11-19 13:07:42 +08:00
|
|
|
|
import { LeftOutlined } from '@ant-design/icons-vue';
|
2022-11-19 18:15:42 +08:00
|
|
|
|
import { KeyCode } from '../plugin/keyCodes';
|
2022-12-28 12:13:52 +08:00
|
|
|
|
import { noClosePanel } from '../plugin/uiController';
|
2023-08-01 11:09:23 +08:00
|
|
|
|
import { ToShowEnemy, detailInfo } from '../plugin/ui/book';
|
2022-11-14 17:11:23 +08:00
|
|
|
|
|
2022-12-27 23:31:14 +08:00
|
|
|
|
const floorId =
|
2022-12-28 12:13:52 +08:00
|
|
|
|
// @ts-ignore
|
|
|
|
|
core.floorIds[core.status.event?.ui?.index] ?? core.status.floorId;
|
|
|
|
|
|
2023-08-01 11:09:23 +08:00
|
|
|
|
const specials = Object.fromEntries(
|
|
|
|
|
core.getSpecials().map(v => {
|
|
|
|
|
return [v[0], v.slice(1)];
|
|
|
|
|
})
|
|
|
|
|
) as Record<
|
|
|
|
|
string,
|
|
|
|
|
EnemySpecialDeclaration extends [number, ...infer F] ? F : never
|
|
|
|
|
>;
|
|
|
|
|
|
2022-11-14 17:11:23 +08:00
|
|
|
|
const enemy = core.getCurrentEnemys(floorId);
|
2023-07-31 16:49:04 +08:00
|
|
|
|
const toShow: ToShowEnemy[] = enemy.map(v => {
|
2023-08-02 15:20:39 +08:00
|
|
|
|
const e = v.enemy;
|
|
|
|
|
const dam = e.calDamage().damage;
|
|
|
|
|
const cri = e.calCritical(1);
|
2023-07-31 16:49:04 +08:00
|
|
|
|
const critical = core.formatBigNumber(cri[0]?.atkDelta);
|
|
|
|
|
const criticalDam = core.formatBigNumber(-cri[0]?.delta);
|
|
|
|
|
const ratio = core.status.maps[floorId].ratio;
|
2023-08-02 15:20:39 +08:00
|
|
|
|
const defDam = core.formatBigNumber(-e.calDefDamage(ratio).delta);
|
|
|
|
|
const damage = core.formatBigNumber(dam);
|
2023-07-31 16:49:04 +08:00
|
|
|
|
|
|
|
|
|
const fromFunc = (
|
|
|
|
|
func: string | ((enemy: Enemy) => string),
|
|
|
|
|
enemy: Enemy
|
|
|
|
|
) => {
|
|
|
|
|
return typeof func === 'string' ? func : func(enemy);
|
|
|
|
|
};
|
|
|
|
|
const special: [string, string, string][] = v.enemy.enemy.special.map(
|
|
|
|
|
vv => {
|
|
|
|
|
const s = specials[vv];
|
|
|
|
|
return [
|
|
|
|
|
fromFunc(s[0], v.enemy.enemy),
|
|
|
|
|
fromFunc(s[1], v.enemy.enemy),
|
|
|
|
|
s[2] as string
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
const showSpecial =
|
|
|
|
|
special.length > 2
|
|
|
|
|
? special.slice(0, 2).concat(['...', '', '#fff'])
|
|
|
|
|
: special.slice();
|
|
|
|
|
|
2023-08-02 15:20:39 +08:00
|
|
|
|
const damageColor = getDamageColor(dam) as string;
|
2023-07-31 16:49:04 +08:00
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
critical,
|
|
|
|
|
criticalDam,
|
|
|
|
|
defDam,
|
|
|
|
|
special,
|
|
|
|
|
damageColor,
|
|
|
|
|
showSpecial,
|
|
|
|
|
damage,
|
|
|
|
|
...v
|
|
|
|
|
};
|
|
|
|
|
});
|
2022-11-16 23:01:23 +08:00
|
|
|
|
|
2022-11-19 11:30:14 +08:00
|
|
|
|
const scroll = ref(0);
|
|
|
|
|
const drag = ref(false);
|
|
|
|
|
const detail = ref(false);
|
2022-11-19 18:15:42 +08:00
|
|
|
|
const selected = ref(0);
|
2022-11-19 11:30:14 +08:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 选择怪物,展示详细信息
|
|
|
|
|
* @param enemy 选择的怪物
|
|
|
|
|
* @param index 选择的怪物索引
|
|
|
|
|
*/
|
2023-07-31 16:49:04 +08:00
|
|
|
|
function select(enemy: ToShowEnemy, index: number) {
|
2022-11-19 11:30:14 +08:00
|
|
|
|
if (drag.value) return;
|
|
|
|
|
const h = window.innerHeight;
|
|
|
|
|
const y = index * h * 0.2 - scroll.value;
|
2023-07-31 16:49:04 +08:00
|
|
|
|
detailInfo.enemy = enemy;
|
|
|
|
|
detailInfo.pos = y;
|
2022-11-19 11:30:14 +08:00
|
|
|
|
detail.value = true;
|
|
|
|
|
hide();
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-19 18:15:42 +08:00
|
|
|
|
/**
|
|
|
|
|
* 隐藏怪物手册
|
|
|
|
|
*/
|
2022-11-19 11:30:14 +08:00
|
|
|
|
async function hide() {
|
|
|
|
|
const div = document.getElementById('book') as HTMLDivElement;
|
|
|
|
|
div.style.opacity = '0';
|
|
|
|
|
await sleep(600);
|
|
|
|
|
div.style.display = 'none';
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-19 18:15:42 +08:00
|
|
|
|
/**
|
|
|
|
|
* 关闭详细信息
|
|
|
|
|
*/
|
2022-11-19 11:30:14 +08:00
|
|
|
|
async function closeDetail() {
|
|
|
|
|
show();
|
|
|
|
|
await sleep(600);
|
|
|
|
|
detail.value = false;
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-19 18:15:42 +08:00
|
|
|
|
/**
|
|
|
|
|
* 显示怪物手册
|
|
|
|
|
*/
|
2022-11-19 11:30:14 +08:00
|
|
|
|
async function show() {
|
|
|
|
|
const div = document.getElementById('book') as HTMLDivElement;
|
2022-11-19 13:07:42 +08:00
|
|
|
|
div.style.display = 'flex';
|
2022-11-19 11:30:14 +08:00
|
|
|
|
await sleep(50);
|
|
|
|
|
div.style.opacity = '1';
|
|
|
|
|
}
|
2022-11-19 13:07:42 +08:00
|
|
|
|
|
2022-11-19 18:15:42 +08:00
|
|
|
|
/**
|
|
|
|
|
* 退出怪物手册
|
|
|
|
|
*/
|
2022-12-28 12:13:52 +08:00
|
|
|
|
async function exit() {
|
|
|
|
|
noClosePanel.value = true;
|
2023-08-01 12:22:05 +08:00
|
|
|
|
ancTe.plugin.ui.bookOpened.value = false;
|
|
|
|
|
if (ancTe.plugin.ui.transition.value) await sleep(650);
|
2022-12-29 00:26:12 +08:00
|
|
|
|
else await sleep(100);
|
2022-12-28 12:13:52 +08:00
|
|
|
|
if (core.events.recoverEvents(core.status.event.interval)) {
|
|
|
|
|
return;
|
|
|
|
|
} else if (has(core.status.event.ui)) {
|
|
|
|
|
core.status.boxAnimateObjs = [];
|
|
|
|
|
// @ts-ignore
|
|
|
|
|
core.ui._drawViewMaps(core.status.event.ui);
|
|
|
|
|
} else core.ui.closePanel();
|
2022-11-19 13:07:42 +08:00
|
|
|
|
}
|
2022-11-19 18:15:42 +08:00
|
|
|
|
|
|
|
|
|
function checkScroll() {
|
|
|
|
|
const h = window.innerHeight;
|
|
|
|
|
const y = selected.value * h * 0.2 - scroll.value;
|
|
|
|
|
if (y < 0) {
|
|
|
|
|
scroll.value += y - 20;
|
|
|
|
|
}
|
|
|
|
|
if (y > h * 0.655) {
|
|
|
|
|
scroll.value += y - h * 0.655 + 20;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 键盘松开时
|
|
|
|
|
*/
|
|
|
|
|
function keyup(e: KeyboardEvent) {
|
|
|
|
|
const c = keycode(e.keyCode);
|
|
|
|
|
if (c === KeyCode.KeyX || c === KeyCode.Escape) {
|
|
|
|
|
exit();
|
|
|
|
|
}
|
2023-04-22 10:04:03 +08:00
|
|
|
|
if (
|
|
|
|
|
(c === KeyCode.Enter || c === KeyCode.KeyC || c === KeyCode.Space) &&
|
|
|
|
|
!detail.value
|
|
|
|
|
) {
|
2023-07-31 16:49:04 +08:00
|
|
|
|
select(toShow[selected.value], selected.value);
|
2022-11-19 18:15:42 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 键盘按下时
|
|
|
|
|
*/
|
|
|
|
|
function keydown(e: KeyboardEvent) {
|
|
|
|
|
const c = keycode(e.keyCode);
|
|
|
|
|
if (!detail.value) {
|
|
|
|
|
if (c === KeyCode.DownArrow) {
|
|
|
|
|
if (selected.value < enemy.length - 1) {
|
|
|
|
|
selected.value++;
|
|
|
|
|
}
|
|
|
|
|
checkScroll();
|
|
|
|
|
}
|
|
|
|
|
if (c === KeyCode.UpArrow) {
|
|
|
|
|
if (selected.value > 0) {
|
|
|
|
|
selected.value--;
|
|
|
|
|
}
|
|
|
|
|
checkScroll();
|
|
|
|
|
}
|
|
|
|
|
// 一次移动5个怪物
|
|
|
|
|
if (c === KeyCode.LeftArrow || c === KeyCode.PageUp) {
|
|
|
|
|
if (selected.value <= 4) {
|
|
|
|
|
selected.value = 0;
|
|
|
|
|
} else {
|
|
|
|
|
selected.value -= 5;
|
|
|
|
|
}
|
|
|
|
|
checkScroll();
|
|
|
|
|
}
|
|
|
|
|
if (c === KeyCode.RightArrow || c === KeyCode.PageDown) {
|
|
|
|
|
if (selected.value >= enemy.length - 5) {
|
|
|
|
|
selected.value = enemy.length - 1;
|
|
|
|
|
} else {
|
|
|
|
|
selected.value += 5;
|
|
|
|
|
}
|
|
|
|
|
checkScroll();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onMounted(async () => {
|
2023-08-01 12:22:05 +08:00
|
|
|
|
if (ancTe.plugin.ui.transition.value) await sleep(600);
|
2022-12-29 13:39:40 +08:00
|
|
|
|
else await sleep(50);
|
2022-11-19 18:15:42 +08:00
|
|
|
|
document.addEventListener('keyup', keyup);
|
|
|
|
|
document.addEventListener('keydown', keydown);
|
|
|
|
|
});
|
|
|
|
|
|
2022-11-21 20:00:34 +08:00
|
|
|
|
onUnmounted(async () => {
|
2022-11-19 18:15:42 +08:00
|
|
|
|
document.removeEventListener('keyup', keyup);
|
|
|
|
|
document.removeEventListener('keydown', keydown);
|
|
|
|
|
});
|
2022-11-14 17:11:23 +08:00
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style lang="less" scoped>
|
2022-11-16 23:01:23 +08:00
|
|
|
|
#book {
|
|
|
|
|
user-select: none;
|
|
|
|
|
width: 80%;
|
|
|
|
|
height: 100%;
|
|
|
|
|
font-family: 'normal';
|
|
|
|
|
overflow: hidden;
|
2022-11-19 11:30:14 +08:00
|
|
|
|
transition: opacity 0.6s linear;
|
2022-11-19 13:07:42 +08:00
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
justify-content: space-between;
|
2022-11-16 23:01:23 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-11-19 13:07:42 +08:00
|
|
|
|
#tools {
|
2022-11-30 16:42:44 +08:00
|
|
|
|
height: 6%;
|
2022-12-29 19:57:31 +08:00
|
|
|
|
font-size: 3.2vh;
|
2022-11-19 13:07:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-11-16 23:01:23 +08:00
|
|
|
|
#none {
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 100%;
|
2022-12-28 20:34:23 +08:00
|
|
|
|
font-size: 6vw;
|
2022-11-16 23:01:23 +08:00
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
align-items: center;
|
|
|
|
|
font-family: 'normal';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.enemy {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
height: 20vh;
|
|
|
|
|
width: 100%;
|
|
|
|
|
padding: 0 1% 0 1%;
|
2022-11-14 17:11:23 +08:00
|
|
|
|
}
|
2022-11-19 13:07:42 +08:00
|
|
|
|
|
|
|
|
|
@media screen and (max-width: 600px) {
|
|
|
|
|
#book {
|
|
|
|
|
width: 100%;
|
2022-12-31 19:49:43 +08:00
|
|
|
|
padding: 5%;
|
2022-11-19 13:07:42 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2022-11-14 17:11:23 +08:00
|
|
|
|
</style>
|