치지직 채널 ID로 입장하게 변경 및 일부 판 커스텀 설정 추가.

This commit is contained in:
kimyu
2026-09-16 05:29:50 +09:00
parent 7c402dfd8f
commit 6f72824598
5 changed files with 170 additions and 31 deletions

View File

@@ -34,6 +34,8 @@ export type BoardCellConfig = {
eventId?: string | null;
/** 칸 전용 이미지 (data URL 또는 상대 경로) */
imageSrc?: string | null;
/** false면 게임에서 이름·이미지를 숨김 (기본 true) */
contentVisible?: boolean;
};
export type BoardConfig = {
@@ -117,9 +119,18 @@ export function createRandomBoardConfig(
const geo = buildPerimeterGeometry(w, h);
const specials = defaultSpecials(w, h);
const cells: BoardCellConfig[] = geo.map((_, index) => {
if (index === 0) return { type: '시작', eventId: null, imageSrc: null };
if (specials[index]) return { ...specials[index], imageSrc: null };
return { type: randomPresetType(), eventId: null, imageSrc: null };
if (index === 0) {
return { type: '시작', eventId: null, imageSrc: null, contentVisible: true };
}
if (specials[index]) {
return { ...specials[index], imageSrc: null, contentVisible: true };
}
return {
type: randomPresetType(),
eventId: null,
imageSrc: null,
contentVisible: true,
};
});
return { version: BOARD_VERSION, width: w, height: h, cells };
}
@@ -136,7 +147,8 @@ function sanitizeCell(src: BoardCellConfig | undefined, fallback: BoardCellConfi
: String(src.eventId);
const imageSrc =
typeof src.imageSrc === 'string' && src.imageSrc.length > 0 ? src.imageSrc : null;
return { type: src.type.trim(), eventId, imageSrc };
const contentVisible = src.contentVisible !== false;
return { type: src.type.trim(), eventId, imageSrc, contentVisible };
}
export function normalizeBoardConfig(input: BoardConfig | null | undefined): BoardConfig {
@@ -154,7 +166,12 @@ export function normalizeBoardConfig(input: BoardConfig | null | undefined): Boa
cells.push(sanitizeCell(input.cells[i], base.cells[i]));
}
cells[0] = { type: '시작', eventId: null, imageSrc: cells[0]?.imageSrc ?? null };
cells[0] = {
type: '시작',
eventId: null,
imageSrc: cells[0]?.imageSrc ?? null,
contentVisible: cells[0]?.contentVisible !== false,
};
return { version: BOARD_VERSION, width, height, cells };
}
@@ -227,6 +244,7 @@ export function resizeBoardConfig(
type: '시작',
eventId: null,
imageSrc: prev.cells[0]?.imageSrc ?? null,
contentVisible: prev.cells[0]?.contentVisible !== false,
});
continue;
}
@@ -242,6 +260,7 @@ export function resizeBoardConfig(
type: src?.type && src.type !== '시작' ? src.type : randomPresetType(),
eventId: src?.eventId ?? null,
imageSrc: src?.imageSrc ?? null,
contentVisible: src?.contentVisible !== false,
});
}
@@ -258,6 +277,10 @@ export function updateBoardCell(
if (index < 0 || index >= current.cells.length) return current;
const cells = current.cells.map((cell, i) => {
if (i !== index) return cell;
const contentVisible =
patch.contentVisible === undefined
? cell.contentVisible !== false
: Boolean(patch.contentVisible);
if (i === 0) {
return {
type: '시작',
@@ -268,6 +291,7 @@ export function updateBoardCell(
: patch.imageSrc === ''
? null
: patch.imageSrc,
contentVisible,
};
}
return {
@@ -284,6 +308,7 @@ export function updateBoardCell(
: patch.imageSrc === ''
? null
: patch.imageSrc,
contentVisible,
};
});
const next = {
@@ -296,6 +321,25 @@ export function updateBoardCell(
return next;
}
/** 모든 칸의 내용 표시 여부를 한 번에 설정 */
export function setAllCellsContentVisible(
visible: boolean,
current = getOrCreateBoardConfig(),
): BoardConfig {
const cells = current.cells.map((cell) => ({
...cell,
contentVisible: visible,
}));
const next = {
version: BOARD_VERSION,
width: current.width,
height: current.height,
cells,
};
writeStoredBoard(next);
return next;
}
export function buildPlaneCells(config: BoardConfig = getOrCreateBoardConfig()): PlaneCell[] {
const normalized = normalizeBoardConfig(config);
const geo = buildPerimeterGeometry(normalized.width, normalized.height);
@@ -306,10 +350,19 @@ export function buildPlaneCells(config: BoardConfig = getOrCreateBoardConfig()):
type: normalized.cells[index]?.type ?? (index === 0 ? '시작' : '한잔'),
eventId: index === 0 ? null : (normalized.cells[index]?.eventId ?? null),
imageSrc: normalized.cells[index]?.imageSrc ?? null,
contentVisible: normalized.cells[index]?.contentVisible !== false,
}));
}
export function cellColorFor(eventId: string | null | undefined, index: number) {
export function cellColorFor(
eventId: string | null | undefined,
index: number,
options?: { contentVisible?: boolean },
) {
// 내용 숨김이면 종류가 색으로도 드러나지 않게 통일
if (options?.contentVisible === false && index !== 0) {
return '#be123c';
}
if (index === 0) return '#059669';
switch (eventId) {
case 'island':