건설 시간 시스템: 배치 후 공사장 표시 → 시간 경과 시 완공
- BuildDef.buildTime 추가 (부엌 60초, 채석장 120초), 상점에 ⏱ 표시 - 배치 확정 시 constructionUntil 타임스탬프 설정 (오프라인에도 진행) - 건설 중: 공사장 일러스트 + 🔨 카운트다운 판자 배지 + "건설 중" 라벨, 생산·배치 불가, 회관 증축 요건에도 미인정 - 패널: 공사장 이미지 + 진행 바 + 남은 시간 표시 - 완공 시 tick에서 자동 전환 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
이 커밋은 다음에 포함됨:
@@ -9,6 +9,7 @@ import {
|
||||
effectiveRate,
|
||||
activeRecipe,
|
||||
fullnessPenalty,
|
||||
isUnderConstruction,
|
||||
} from "@/lib/game/engine";
|
||||
import {
|
||||
APTITUDE_LABEL,
|
||||
@@ -408,6 +409,7 @@ function ShopPanel({
|
||||
<div className="font-jua text-[15px] text-[#3f2c14]">{def.name}</div>
|
||||
<div className="font-num text-xs text-[#8a6316]">
|
||||
{costEntries.map(([k, v]) => `${RES_EMOJI[k]} ${v}`).join(" + ")}
|
||||
{` · ⏱ ${def.buildTime}초`}
|
||||
{def.reqHallLv > 1 && ` · 회관 Lv${def.reqHallLv}`}
|
||||
</div>
|
||||
<div className="mt-0.5 line-clamp-2 text-[11px] text-[#8a7551]">{def.desc}</div>
|
||||
@@ -470,6 +472,33 @@ function BuildingPanel({
|
||||
effectiveRate(b, building.aptitude) - effectiveRate(a, building.aptitude),
|
||||
);
|
||||
|
||||
if (isUnderConstruction(building)) {
|
||||
const def = BUILD_DEFS.find((d) => d.type === building.type);
|
||||
const total = (def?.buildTime ?? 60) * 1000;
|
||||
const remainMs = Math.max(0, (building.constructionUntil ?? 0) - Date.now());
|
||||
const pct = Math.min(100, ((total - remainMs) / total) * 100);
|
||||
const remainSec = Math.ceil(remainMs / 1000);
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||
<img
|
||||
src={BUILDING_IMG.construction}
|
||||
alt="건설 중"
|
||||
className="mx-auto h-28 object-contain"
|
||||
/>
|
||||
<p className="text-center text-sm text-[#6f5c39]">
|
||||
🔨 열심히 짓는 중이에요…
|
||||
</p>
|
||||
<div className="bar-track h-3 w-full">
|
||||
<div className="bar-fill-amber" style={{ width: `${pct}%` }} />
|
||||
</div>
|
||||
<p className="font-num text-center text-sm text-[#8a6316]">
|
||||
남은 시간 {Math.floor(remainSec / 60)}:{String(remainSec % 60).padStart(2, "0")}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="space-y-5">
|
||||
{/* 정보 */}
|
||||
|
||||
새 이슈에서 참조
사용자 차단