import { DefaultProps, ElementLocator, Font } from '@motajs/render';
import { computed, defineComponent, ref } from 'vue';
import { SetupComponentOptions } from '../components';
import {
DanmakuIcon,
DoubleArrow,
NumpadIcon,
PauseIcon,
PlayIcon,
ReplayIcon,
RetweetIcon,
RollbackIcon,
StepForward,
ViewMapIcon
} from '../components/icons';
import {
generateBinary,
getVitualKeyOnce,
openDanmakuPoster
} from '@motajs/legacy-ui';
import { gameKey } from '@motajs/system-action';
import { generateKeyboardEvent } from '@motajs/system-action';
import { transitioned } from '../use';
import { linear } from 'mutate-animate';
import { KeyCode } from '@motajs/client-base';
import { Progress } from '../components/misc';
interface ToolbarProps extends DefaultProps {
loc?: ElementLocator;
}
type ToolbarEmits = {
numpad: () => void;
};
const toolbarProps = {
props: ['loc'],
emits: ['numpad']
} satisfies SetupComponentOptions<
ToolbarProps,
ToolbarEmits,
keyof ToolbarEmits
>;
const im = (col: number, row: number): ElementLocator => {
return [5 + 34 * col, 5 + 36 * row, 32, 32];
};
const ic = (col: number, row: number): ElementLocator => {
return [7 + 34 * col, 7 + 36 * row, 28, 28];
};
const ic2 = (col: number, row: number): ElementLocator => {
return [9 + 34 * col, 9 + 36 * row, 24, 24];
};
const middle = (col: number, row: number): ElementLocator => {
return [21 + 34 * col, 21 + 36 * row, void 0, void 0, 0.5, 0.5];
};
const middle2 = (
col: number,
row: number,
width: number,
height: number
): ElementLocator => {
return [21 + 34 * col, 21 + 36 * row, width, height, 0.5, 0.5];
};
export const PlayingToolbar = defineComponent<
ToolbarProps,
ToolbarEmits,
keyof ToolbarEmits
>((props, { emit }) => {
const bookIcon = core.statusBar.icons.book;
const flyIcon = core.statusBar.icons.fly;
const toolIcon = core.statusBar.icons.toolbox;
const equipIcon = core.statusBar.icons.equipbox;
const keyIcon = core.statusBar.icons.keyboard;
const shopIcon = core.statusBar.icons.shop;
const saveIcon = core.statusBar.icons.save;
const loadIcon = core.statusBar.icons.load;
const setIcon = core.statusBar.icons.settings;
const iconFont = new Font('Verdana', 12);
const book = () => core.openBook(true);
const tool = () => core.openEquipbox(true);
const fly = () => core.useFly(true);
const save = () => core.save(true);
const load = () => core.load(true);
const equip = () => core.openEquipbox(true);
const shop = () => core.openQuickShop(true);
const key = () => {
getVitualKeyOnce().then(value => {
gameKey.emitKey(
value.key,
value.assist,
'up',
generateKeyboardEvent(value.key, value.assist)
);
});
};
const undo = () => core.doSL('autoSave', 'load');
const redo = () => core.doSL('autoSave', 'reload');
const numpad = () => emit('numpad');
const view = () => {
if (core.isPlaying() && !core.isMoving() && !core.status.lockControl) {
core.ui._drawViewMaps();
}
};
const danmaku = () => requestAnimationFrame(openDanmakuPoster);
const replay = () => core.ui._drawReplay();
const settings = () => core.openSettings(true);
return () => (
);
}, toolbarProps);
export interface ReplayingStatus {
/** 是否正在播放 */
playing: boolean;
/** 录像播放速度 */
speed: number;
/** 已播放的长度 */
played: number;
/** 总长度 */
total: number;
}
export interface ReplayingProps extends ToolbarProps {
/** 录像播放状态 */
status: ReplayingStatus;
}
const replayingProps = {
props: ['status', 'loc']
} satisfies SetupComponentOptions;
export const ReplayingToolbar = defineComponent(props => {
const status = props.status;
const bookIcon = core.statusBar.icons.book;
const saveIcon = core.statusBar.icons.save;
const font1 = new Font('normal', 16);
const font2 = new Font('Verdana', 12);
const speedText = computed(() => `${status.speed}速`);
const progress = computed(() => status.played / status.total);
const progressText1 = computed(() => `${status.played}/${status.total}`);
const progressText2 = computed(
() => `${(progress.value * 100).toFixed(2)}%`
);
const play = () => core.resumeReplay();
const pause = () => core.pauseReplay();
const stop = () => core.stopReplay(true);
const speedDown = () => core.speedDownReplay();
const speedUp = () => core.speedUpReplay();
const book = () => core.openBook(true);
const save = () => core.save(true);
const view = () => {
if (core.isPlaying() && !core.isMoving() && !core.status.lockControl) {
core.ui._drawViewMaps();
}
};
const rewind = () => core.rewindReplay();
const step = () => core.stepReplay();
return () => {
return (
{status.playing ? (
) : (
)}
);
};
}, replayingProps);
export const NumpadToolbar = defineComponent<
ToolbarProps,
ToolbarEmits,
keyof ToolbarEmits
>((props, { emit }) => {
const numpad = () => emit('numpad');
const nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
const ctrlEnabled = ref(false);
const shiftEnabled = ref(false);
const altEnabled = ref(false);
const ctrlAlpha = transitioned(0, 100, linear())!;
const shiftAlpha = transitioned(0, 100, linear())!;
const altAlpha = transitioned(0, 100, linear())!;
const ctrlColor = computed(
() => `rgba(221,221,221,${ctrlAlpha.ref.value})`
);
const ctrlTextColor = computed(() => {
const rgb = Math.floor(255 - ctrlAlpha.ref.value * 255);
return `rgba(${rgb},${rgb},${rgb},1)`;
});
const shiftColor = computed(
() => `rgba(221,221,221,${shiftAlpha.ref.value})`
);
const shiftTextColor = computed(() => {
const rgb = Math.floor(255 - shiftAlpha.ref.value * 255);
return `rgba(${rgb},${rgb},${rgb},1)`;
});
const altColor = computed(() => `rgba(221,221,221,${altAlpha.ref.value})`);
const altTextColor = computed(() => {
const rgb = Math.floor(255 - altAlpha.ref.value * 255);
return `rgba(${rgb},${rgb},${rgb},1)`;
});
const clickCtrl = () => {
ctrlEnabled.value = !ctrlEnabled.value;
ctrlAlpha.set(ctrlEnabled.value ? 1 : 0);
};
const clickShift = () => {
shiftEnabled.value = !shiftEnabled.value;
shiftAlpha.set(shiftEnabled.value ? 1 : 0);
};
const clickAlt = () => {
altEnabled.value = !altEnabled.value;
altAlpha.set(altEnabled.value ? 1 : 0);
};
const clickNum = (num: number) => {
const bin = generateBinary([
ctrlEnabled.value,
shiftEnabled.value,
altEnabled.value
]);
const code = (KeyCode.Digit0 + num) as KeyCode;
gameKey.emitKey(code, bin, 'up', generateKeyboardEvent(code, bin));
};
return () => (
{nums
.map((v, i) => {
const col = i % 5;
const row = Math.floor(i / 5);
return [
clickNum(v)}
/>,
];
})
.flat()}
);
}, toolbarProps);