179 lines
5.2 KiB
TypeScript
179 lines
5.2 KiB
TypeScript
/**
|
|
* Automap Reveal Plugin (`plugins/automap-reveal/index.ts` — Issue #714).
|
|
*
|
|
* Isolates the non-1.13c full-level (`level`) and full-act (`act`) automap reveal
|
|
* enhancement outside core `src/`. When disabled, `PluginHost` releases the capability
|
|
* claim and strictly enforces 1.13c fog-of-war (`automapReveal = 'off'`).
|
|
*/
|
|
|
|
import {
|
|
VALID_AUTOMAP_REVEAL_MODES,
|
|
type AutomapRevealMode,
|
|
type D2WebPlugin,
|
|
type LocalizedText,
|
|
type PluginContext,
|
|
type PluginInstance,
|
|
type PluginStatus,
|
|
type PluginToolbarSelectOption,
|
|
} from '../../src/client/plugin-host/api.ts'
|
|
|
|
const AUTOMAP_MODE_LABELS: Readonly<Record<AutomapRevealMode, LocalizedText>> = {
|
|
off: {
|
|
zh: '关闭',
|
|
en: 'Off',
|
|
},
|
|
level: {
|
|
zh: '本层全开',
|
|
en: 'Current Level',
|
|
},
|
|
act: {
|
|
zh: '整幕全开',
|
|
en: 'Full Act',
|
|
},
|
|
}
|
|
|
|
const AUTOMAP_SELECT_OPTIONS: readonly PluginToolbarSelectOption[] =
|
|
VALID_AUTOMAP_REVEAL_MODES.map((mode) => ({
|
|
value: mode,
|
|
label: AUTOMAP_MODE_LABELS[mode],
|
|
}))
|
|
|
|
function isAutomapRevealMode(value: unknown): value is AutomapRevealMode {
|
|
return (
|
|
typeof value === 'string' &&
|
|
(VALID_AUTOMAP_REVEAL_MODES as readonly string[]).includes(value)
|
|
)
|
|
}
|
|
|
|
export interface AutomapRevealPluginInstance extends PluginInstance {
|
|
getMode(): AutomapRevealMode
|
|
setMode(mode: AutomapRevealMode): void
|
|
}
|
|
|
|
export function createAutomapRevealPlugin(): D2WebPlugin {
|
|
return {
|
|
id: 'automap-reveal',
|
|
name: {
|
|
zh: '小地图全图透视',
|
|
en: 'Automap Reveal',
|
|
},
|
|
description: {
|
|
zh: '非 1.13c 增强:支持一键揭开本层或整幕全部小地图房间与传送点标记。关闭插件后严格恢复 1.13c 原版战争迷雾(仅显示服务端已探索区域)。',
|
|
en: 'Non-1.13c enhancement: reveals all rooms and warp markers for the current level or entire Act. When disabled, strictly enforces 1.13c server-driven fog of war.',
|
|
},
|
|
defaultEnabled: true,
|
|
settings: [
|
|
{
|
|
kind: 'select',
|
|
key: 'mode',
|
|
label: {
|
|
zh: '透视范围',
|
|
en: 'Reveal Scope',
|
|
},
|
|
default: 'off',
|
|
options: AUTOMAP_SELECT_OPTIONS,
|
|
},
|
|
{
|
|
kind: 'boolean',
|
|
key: 'showToolbarShortcut',
|
|
label: {
|
|
zh: '在工具栏显示快捷下拉框',
|
|
en: 'Show selector in toolbar',
|
|
},
|
|
default: true,
|
|
},
|
|
],
|
|
activate(ctx: PluginContext): AutomapRevealPluginInstance {
|
|
const storedSetting = ctx.settings.get('mode')
|
|
const initialMode: AutomapRevealMode = isAutomapRevealMode(storedSetting)
|
|
? storedSetting
|
|
: 'off'
|
|
|
|
ctx.client.setAutomapReveal(initialMode)
|
|
|
|
const unsubClient = ctx.client.subscribeAutomapReveal((clientMode) => {
|
|
if (ctx.settings.get('mode') !== clientMode) {
|
|
ctx.settings.set('mode', clientMode)
|
|
}
|
|
ctx.notifyStatusChanged()
|
|
})
|
|
|
|
let removeToolbarSelect: (() => void) | null = null
|
|
const syncToolbarShortcut = (): void => {
|
|
const show = ctx.settings.get('showToolbarShortcut') === true
|
|
if (show && !removeToolbarSelect) {
|
|
removeToolbarSelect = ctx.toolbar.addSelect({
|
|
id: 'mode',
|
|
selectDomId: 'd2-toolbar-automap-select',
|
|
label: {
|
|
zh: '小地图',
|
|
en: 'Automap',
|
|
},
|
|
options: AUTOMAP_SELECT_OPTIONS,
|
|
getValue: () => {
|
|
const raw = ctx.settings.get('mode')
|
|
return isAutomapRevealMode(raw) ? raw : 'off'
|
|
},
|
|
onChange: (value: string) => {
|
|
if (!isAutomapRevealMode(value)) {
|
|
throw new Error(`Invalid automap reveal mode: ${value}`)
|
|
}
|
|
ctx.settings.set('mode', value)
|
|
},
|
|
})
|
|
} else if (!show && removeToolbarSelect) {
|
|
removeToolbarSelect()
|
|
removeToolbarSelect = null
|
|
}
|
|
}
|
|
|
|
syncToolbarShortcut()
|
|
|
|
const unsubSettings = ctx.settings.subscribe((key) => {
|
|
if (key === 'mode') {
|
|
const next = ctx.settings.get('mode')
|
|
if (isAutomapRevealMode(next)) {
|
|
ctx.client.setAutomapReveal(next)
|
|
ctx.notifyStatusChanged()
|
|
}
|
|
} else if (key === 'showToolbarShortcut') {
|
|
syncToolbarShortcut()
|
|
}
|
|
})
|
|
|
|
const getStatus = (): PluginStatus => {
|
|
const mode = ctx.client.getAutomapReveal()
|
|
const label = AUTOMAP_MODE_LABELS[mode]
|
|
return {
|
|
level: 'ok',
|
|
text: {
|
|
zh: `当前:${label.zh}`,
|
|
en: `Mode: ${label.en}`,
|
|
},
|
|
}
|
|
}
|
|
|
|
return {
|
|
getMode: () => ctx.client.getAutomapReveal(),
|
|
setMode: (mode: AutomapRevealMode) => {
|
|
if (!isAutomapRevealMode(mode)) {
|
|
throw new Error(`Invalid automap reveal mode: ${String(mode)}`)
|
|
}
|
|
ctx.settings.set('mode', mode)
|
|
},
|
|
getStatus,
|
|
deactivate(): void {
|
|
unsubClient()
|
|
unsubSettings()
|
|
if (removeToolbarSelect) {
|
|
removeToolbarSelect()
|
|
removeToolbarSelect = null
|
|
}
|
|
},
|
|
}
|
|
},
|
|
}
|
|
}
|
|
|
|
export const automapRevealPlugin: D2WebPlugin = createAutomapRevealPlugin()
|