mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-06-28 13:17:59 +08:00
feat: 自定义工具栏显示小地图
This commit is contained in:
parent
59c3b46cfc
commit
fef9950542
@ -4441,7 +4441,6 @@ events.prototype.tryUseItem = function (itemId, noRoute, callback) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (core.canUseItem(itemId)) {
|
if (core.canUseItem(itemId)) {
|
||||||
core.ui.closePanel();
|
|
||||||
core.useItem(itemId, noRoute, callback);
|
core.useItem(itemId, noRoute, callback);
|
||||||
} else {
|
} else {
|
||||||
core.playSound('操作失败');
|
core.playSound('操作失败');
|
||||||
|
@ -201,6 +201,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = {
|
|||||||
}
|
}
|
||||||
if (!flags.debug && !main.replayChecking)
|
if (!flags.debug && !main.replayChecking)
|
||||||
Mota.Plugin.require('completion_r').checkVisitedFloor();
|
Mota.Plugin.require('completion_r').checkVisitedFloor();
|
||||||
|
Mota.require('var', 'hook').emit('afterChangeFloor', floorId);
|
||||||
},
|
},
|
||||||
flyTo: function (toId, callback) {
|
flyTo: function (toId, callback) {
|
||||||
// 楼层传送器的使用,从当前楼层飞往toId
|
// 楼层传送器的使用,从当前楼层飞往toId
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="ui-fixed">
|
<div id="ui-fixed">
|
||||||
<template v-for="ui of fixedUi.stack">
|
<template v-for="ui of fixedUi.stack" :key="ui.num">
|
||||||
<component
|
<component
|
||||||
:is="ui.ui.component"
|
:is="ui.ui.component"
|
||||||
v-on="ui.vOn ?? {}"
|
v-on="ui.vOn ?? {}"
|
||||||
|
@ -3,9 +3,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted } from 'vue';
|
import { onMounted, onUnmounted } from 'vue';
|
||||||
import { requireUniqueSymbol } from '../plugin/utils';
|
import { requireUniqueSymbol } from '../plugin/utils';
|
||||||
import { MinimapDrawer } from '../plugin/ui/fly';
|
import { MinimapDrawer, getArea } from '../plugin/ui/fly';
|
||||||
|
import { hook } from '@/game/game';
|
||||||
|
import { useDrag, useWheel } from '@/plugin/use';
|
||||||
|
import { debounce } from 'lodash-es';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
action?: boolean;
|
action?: boolean;
|
||||||
@ -13,20 +16,144 @@ const props = defineProps<{
|
|||||||
noBorder?: boolean;
|
noBorder?: boolean;
|
||||||
showInfo?: boolean;
|
showInfo?: boolean;
|
||||||
autoLocate?: boolean;
|
autoLocate?: boolean;
|
||||||
|
width?: number;
|
||||||
|
height?: number;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
const area = getArea();
|
||||||
const id = requireUniqueSymbol().toFixed(0);
|
const id = requireUniqueSymbol().toFixed(0);
|
||||||
|
|
||||||
let canvas: HTMLCanvasElement;
|
let canvas: HTMLCanvasElement;
|
||||||
let drawer: MinimapDrawer;
|
let drawer: MinimapDrawer;
|
||||||
|
|
||||||
|
function onChange(floor: FloorIds) {
|
||||||
|
drawer.nowFloor = floor;
|
||||||
|
drawer.nowArea =
|
||||||
|
Object.keys(area).find(v => area[v].includes(core.status.floorId)) ??
|
||||||
|
'';
|
||||||
|
drawer.drawedThumbnail = {};
|
||||||
|
if (props.autoLocate) {
|
||||||
|
drawer.locateMap(drawer.nowFloor);
|
||||||
|
}
|
||||||
|
drawer.drawMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
let scale = props.scale ?? 3;
|
||||||
|
|
||||||
|
let lastX = 0;
|
||||||
|
let lastY = 0;
|
||||||
|
|
||||||
|
let moved = false;
|
||||||
|
let startX = 0;
|
||||||
|
let startY = 0;
|
||||||
|
|
||||||
|
let touchScale = false;
|
||||||
|
let lastDis = 0;
|
||||||
|
|
||||||
|
let lastScale = scale;
|
||||||
|
const changeScale = debounce((s: number) => {
|
||||||
|
canvas.style.transform = '';
|
||||||
|
drawer.drawedThumbnail = {};
|
||||||
|
drawer.scale = s;
|
||||||
|
drawer.drawMap();
|
||||||
|
lastScale = s;
|
||||||
|
}, 200);
|
||||||
|
|
||||||
|
function resize(delta: number) {
|
||||||
|
drawer.ox *= delta;
|
||||||
|
drawer.oy *= delta;
|
||||||
|
scale = delta * scale;
|
||||||
|
changeScale(scale);
|
||||||
|
canvas.style.transform = `scale(${scale / lastScale})`;
|
||||||
|
drawer.thumbnailLoc = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
function drag(x: number, y: number) {
|
||||||
|
if (touchScale) return;
|
||||||
|
const dx = x - lastX;
|
||||||
|
const dy = y - lastY;
|
||||||
|
drawer.ox += dx;
|
||||||
|
drawer.oy += dy;
|
||||||
|
lastX = x;
|
||||||
|
lastY = y;
|
||||||
|
drawer.checkMoveThumbnail();
|
||||||
|
drawer.drawToTarget();
|
||||||
|
if (Math.abs(x - startX) > 10 || Math.abs(y - startY) > 10) moved = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function touchdown(e: TouchEvent) {
|
||||||
|
if (e.touches.length >= 2) {
|
||||||
|
touchScale = true;
|
||||||
|
lastDis = Math.sqrt(
|
||||||
|
(e.touches[0].clientX - e.touches[1].clientX) ** 2 +
|
||||||
|
(e.touches[0].clientY - e.touches[1].clientY) ** 2
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function touchup(e: TouchEvent) {
|
||||||
|
if (e.touches.length < 2) touchScale = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function touchmove(e: TouchEvent) {
|
||||||
|
if (!touchScale) return;
|
||||||
|
const dis = Math.sqrt(
|
||||||
|
(e.touches[0].clientX - e.touches[1].clientX) ** 2 +
|
||||||
|
(e.touches[0].clientY - e.touches[1].clientY) ** 2
|
||||||
|
);
|
||||||
|
resize(dis / lastDis);
|
||||||
|
lastDis = dis;
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
const width = props.width ?? 300;
|
||||||
|
const height = props.height ?? 300;
|
||||||
canvas = document.getElementById(`minimap-${id}`) as HTMLCanvasElement;
|
canvas = document.getElementById(`minimap-${id}`) as HTMLCanvasElement;
|
||||||
|
canvas.style.width = `${width}px`;
|
||||||
|
canvas.style.height = `${height}px`;
|
||||||
|
canvas.width = width * devicePixelRatio;
|
||||||
|
canvas.height = height * devicePixelRatio;
|
||||||
drawer = new MinimapDrawer(canvas);
|
drawer = new MinimapDrawer(canvas);
|
||||||
|
|
||||||
drawer.scale = props.scale ?? 3;
|
drawer.scale = props.scale ?? 3;
|
||||||
drawer.noBorder = props.noBorder ?? false;
|
drawer.noBorder = props.noBorder ?? false;
|
||||||
drawer.showInfo = props.showInfo ?? false;
|
drawer.showInfo = props.showInfo ?? false;
|
||||||
|
|
||||||
|
drawer.drawMap();
|
||||||
|
|
||||||
|
hook.on('afterChangeFloor', onChange);
|
||||||
|
|
||||||
|
if (props.action) {
|
||||||
|
useDrag(
|
||||||
|
canvas,
|
||||||
|
drag,
|
||||||
|
(x, y) => {
|
||||||
|
lastX = x;
|
||||||
|
lastY = y;
|
||||||
|
startX = x;
|
||||||
|
startY = y;
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
moved = false;
|
||||||
|
}, 50);
|
||||||
|
},
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
useWheel(canvas, (x, y) => {
|
||||||
|
const delta = -Math.sign(y) * 0.1 + 1;
|
||||||
|
resize(delta);
|
||||||
|
});
|
||||||
|
|
||||||
|
canvas.addEventListener('touchstart', touchdown);
|
||||||
|
canvas.addEventListener('touchend', touchup);
|
||||||
|
canvas.addEventListener('touchmove', touchmove);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
hook.off('afterChangeFloor', onChange);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ interface CustomToolbarEvent extends EmitableEvent {
|
|||||||
interface ToolbarItemBase<T extends ToolbarItemType> {
|
interface ToolbarItemBase<T extends ToolbarItemType> {
|
||||||
type: T;
|
type: T;
|
||||||
id: string;
|
id: string;
|
||||||
|
noDefaultAction?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 快捷键
|
// 快捷键
|
||||||
@ -52,6 +53,8 @@ interface MinimatToolbar extends ToolbarItemBase<'minimap'> {
|
|||||||
noBorder: boolean;
|
noBorder: boolean;
|
||||||
showInfo: boolean;
|
showInfo: boolean;
|
||||||
autoLocate: boolean;
|
autoLocate: boolean;
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ToolbarItemMap {
|
interface ToolbarItemMap {
|
||||||
@ -407,6 +410,28 @@ CustomToolbar.register(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
CustomToolbar.register(
|
||||||
|
'minimap',
|
||||||
|
'小地图',
|
||||||
|
function (id, item) {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
COM.MinimapTool,
|
||||||
|
EDITOR.MinimapTool,
|
||||||
|
item => {
|
||||||
|
return {
|
||||||
|
action: false,
|
||||||
|
scale: 5,
|
||||||
|
width: 300,
|
||||||
|
height: 300,
|
||||||
|
noBorder: false,
|
||||||
|
showInfo: false,
|
||||||
|
autoLocate: true,
|
||||||
|
...item,
|
||||||
|
noDefaultAction: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
Mota.require('var', 'loading').once('coreInit', () => {
|
Mota.require('var', 'loading').once('coreInit', () => {
|
||||||
CustomToolbar.load();
|
CustomToolbar.load();
|
||||||
|
@ -147,6 +147,7 @@ function showSpecialSetting(id: string, vBind?: any) {
|
|||||||
mainUi.showAll();
|
mainUi.showAll();
|
||||||
});
|
});
|
||||||
mainUi.open(id, vBind);
|
mainUi.open(id, vBind);
|
||||||
|
console.log(core.status.lockControl);
|
||||||
}
|
}
|
||||||
|
|
||||||
function HotkeySetting(props: SettingComponentProps) {
|
function HotkeySetting(props: SettingComponentProps) {
|
||||||
|
@ -7,7 +7,13 @@ import BoxAnimate from '@/components/boxAnimate.vue';
|
|||||||
import { checkAssist } from '../custom/hotkey';
|
import { checkAssist } from '../custom/hotkey';
|
||||||
import { getVitualKeyOnce } from '@/plugin/utils';
|
import { getVitualKeyOnce } from '@/plugin/utils';
|
||||||
import { cloneDeep } from 'lodash-es';
|
import { cloneDeep } from 'lodash-es';
|
||||||
import { Select, SelectOption } from 'ant-design-vue';
|
import {
|
||||||
|
Button,
|
||||||
|
InputNumber,
|
||||||
|
Select,
|
||||||
|
SelectOption,
|
||||||
|
Switch
|
||||||
|
} from 'ant-design-vue';
|
||||||
import { mainSetting } from '../setting';
|
import { mainSetting } from '../setting';
|
||||||
import Minimap from '@/components/minimap.vue';
|
import Minimap from '@/components/minimap.vue';
|
||||||
|
|
||||||
@ -18,6 +24,7 @@ interface Components {
|
|||||||
KeyTool: CustomToolbarComponent<'hotkey'>;
|
KeyTool: CustomToolbarComponent<'hotkey'>;
|
||||||
ItemTool: CustomToolbarComponent<'item'>;
|
ItemTool: CustomToolbarComponent<'item'>;
|
||||||
AssistKeyTool: CustomToolbarComponent<'assistKey'>;
|
AssistKeyTool: CustomToolbarComponent<'assistKey'>;
|
||||||
|
MinimapTool: CustomToolbarComponent<'minimap'>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createToolbarComponents() {
|
export function createToolbarComponents() {
|
||||||
@ -25,7 +32,8 @@ export function createToolbarComponents() {
|
|||||||
DefaultTool,
|
DefaultTool,
|
||||||
KeyTool,
|
KeyTool,
|
||||||
ItemTool,
|
ItemTool,
|
||||||
AssistKeyTool
|
AssistKeyTool,
|
||||||
|
MinimapTool
|
||||||
};
|
};
|
||||||
return com;
|
return com;
|
||||||
}
|
}
|
||||||
@ -35,7 +43,8 @@ export function createToolbarEditorComponents() {
|
|||||||
DefaultTool: DefaultToolEditor,
|
DefaultTool: DefaultToolEditor,
|
||||||
KeyTool: KeyToolEdtior,
|
KeyTool: KeyToolEdtior,
|
||||||
ItemTool: ItemToolEditor,
|
ItemTool: ItemToolEditor,
|
||||||
AssistKeyTool: AssistKeyToolEditor
|
AssistKeyTool: AssistKeyToolEditor,
|
||||||
|
MinimapTool: MinimapToolEditor
|
||||||
};
|
};
|
||||||
return com;
|
return com;
|
||||||
}
|
}
|
||||||
@ -89,12 +98,20 @@ function AssistKeyTool(props: CustomToolbarProps<'assistKey'>) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function MinimapToolbar(props: CustomToolbarProps<'minimap'>) {
|
function MinimapTool(props: CustomToolbarProps<'minimap'>) {
|
||||||
const { item, toolbar } = props;
|
const { item, toolbar } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div style={{ width: `${item.width}px`, height: `${item.height}px` }}>
|
||||||
<Minimap></Minimap>
|
<Minimap
|
||||||
|
action={item.action}
|
||||||
|
scale={item.scale}
|
||||||
|
noBorder={item.noBorder}
|
||||||
|
showInfo={item.showInfo}
|
||||||
|
autoLocate={item.autoLocate}
|
||||||
|
width={item.width}
|
||||||
|
height={item.height}
|
||||||
|
></Minimap>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -215,3 +232,155 @@ function AssistKeyToolEditor(props: CustomToolbarProps<'assistKey'>) {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function MinimapToolEditor(props: CustomToolbarProps<'minimap'>) {
|
||||||
|
const { item, toolbar } = props;
|
||||||
|
|
||||||
|
type K = keyof typeof item;
|
||||||
|
const setConfig: <T extends K>(key: T, value: (typeof item)[T]) => void = (
|
||||||
|
key,
|
||||||
|
value
|
||||||
|
) => {
|
||||||
|
let v = value;
|
||||||
|
if (key === 'height' || key === 'height') {
|
||||||
|
if ((v as number) > 1000) (v as number) = 1000;
|
||||||
|
if ((v as number) < 50) (v as number) = 50;
|
||||||
|
} else if (key === 'scale') {
|
||||||
|
if ((v as number) > 20) (v as number) = 20;
|
||||||
|
if ((v as number) < 1) (v as number) = 1;
|
||||||
|
}
|
||||||
|
toolbar.set(item.id, { [key]: v });
|
||||||
|
toolbar.refresh();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
display: flex; flex-direction: column;
|
||||||
|
align-items: center; padding: 0 5%; margin: 1%
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div class="toolbar-editor-item">
|
||||||
|
<span>宽度</span>
|
||||||
|
<div style="width: 70%; display: flex; justify-content: end">
|
||||||
|
<InputNumber
|
||||||
|
class="number-input"
|
||||||
|
size="large"
|
||||||
|
// keyboard={true}
|
||||||
|
min={50}
|
||||||
|
max={1000}
|
||||||
|
step={50}
|
||||||
|
value={item.width}
|
||||||
|
onChange={value => setConfig('width', value as number)}
|
||||||
|
></InputNumber>
|
||||||
|
<Button
|
||||||
|
style="margin-left: 5%"
|
||||||
|
class="number-button"
|
||||||
|
type="primary"
|
||||||
|
onClick={() => setConfig('width', item.width - 50)}
|
||||||
|
>
|
||||||
|
减少
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
style="margin-left: 5%"
|
||||||
|
class="number-button"
|
||||||
|
type="primary"
|
||||||
|
onClick={() => setConfig('width', item.width + 50)}
|
||||||
|
>
|
||||||
|
增加
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="toolbar-editor-item">
|
||||||
|
<span>高度</span>
|
||||||
|
<div style="width: 70%; display: flex; justify-content: end">
|
||||||
|
<InputNumber
|
||||||
|
class="number-input"
|
||||||
|
size="large"
|
||||||
|
// keyboard={true}
|
||||||
|
min={50}
|
||||||
|
max={1000}
|
||||||
|
step={50}
|
||||||
|
value={item.height}
|
||||||
|
onChange={value => setConfig('height', value as number)}
|
||||||
|
></InputNumber>
|
||||||
|
<Button
|
||||||
|
style="margin-left: 5%"
|
||||||
|
class="number-button"
|
||||||
|
type="primary"
|
||||||
|
onClick={() => setConfig('height', item.height - 50)}
|
||||||
|
>
|
||||||
|
减少
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
style="margin-left: 5%"
|
||||||
|
class="number-button"
|
||||||
|
type="primary"
|
||||||
|
onClick={() => setConfig('height', item.height + 50)}
|
||||||
|
>
|
||||||
|
增加
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="toolbar-editor-item">
|
||||||
|
<span>放缩比例</span>
|
||||||
|
<div style="width: 70%; display: flex; justify-content: end">
|
||||||
|
<InputNumber
|
||||||
|
class="number-input"
|
||||||
|
size="large"
|
||||||
|
// keyboard={true}
|
||||||
|
min={1}
|
||||||
|
max={20}
|
||||||
|
step={1}
|
||||||
|
value={item.scale}
|
||||||
|
onChange={value => setConfig('scale', value as number)}
|
||||||
|
></InputNumber>
|
||||||
|
<Button
|
||||||
|
style="margin-left: 5%"
|
||||||
|
class="number-button"
|
||||||
|
type="primary"
|
||||||
|
onClick={() => setConfig('scale', item.scale - 1)}
|
||||||
|
>
|
||||||
|
减少
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
style="margin-left: 5%"
|
||||||
|
class="number-button"
|
||||||
|
type="primary"
|
||||||
|
onClick={() => setConfig('scale', item.scale + 1)}
|
||||||
|
>
|
||||||
|
增加
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="toolbar-editor-item">
|
||||||
|
<span>无边框模式</span>
|
||||||
|
<Switch
|
||||||
|
checked={item.noBorder}
|
||||||
|
onClick={() => setConfig('noBorder', !item.noBorder)}
|
||||||
|
></Switch>
|
||||||
|
</div>
|
||||||
|
<div class="toolbar-editor-item">
|
||||||
|
<span>显示漏怪</span>
|
||||||
|
<Switch
|
||||||
|
checked={item.showInfo}
|
||||||
|
onClick={() => setConfig('showInfo', !item.showInfo)}
|
||||||
|
></Switch>
|
||||||
|
</div>
|
||||||
|
<div class="toolbar-editor-item">
|
||||||
|
<span>自动居中</span>
|
||||||
|
<Switch
|
||||||
|
checked={item.autoLocate}
|
||||||
|
onClick={() => setConfig('autoLocate', !item.autoLocate)}
|
||||||
|
></Switch>
|
||||||
|
</div>
|
||||||
|
<div class="toolbar-editor-item">
|
||||||
|
<span>允许交互</span>
|
||||||
|
<Switch
|
||||||
|
checked={item.action}
|
||||||
|
onClick={() => setConfig('action', !item.action)}
|
||||||
|
></Switch>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@ -83,13 +83,14 @@ export interface GameEvent extends EmitableEvent {
|
|||||||
/** Emitted in core/index.ts */
|
/** Emitted in core/index.ts */
|
||||||
renderLoaded: () => void;
|
renderLoaded: () => void;
|
||||||
// /** Emitted in libs/events.js */
|
// /** Emitted in libs/events.js */
|
||||||
// afterGetItem: (
|
afterGetItem: (
|
||||||
// itemId: AllIdsOf<'items'>,
|
itemId: AllIdsOf<'items'>,
|
||||||
// x: number,
|
x: number,
|
||||||
// y: number,
|
y: number,
|
||||||
// isGentleClick: boolean
|
isGentleClick: boolean
|
||||||
// ) => void;
|
) => void;
|
||||||
// afterOpenDoor: (doorId: AllIdsOf<'animates'>, x: number, y: number) => void;
|
afterOpenDoor: (doorId: AllIdsOf<'animates'>, x: number, y: number) => void;
|
||||||
|
afterChangeFloor: (floorId: FloorIds) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const hook = new EventEmitter<GameEvent>();
|
export const hook = new EventEmitter<GameEvent>();
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { mainSetting } from '@/core/main/setting';
|
||||||
import { downloadCanvasImage, has, tip } from '../utils';
|
import { downloadCanvasImage, has, tip } from '../utils';
|
||||||
|
|
||||||
type BFSFromString = `${FloorIds},${number},${number},${Dir}`;
|
type BFSFromString = `${FloorIds},${number},${number},${Dir}`;
|
||||||
@ -225,11 +226,14 @@ export class MinimapDrawer {
|
|||||||
private tempCtx: CanvasRenderingContext2D;
|
private tempCtx: CanvasRenderingContext2D;
|
||||||
|
|
||||||
private downloadMode: boolean = false;
|
private downloadMode: boolean = false;
|
||||||
|
private innerRatio: number = 1;
|
||||||
|
|
||||||
constructor(canvas: HTMLCanvasElement) {
|
constructor(canvas: HTMLCanvasElement) {
|
||||||
this.canvas = canvas;
|
this.canvas = canvas;
|
||||||
this.ctx = canvas.getContext('2d')!;
|
this.ctx = canvas.getContext('2d')!;
|
||||||
this.tempCtx = this.tempCanvas.getContext('2d')!;
|
this.tempCtx = this.tempCanvas.getContext('2d')!;
|
||||||
|
this.innerRatio = mainSetting.getValue('ui.mapScale', 100) / 100;
|
||||||
|
this.scale *= this.innerRatio;
|
||||||
}
|
}
|
||||||
|
|
||||||
link(canvas: HTMLCanvasElement) {
|
link(canvas: HTMLCanvasElement) {
|
||||||
@ -327,6 +331,8 @@ export class MinimapDrawer {
|
|||||||
map.height
|
map.height
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (!this.noBorder && this.scale * this.innerRatio <= 7)
|
||||||
|
this.drawEnemy(ctx, id, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -375,7 +381,7 @@ export class MinimapDrawer {
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
this.drawedThumbnail[floorId] ||
|
this.drawedThumbnail[floorId] ||
|
||||||
(!this.noBorder && scale <= 4) ||
|
(!this.noBorder && scale * this.innerRatio <= 7) ||
|
||||||
right < 0 ||
|
right < 0 ||
|
||||||
bottom < 0 ||
|
bottom < 0 ||
|
||||||
left > map.width ||
|
left > map.width ||
|
||||||
@ -414,7 +420,7 @@ export class MinimapDrawer {
|
|||||||
w: floor.width,
|
w: floor.width,
|
||||||
h: floor.height,
|
h: floor.height,
|
||||||
ctx,
|
ctx,
|
||||||
damage: this.scale > 7
|
damage: this.scale * this.innerRatio > 15
|
||||||
});
|
});
|
||||||
if (!this.downloadMode) {
|
if (!this.downloadMode) {
|
||||||
if (!core.hasVisitedFloor(floorId)) {
|
if (!core.hasVisitedFloor(floorId)) {
|
||||||
@ -438,21 +444,7 @@ export class MinimapDrawer {
|
|||||||
ctx.fillStyle = '#000';
|
ctx.fillStyle = '#000';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.scale > 2) {
|
this.drawEnemy(ctx, floorId, x, y);
|
||||||
ctx.save();
|
|
||||||
ctx.textAlign = 'center';
|
|
||||||
ctx.textBaseline = 'middle';
|
|
||||||
ctx.font = `3px "normal"`;
|
|
||||||
ctx.strokeStyle = 'black';
|
|
||||||
Mota.require('fn', 'ensureFloorDamage')(floorId);
|
|
||||||
const enemyNum = core.status.maps[floorId].enemy.list.length;
|
|
||||||
ctx.fillStyle = 'rgba(0, 0, 0, 0.6)';
|
|
||||||
ctx.fillRect(x - 6, y - 2, 12, 4);
|
|
||||||
ctx.fillStyle = 'white';
|
|
||||||
ctx.strokeText(`${enemyNum}怪物`, x, y);
|
|
||||||
ctx.fillText(`${enemyNum}怪物`, x, y);
|
|
||||||
ctx.restore();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -506,4 +498,57 @@ export class MinimapDrawer {
|
|||||||
this.ox = (-x + data.width / 2 - 5) * this.scale;
|
this.ox = (-x + data.width / 2 - 5) * this.scale;
|
||||||
this.oy = (-y + data.height / 2 - 5) * this.scale;
|
this.oy = (-y + data.height / 2 - 5) * this.scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private drawEnemy(
|
||||||
|
ctx: CanvasRenderingContext2D,
|
||||||
|
floorId: FloorIds,
|
||||||
|
x: number,
|
||||||
|
y: number
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
this.scale * this.innerRatio > 10 &&
|
||||||
|
this.scale * this.innerRatio < 40 &&
|
||||||
|
!this.downloadMode &&
|
||||||
|
this.showInfo
|
||||||
|
) {
|
||||||
|
ctx.save();
|
||||||
|
ctx.lineWidth = 0.5;
|
||||||
|
ctx.textAlign = 'center';
|
||||||
|
ctx.textBaseline = 'middle';
|
||||||
|
ctx.font = `3px "normal"`;
|
||||||
|
ctx.strokeStyle = 'black';
|
||||||
|
Mota.require('fn', 'ensureFloorDamage')(floorId);
|
||||||
|
ctx.fillStyle = 'rgba(0, 0, 0, 0.6)';
|
||||||
|
ctx.fillRect(x - 6, y - 2, 12, 4);
|
||||||
|
ctx.fillStyle = 'white';
|
||||||
|
const enemy = core.status.maps[floorId].enemy.list;
|
||||||
|
if (enemy.length === 0) {
|
||||||
|
ctx.strokeStyle = 'lightgreen';
|
||||||
|
ctx.lineCap = 'round';
|
||||||
|
ctx.lineJoin = 'round';
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(x - 1.5, y);
|
||||||
|
ctx.lineTo(x - 0.5, y + 1);
|
||||||
|
ctx.lineTo(x + 1.5, y - 1);
|
||||||
|
ctx.stroke();
|
||||||
|
} else {
|
||||||
|
const ids = [...new Set(enemy.map(v => v.id))];
|
||||||
|
if (ids.length === 1) {
|
||||||
|
core.drawIcon(ctx, ids[0], x - 2, y - 2, 4, 4);
|
||||||
|
} else if (ids.length === 2) {
|
||||||
|
core.drawIcon(ctx, ids[0], x - 4, y - 2, 4, 4);
|
||||||
|
core.drawIcon(ctx, ids[1], x, y - 2, 4, 4);
|
||||||
|
} else {
|
||||||
|
core.drawIcon(ctx, ids[0], x - 5, y - 2, 4, 4);
|
||||||
|
core.drawIcon(ctx, ids[1], x - 1, y - 2, 4, 4);
|
||||||
|
ctx.fillStyle = 'white';
|
||||||
|
ctx.strokeStyle = 'black';
|
||||||
|
ctx.strokeText('…', x + 4, y);
|
||||||
|
ctx.fillText('…', x + 4, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,3 +111,11 @@
|
|||||||
background-color: #0000;
|
background-color: #0000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.toolbar-editor-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
@ -309,6 +309,7 @@ onMounted(async () => {
|
|||||||
main = document.getElementById('start-main') as HTMLDivElement;
|
main = document.getElementById('start-main') as HTMLDivElement;
|
||||||
start = document.getElementById('start') as HTMLDivElement;
|
start = document.getElementById('start') as HTMLDivElement;
|
||||||
background = document.getElementById('background') as HTMLImageElement;
|
background = document.getElementById('background') as HTMLImageElement;
|
||||||
|
CustomToolbar.closeAll();
|
||||||
|
|
||||||
window.addEventListener('resize', resize);
|
window.addEventListener('resize', resize);
|
||||||
resize();
|
resize();
|
||||||
@ -325,8 +326,6 @@ onMounted(async () => {
|
|||||||
await sleep(1000);
|
await sleep(1000);
|
||||||
showCursor();
|
showCursor();
|
||||||
await sleep(1200);
|
await sleep(1200);
|
||||||
|
|
||||||
CustomToolbar.closeAll();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
|
@ -525,7 +525,7 @@ onUnmounted(() => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
margin: v-bind('5 * scale + "px"');
|
margin: v-bind('5 * scale + "px"');
|
||||||
min-width: v-bind('50 * scale + "px"');
|
min-width: v-bind('50 * scale + "px"');
|
||||||
height: v-bind('50 * scale + "px"');
|
min-height: v-bind('50 * scale + "px"');
|
||||||
background-color: #222;
|
background-color: #222;
|
||||||
border: 1.5px solid #ddd8;
|
border: 1.5px solid #ddd8;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
@ -7,12 +7,14 @@
|
|||||||
v-model:top="box.y"
|
v-model:top="box.y"
|
||||||
v-model:height="box.height"
|
v-model:height="box.height"
|
||||||
v-model:width="box.width"
|
v-model:width="box.width"
|
||||||
|
:key="num"
|
||||||
>
|
>
|
||||||
<div class="toolbar">
|
<div class="toolbar">
|
||||||
<div
|
<div
|
||||||
class="toolbar-item"
|
class="toolbar-item"
|
||||||
v-for="item of bar.items"
|
v-for="item of bar.items"
|
||||||
@click.stop="click"
|
@click.stop="click"
|
||||||
|
:noaction="!!item.noDefaultAction"
|
||||||
>
|
>
|
||||||
<component
|
<component
|
||||||
:is="(CustomToolbar.info[item.type].show as any)"
|
:is="(CustomToolbar.info[item.type].show as any)"
|
||||||
@ -97,8 +99,7 @@ onUnmounted(() => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
margin: v-bind('scale * 5 + "px"');
|
margin: v-bind('scale * 5 + "px"');
|
||||||
min-width: v-bind('scale * 50 + "px"');
|
min-width: v-bind('scale * 50 + "px"');
|
||||||
height: v-bind('scale * 50 + "px"');
|
min-height: v-bind('scale * 50 + "px"');
|
||||||
cursor: pointer;
|
|
||||||
background-color: #222;
|
background-color: #222;
|
||||||
border: 1.5px solid #ddd8;
|
border: 1.5px solid #ddd8;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@ -106,6 +107,10 @@ onUnmounted(() => {
|
|||||||
transition: all 0.1s linear;
|
transition: all 0.1s linear;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.toolbar-item[noaction='false'] {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
.toolbar-item::v-deep(> *) {
|
.toolbar-item::v-deep(> *) {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
min-width: v-bind('scale * 50 + "px"');
|
min-width: v-bind('scale * 50 + "px"');
|
||||||
@ -123,11 +128,11 @@ onUnmounted(() => {
|
|||||||
background-color: #555;
|
background-color: #555;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toolbar-item:hover {
|
.toolbar-item:hover[noaction='false'] {
|
||||||
background-color: #444;
|
background-color: #444;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toolbar-item:active {
|
.toolbar-item:active[noaction='false'] {
|
||||||
background-color: #333;
|
background-color: #333;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
Loading…
Reference in New Issue
Block a user