110 lines
2.8 KiB
TypeScript
110 lines
2.8 KiB
TypeScript
export const combatPresentationStorageKey = 'heros-web:combat-presentation-mode';
|
|
|
|
export type CombatPresentationMode = 'always' | 'important' | 'map';
|
|
|
|
export type CombatPresentationImportance = {
|
|
signature?: boolean;
|
|
critical?: boolean;
|
|
defeated?: boolean;
|
|
resonance?: boolean;
|
|
growth?: boolean;
|
|
};
|
|
|
|
type StorageLike = Pick<Storage, 'getItem' | 'setItem'>;
|
|
|
|
export const combatPresentationModes: readonly CombatPresentationMode[] = ['always', 'important', 'map'];
|
|
|
|
export const combatPresentationModeLabels: Record<CombatPresentationMode, string> = {
|
|
always: '항상',
|
|
important: '중요 장면만',
|
|
map: '지도 연출'
|
|
};
|
|
|
|
export function isCombatPresentationMode(value: unknown): value is CombatPresentationMode {
|
|
return typeof value === 'string' && combatPresentationModes.includes(value as CombatPresentationMode);
|
|
}
|
|
|
|
export function nextCombatPresentationMode(mode: CombatPresentationMode): CombatPresentationMode {
|
|
const index = combatPresentationModes.indexOf(mode);
|
|
return combatPresentationModes[(index + 1) % combatPresentationModes.length];
|
|
}
|
|
|
|
export function combatPresentationModeLabel(mode: CombatPresentationMode) {
|
|
return combatPresentationModeLabels[mode];
|
|
}
|
|
|
|
export function shouldUseFullCombatCutIn(
|
|
mode: CombatPresentationMode,
|
|
importance: CombatPresentationImportance
|
|
) {
|
|
if (mode === 'always') {
|
|
return true;
|
|
}
|
|
if (mode === 'map') {
|
|
return false;
|
|
}
|
|
return Boolean(
|
|
importance.signature ||
|
|
importance.critical ||
|
|
importance.defeated ||
|
|
importance.resonance ||
|
|
importance.growth
|
|
);
|
|
}
|
|
|
|
export function combatPresentationImportanceReason(importance: CombatPresentationImportance) {
|
|
if (importance.signature) {
|
|
return '고유 전법';
|
|
}
|
|
if (importance.defeated) {
|
|
return '격파';
|
|
}
|
|
if (importance.critical) {
|
|
return '치명타';
|
|
}
|
|
if (importance.resonance) {
|
|
return '공명';
|
|
}
|
|
if (importance.growth) {
|
|
return '레벨 상승';
|
|
}
|
|
return '일반 행동';
|
|
}
|
|
|
|
export function loadCombatPresentationMode(storage = resolveStorage()): CombatPresentationMode {
|
|
if (!storage) {
|
|
return 'important';
|
|
}
|
|
try {
|
|
const value = storage.getItem(combatPresentationStorageKey);
|
|
return isCombatPresentationMode(value) ? value : 'important';
|
|
} catch {
|
|
return 'important';
|
|
}
|
|
}
|
|
|
|
export function saveCombatPresentationMode(
|
|
mode: CombatPresentationMode,
|
|
storage = resolveStorage()
|
|
) {
|
|
if (!storage) {
|
|
return;
|
|
}
|
|
try {
|
|
storage.setItem(combatPresentationStorageKey, mode);
|
|
} catch {
|
|
// Local storage can be unavailable in private or restricted browser contexts.
|
|
}
|
|
}
|
|
|
|
function resolveStorage(): StorageLike | undefined {
|
|
if (typeof window === 'undefined') {
|
|
return undefined;
|
|
}
|
|
try {
|
|
return window.localStorage;
|
|
} catch {
|
|
return undefined;
|
|
}
|
|
}
|