优化怪物手册,状态栏初步

This commit is contained in:
unanmed 2022-12-28 12:13:52 +08:00
parent ed4b0fe730
commit 0ecdcbdf34
22 changed files with 153 additions and 30 deletions

View File

@ -9277,5 +9277,17 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = {
ui.prototype._drawEquipbox = function () {
return (core.plugin.equipOpened.value = true);
};
control.prototype.updateStatusBar_update = function () {
if (!core.isPlaying() || core.hasFlag('__statistics__')) return;
core.control.controldata.updateStatusBar();
if (!core.control.noAutoEvents) core.checkAutoEvents();
core.control._updateStatusBar_setToolboxIcon();
core.clearRouteFolding();
core.control.noAutoEvents = true;
// 更新vue状态栏
core.plugin.statusBarStatus.value =
!core.plugin.statusBarStatus.value;
};
}
};

View File

@ -543,8 +543,3 @@ p#name {
overflow: visible;
height: 100%;
}
@font-face {
font-family: Fira Code;
src: url(../src/fonts/FiraCode-Regular.ttf);
}

View File

@ -14,7 +14,7 @@ import { has } from '../plugin/utils';
const id = (Math.random() * 1e8).toFixed(0);
const props = defineProps<{
id: string;
id: AllIds | 'hero';
noborder?: boolean;
width?: number;
height?: number;
@ -29,7 +29,7 @@ function draw() {
if (id === 'none') return;
if (has(drawFn)) removeAnimate(drawFn);
const cls = core.getClsFromId(props.id);
const cls = core.getClsFromId(props.id as AllIds);
const frames = core.getAnimateFrames(cls);
const w = props.width ?? 32;
const h = props.height ?? 32;

View File

@ -20,7 +20,7 @@
>
<span
v-for="(text, i) in enemy.toShowSpecial"
:style="{ color: enemy.toShowColor![i] }"
:style="{ color: enemy.toShowColor![i] as string }"
>&nbsp;{{ text }}&nbsp;</span
>
</div>
@ -93,20 +93,23 @@
? 'gold'
: 'lightpink'
}"
><span style="font-family: 'Fira Code'">{{
enemy.criticalDamage < 0 ? '=>' : ''
}}</span
>{{
core.formatBigNumber(
enemy.criticalDamage,
false,
enemy.criticalDamage < 0
? -enemy.criticalDamage
: enemy.criticalDamage
)
}}</span
></span
>
</div>
<div class="detail-info">
<span :style="{color: enemy.damageColor!}"
<span :style="{color: enemy.damageColor! as string}"
>伤害&nbsp;&nbsp;&nbsp;&nbsp;{{
core.formatBigNumber(enemy.damage)
core.formatBigNumber(enemy.damage!)
}}</span
>
</div>
@ -122,7 +125,7 @@ import BoxAnimate from '../components/boxAnimate.vue';
import { isMobile } from '../plugin/use';
const props = defineProps<{
enemy: Enemy & DetailedEnemy;
enemy: DetailedEnemy;
selected?: boolean;
}>();

Binary file not shown.

View File

@ -4,10 +4,11 @@ import ui from './plugin/uiController';
import use from './plugin/use';
import animate from './plugin/animateController';
import utils from './plugin/utils';
import status from './plugin/ui/statusBar';
window.addEventListener('load', () => {
// 每个引入的插件都要在这里执行,否则不会被转发
const toForward: any[] = [pop(), ui(), use(), animate(), utils()];
const toForward: any[] = [pop(), ui(), use(), animate(), utils(), status()];
// 初始化所有插件并转发到core上
(async function () {

View File

@ -61,7 +61,16 @@
isMobile ? '' : '&nbsp;&nbsp;&nbsp;&nbsp;'
}}</span
>
<span>{{ format(nowDamage[0], false, nowDamage[0] < 0) }}</span>
<span
><span style="font-family: 'Fira Code'">{{
nowDamage[0] < 0 ? '=>' : ''
}}</span
>{{
nowDamage[0] < 0
? format(-nowDamage[0])
: format(nowDamage[0])
}}</span
>
</div>
<div>
<span

View File

@ -20,9 +20,12 @@
</div>
<div v-for="[atk, dam] of criticals" class="critical">
<span class="critical-atk">{{ format(atk) }}</span>
<span>{{
dam < 0 ? `->&nbsp;${format(-dam)}` : format(dam)
}}</span>
<span
><span style="font-family: 'Fira Code'">{{
dam < 0 ? '=>' : ''
}}</span
>{{ dam < 0 ? `${format(-dam)}` : format(dam) }}</span
>
</div>
</div>
</div>

View File

@ -75,7 +75,6 @@ export function getDefDamage(
if (!has(dam)) continue;
if (dam.damage === origin) continue;
if (dam.damage === res.at(-1)?.[1]) continue;
if (last === dam.damage) break;
last = dam.damage;
res.push([ratio * i + addDef, dam.damage]);
}
@ -121,7 +120,6 @@ export function getCriticalDamage(
if (!has(dam)) continue;
if (dam.damage === origin) continue;
if (dam.damage === res.at(-1)?.[1]) continue;
if (last === dam.damage) break;
last = dam.damage;
res.push([ratio * i + addAtk, dam.damage]);
}

View File

@ -0,0 +1,9 @@
import { ref } from 'vue';
const status = ref(false);
export default function init() {
return { statusBarStatus: status };
}
export { status };

View File

@ -9,6 +9,7 @@ export const toolOpened = ref(false);
export const equipOpened = ref(false);
export const transition = ref(true);
export const noClosePanel = ref(false);
let app: HTMLDivElement;
@ -61,12 +62,14 @@ async function hideApp(index: number) {
await sleep(600);
uiStack.value.splice(index, 1);
app.style.display = 'none';
core.closePanel();
if (!noClosePanel.value) core.closePanel();
noClosePanel.value = false;
} else {
app.style.transition = '';
app.style.opacity = '0';
uiStack.value.splice(index, 1);
app.style.display = 'none';
core.closePanel();
if (!noClosePanel.value) core.closePanel();
noClosePanel.value = false;
}
}

View File

@ -69,3 +69,8 @@
background-color: rgba(255, 0, 0, 0.319);
cursor: not-allowed;
}
@font-face {
font-family: Fira Code;
src: url(/src/fonts/FiraCode-Regular.ttf);
}

6
src/types/core.d.ts vendored
View File

@ -97,6 +97,8 @@ type MaterialImages = {
*
*/
tilesets: Record<string, HTMLImageElement>;
hero: HTMLImageElement;
};
interface Material {
@ -1448,3 +1450,7 @@ declare const maps_90f36752_8815_4be8_b32b_d7fad1d0542e: {
*
*/
declare const plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1: PluginDeclaration;
interface Window {
core: CoreMixin;
}

View File

@ -30,6 +30,9 @@ type DetailedEnemy<I extends EnemyIds = EnemyIds> = {
toShowColor: Color[];
specialColor: Color[];
damageColor: Color;
criticalDamage: number;
critical: number;
defDamage: number;
} & Enemy<I>;
type Enemy<I extends EnemyIds = EnemyIds> = {

View File

@ -299,7 +299,7 @@ interface Events extends EventData {
*
* @param data
*/
recoverEvents(data?: any): void;
recoverEvents(data?: any): boolean;
/**
*

6
src/types/icon.d.ts vendored
View File

@ -66,6 +66,12 @@ interface Icons {
* @param id id
*/
getTilesetOffset(id: string | number): IconOffsetInfo | null;
/**
*
* @param cls
*/
getAnimateFrames<T extends Cls>(cls: T): FrameOf<T>;
}
declare const icons: new () => Icons;

View File

@ -44,6 +44,9 @@ interface PluginDeclaration extends PluginUtils {
/** 装备栏是否打开 */
readonly equipOpened: Ref<boolean>;
/** 状态栏信息,取反后刷新状态栏 */
readonly statusBarStatus: Ref<boolean>;
/** ui栈 */
readonly uiStack: Ref<Component[]>;

View File

@ -10,12 +10,12 @@ type Cls =
| 'terrains'
| 'enemy48'
| 'npc48'
| 'tilesets';
| 'tileset';
/**
*
*/
type AnimatableCls = Exclude<Cls, 'items' | 'terrains' | 'tilesets'>;
type AnimatableCls = Exclude<Cls, 'items' | 'terrains' | 'tileset'>;
/**
*
@ -85,6 +85,7 @@ interface FrameNumbers {
terrains: 1;
enemy48: 4;
npc48: 4;
tileset: 1;
}
/**

2
src/types/ui.d.ts vendored
View File

@ -592,7 +592,7 @@ interface Ui {
*/
drawIcon(
name: CtxRefer,
id: AllIds,
id: AllIds | 'hero',
x: number,
y: number,
w?: number,

2
src/types/util.d.ts vendored
View File

@ -249,7 +249,7 @@ interface Utils {
* @param onMap
* @returns
*/
formatBigNumber(x: number, onMap?: number): string;
formatBigNumber(x: number | string, onMap?: number): string;
/**
* @deprecated

View File

@ -39,13 +39,21 @@ import { sleep } from 'mutate-animate';
import { onMounted, onUnmounted, ref } from 'vue';
import EnemyOne from '../components/enemyOne.vue';
import Scroll from '../components/scroll.vue';
import { getDamageColor, keycode } from '../plugin/utils';
import { getDamageColor, has, keycode } from '../plugin/utils';
import BookDetail from './bookDetail.vue';
import { LeftOutlined } from '@ant-design/icons-vue';
import { KeyCode } from '../plugin/keyCodes';
import { noClosePanel } from '../plugin/uiController';
const floorId =
core.floorIds[core.status.event?.ui as number] ?? core.status.floorId;
// @ts-ignore
core.floorIds[core.status.event?.ui?.index] ?? core.status.floorId;
//
if (floorId !== core.status.floorId && core.status.checkBlock) {
// @ts-ignore
core.status.checkBlock.cache = {};
}
const enemy = core.getCurrentEnemys(floorId);
const scroll = ref(0);
@ -116,8 +124,17 @@ async function show() {
/**
* 退出怪物手册
*/
function exit() {
async function exit() {
noClosePanel.value = true;
core.plugin.bookOpened.value = false;
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();
await sleep(650);
}
function checkScroll() {

49
src/ui/statusBar.vue Normal file
View File

@ -0,0 +1,49 @@
<template>
<div id="status-bar"></div>
</template>
<script lang="ts" setup>
import { ref, shallowReactive, watch } from 'vue';
import { isMobile } from '../plugin/use';
import { status } from '../plugin/ui/statusBar';
const width = ref(isMobile ? window.innerWidth : 300);
const height = ref(isMobile ? 300 : window.innerHeight - 100);
const left = ref(isMobile ? 0 : 50);
const top = ref(50);
const hero = shallowReactive<Partial<HeroStatus>>({});
const floor = ref<string>();
/**
* 要展示的勇士属性
*/
const toShow: (keyof NumbericHeroStatus)[] = [
'hp', //
'atk', //
'def', //
'mdef', //
'hpmax', //
'mana', //
'money', //
'exp' //
];
watch(status, update);
/**
* 更新显示内容
*/
function update() {
toShow.forEach(v => {
hero[v] = core.getRealStatus(v);
});
floor.value = core.status.thisMap?.title;
}
</script>
<style lang="less" scoped>
#status-bar {
width: 100%;
height: 100%;
position: fixed;
}
</style>