HumanBreak/src/module/render/ui/main.tsx
2025-02-28 17:10:12 +08:00

240 lines
7.9 KiB
TypeScript

import { LayerShadowExtends } from '@/core/fx/shadow';
import {
ILayerGroupRenderExtends,
FloorDamageExtends,
LayerGroupAnimate,
FloorViewport,
ILayerRenderExtends,
HeroRenderer,
LayerDoorAnimate,
Props,
LayerGroup,
Font
} from '@/core/render';
import { WeatherController } from '@/module/weather';
import { FloorChange } from '@/plugin/fallback';
import { LayerGroupFilter } from '@/plugin/fx/gameCanvas';
import { LayerGroupHalo } from '@/plugin/fx/halo';
import { FloorItemDetail } from '@/plugin/fx/itemDetail';
import { PopText } from '@/plugin/fx/pop';
import { LayerGroupPortal } from '@/plugin/fx/portal';
import { defineComponent, onMounted, reactive, ref } from 'vue';
import { Textbox } from '../components';
import { GameUI, UIController } from '@/core/system';
import {
MAIN_HEIGHT,
MAIN_WIDTH,
STATUS_BAR_HEIGHT,
STATUS_BAR_WIDTH
} from '../shared';
import {
ILeftHeroStatus,
IRightHeroStatus,
LeftStatusBar,
RightStatusBar
} from './statusBar';
import { onLoaded } from '../use';
import { ReplayingStatus } from './toolbar';
import { Tip } from '../components/tip';
const MainScene = defineComponent(() => {
const layerGroupExtends: ILayerGroupRenderExtends[] = [
new FloorDamageExtends(),
new FloorItemDetail(),
new LayerGroupFilter(),
new LayerGroupPortal(),
new LayerGroupHalo(),
new LayerGroupAnimate(),
new FloorViewport()
];
const eventExtends: ILayerRenderExtends[] = [
new HeroRenderer(),
new LayerDoorAnimate(),
new LayerShadowExtends()
];
const mapDrawProps: Props<'container'> = {
width: core._PX_,
height: core._PY_
};
const mainTextboxProps: Props<typeof Textbox> = {
text: '',
hidden: true,
loc: [0, 330, 480, 150],
zIndex: 30,
fillStyle: '#fff',
titleFill: 'gold',
font: new Font('normal'),
titleFont: new Font('normal', 20, 'px', 700),
winskin: 'winskin2.png',
interval: 100,
lineHeight: 4,
width: 480
};
const map = ref<LayerGroup>();
const hideStatus = ref(false);
const weather = new WeatherController('main');
onMounted(() => {
weather.bind(map.value);
});
const leftStatus: ILeftHeroStatus = reactive({
hp: 0,
atk: 0,
def: 0,
mdef: 0,
money: 0,
exp: 0,
yellowKey: 0,
blueKey: 0,
redKey: 0,
floor: 'MT0',
lv: '',
regen: 0,
exAtk: 0,
magicDef: 0
});
const replayStatus: ReplayingStatus = reactive({
playing: false,
speed: 1,
played: 0,
total: 0
});
const rightStatus: IRightHeroStatus = reactive({
autoSkill: false,
skillName: '',
skillDesc: '',
jumpCount: 0,
springCount: 0,
floor: 'MT0',
replaying: false,
replayStatus,
night: 0
});
const { getHeroStatusOn } = Mota.requireAll('fn');
const updateStatus = () => {
if (!core.status || !core.status.hero || !core.status.floorId) return;
hideStatus.value = core.getFlag('hideStatusBar', false);
const hero = core.status.hero;
const floor = core.status.floorId;
leftStatus.atk = getHeroStatusOn('atk');
leftStatus.hp = getHeroStatusOn('hp');
leftStatus.def = getHeroStatusOn('def');
leftStatus.mdef = getHeroStatusOn('mdef');
leftStatus.money = getHeroStatusOn('money');
leftStatus.exp = core.getNextLvUpNeed() ?? 0;
leftStatus.yellowKey = core.itemCount('yellowKey');
leftStatus.blueKey = core.itemCount('blueKey');
leftStatus.redKey = core.itemCount('redKey');
leftStatus.floor = core.status.floorId;
leftStatus.lv = core.getLvName(hero.lv);
leftStatus.regen = getHeroStatusOn('hpmax');
leftStatus.exAtk = getHeroStatusOn('mana');
leftStatus.magicDef = getHeroStatusOn('magicDef');
const { HeroSkill, NightSpecial } = Mota.require('module', 'Mechanism');
rightStatus.autoSkill = HeroSkill.getAutoSkill();
rightStatus.skillName = HeroSkill.getSkillName();
rightStatus.skillDesc = HeroSkill.getSkillDesc();
rightStatus.night = NightSpecial.getNight(floor);
rightStatus.floor = floor;
rightStatus.replaying = core.isReplaying();
const { pausing, speed, toReplay, totalList } = core.status.replay;
replayStatus.playing = !pausing;
replayStatus.speed = speed;
replayStatus.played = totalList.length - toReplay.length;
replayStatus.total = totalList.length;
if (HeroSkill.learnedSkill(HeroSkill.Jump)) {
if (Mota.Plugin.require('skill_g').jumpIgnoreFloor.has(floor)) {
rightStatus.jumpCount = -2;
} else {
rightStatus.jumpCount = 3 - (flags[`jump_${floor}`] ?? 0);
}
} else {
rightStatus.jumpCount = -1;
}
if (core.hasFlag('spring')) {
rightStatus.springCount = 50 - (flags.springCount ?? 0);
} else {
rightStatus.springCount = -1;
}
};
const loaded = ref(false);
onLoaded(() => {
loaded.value = true;
});
Mota.require('var', 'hook').on('statusBarUpdate', updateStatus);
return () => (
<container id="main-scene" width={MAIN_WIDTH} height={MAIN_HEIGHT}>
{loaded.value && (
<LeftStatusBar
loc={[0, 0, STATUS_BAR_WIDTH, STATUS_BAR_HEIGHT]}
status={leftStatus}
hidden={hideStatus.value}
></LeftStatusBar>
)}
<g-line line={[180, 0, 180, 480]} lineWidth={1} />
<container id="map-draw" {...mapDrawProps} x={180} zIndex={10}>
<layer-group id="layer-main" ex={layerGroupExtends} ref={map}>
<layer layer="bg" zIndex={10}></layer>
<layer layer="bg2" zIndex={20}></layer>
<layer layer="event" zIndex={30} ex={eventExtends}></layer>
<layer layer="fg" zIndex={40}></layer>
<layer layer="fg2" zIndex={50}></layer>
<PopText id="pop-main" zIndex={80}></PopText>
</layer-group>
<Textbox id="main-textbox" {...mainTextboxProps}></Textbox>
<FloorChange id="floor-change" zIndex={50}></FloorChange>
<Tip
id="main-tip"
zIndex={80}
loc={[8, 8, 200, 32]}
pad={[12, 6]}
corner={16}
/>
</container>
<g-line line={[180 + 480, 0, 180 + 480, 480]} lineWidth={1} />
{loaded.value && (
<RightStatusBar
loc={[480 + 180, 0, STATUS_BAR_WIDTH, STATUS_BAR_HEIGHT]}
status={rightStatus}
hidden={hideStatus.value}
></RightStatusBar>
)}
<container
loc={[0, 0, MAIN_WIDTH, MAIN_HEIGHT]}
hidden={mainUIController.showBack.value}
>
{mainUIController.render()}
</container>
<g-rect
loc={[0, 0, MAIN_WIDTH, MAIN_HEIGHT]}
hidden={hideStatus.value}
zIndex={100}
stroke
noevent
></g-rect>
<g-line
line={[180, 0, 480 + 180, 0]}
hidden={!hideStatus.value}
zIndex={100}
/>
<g-line
line={[180, 480, 480 + 180, 480]}
hidden={!hideStatus.value}
zIndex={100}
/>
</container>
);
});
export const mainSceneUI = new GameUI('main-scene', MainScene);
export const mainUIController = new UIController('main-ui');