건설 시간 시스템: 배치 후 공사장 표시 → 시간 경과 시 완공
- BuildDef.buildTime 추가 (부엌 60초, 채석장 120초), 상점에 ⏱ 표시 - 배치 확정 시 constructionUntil 타임스탬프 설정 (오프라인에도 진행) - 건설 중: 공사장 일러스트 + 🔨 카운트다운 판자 배지 + "건설 중" 라벨, 생산·배치 불가, 회관 증축 요건에도 미인정 - 패널: 공사장 이미지 + 진행 바 + 남은 시간 표시 - 완공 시 tick에서 자동 전환 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
이 커밋은 다음에 포함됨:
+18
-1
@@ -162,6 +162,11 @@ function passiveFoodMul(cat: Cat): number {
|
||||
return mul;
|
||||
}
|
||||
|
||||
/** 건설 중인가 */
|
||||
export function isUnderConstruction(b: Building): boolean {
|
||||
return b.constructionUntil !== undefined && Date.now() < b.constructionUntil;
|
||||
}
|
||||
|
||||
/** 사각 풋프린트 겹침 검사 */
|
||||
function rectsOverlap(
|
||||
a: { i: number; j: number; w: number; h: number },
|
||||
@@ -256,6 +261,14 @@ export const engine = {
|
||||
tick(dt: number) {
|
||||
if (!state) return;
|
||||
for (const building of state.buildings) {
|
||||
// 건설 완료 체크
|
||||
if (building.constructionUntil !== undefined) {
|
||||
if (Date.now() >= building.constructionUntil) {
|
||||
building.constructionUntil = undefined;
|
||||
} else {
|
||||
continue; // 건설 중 — 생산 없음
|
||||
}
|
||||
}
|
||||
let produced = 0;
|
||||
for (const catId of building.assigned) {
|
||||
const cat = state.cats.find((c) => c.id === catId);
|
||||
@@ -354,6 +367,7 @@ export const engine = {
|
||||
pos: { i: pos.i, j: pos.j },
|
||||
level: 1, maxSlots: def.maxSlots, aptitude: def.aptitude,
|
||||
resource: def.resource, assigned: [], stored: 0, progress: 0,
|
||||
constructionUntil: Date.now() + def.buildTime * 1000,
|
||||
});
|
||||
return null;
|
||||
},
|
||||
@@ -415,7 +429,8 @@ export const engine = {
|
||||
}
|
||||
for (const req of next.reqBuildings ?? []) {
|
||||
const b = state.buildings.find((x) => x.type === req.type);
|
||||
if (!b || b.level < (req.level ?? 1)) missing.push(req.label);
|
||||
if (!b || isUnderConstruction(b) || b.level < (req.level ?? 1))
|
||||
missing.push(req.label);
|
||||
}
|
||||
if (next.reqCat) {
|
||||
const count = state.cats.filter((c) => c.level >= next.reqCat!.level).length;
|
||||
@@ -434,6 +449,8 @@ export const engine = {
|
||||
const cat = state.cats.find((c) => c.id === catId);
|
||||
const building = state.buildings.find((b) => b.id === buildingId);
|
||||
if (!cat || !building) return null;
|
||||
if (isUnderConstruction(building))
|
||||
return `${building.name}은(는) 아직 건설 중입니다`;
|
||||
if (cat.aptitude[building.aptitude] === 0)
|
||||
return `${cat.name}은(는) ${building.name} 적성이 없습니다`;
|
||||
if (building.assigned.length >= building.maxSlots)
|
||||
|
||||
새 이슈에서 참조
사용자 차단