diff --git a/src/components/game/Game.tsx b/src/components/game/Game.tsx index 3ca14da..77b83c0 100644 --- a/src/components/game/Game.tsx +++ b/src/components/game/Game.tsx @@ -315,7 +315,10 @@ export default function Game() { 🐾 고양이 - + {rerollUnlocked && ( +
+ +
+ )}

ν•œ 마리만 선택할 수 μžˆμ–΄μš” Β· νŒ¨μ‹œλΈŒμ— 마우슀λ₯Ό 올리면 상세 정보가 λ³΄μž…λ‹ˆλ‹€

diff --git a/src/components/game/NicknameModal.tsx b/src/components/game/NicknameModal.tsx index 39696b8..1c404e0 100644 --- a/src/components/game/NicknameModal.tsx +++ b/src/components/game/NicknameModal.tsx @@ -56,10 +56,12 @@ export default function NicknameModal({ onDone }: { onDone: () => void }) { }; }, [trimmed, mode]); - // λͺ¨λ“œλ³„ κ²°μ • κ°€λŠ₯ 쑰건: μƒˆ λ§ˆμ„=μ‚¬μš© κ°€λŠ₯, 뢈러였기=이미 쑴재 + // λͺ¨λ“œλ³„ κ²°μ • κ°€λŠ₯ 쑰건: μƒˆ λ§ˆμ„=μ‚¬μš© κ°€λŠ₯(μ„œλ²„ λΆˆκ°€ μ‹œμ—λ„ ν—ˆμš©), 뢈러였기=이미 쑴재 const canConfirm = !submitting && - (mode === "new" ? status === "available" : status === "taken"); + (mode === "new" + ? status === "available" || status === "offline" + : status === "taken"); const confirm = async () => { if (!canConfirm) return; @@ -96,7 +98,7 @@ export default function NicknameModal({ onDone }: { onDone: () => void }) { checking: { text: "λ‹€λ₯Έ λ§ˆμ„κ³Ό κ²ΉμΉ˜λŠ”μ§€ 확인 쀑… 🐾", cls: "text-[#8a7551]" }, available: { text: "μ’‹μ•„, 이 이름은 λΉ„μ–΄ μžˆμ–΄! ✨", cls: "text-[#5c8a2a]" }, taken: { text: "μ•—, 이미 λ‹€λ₯Έ λ§ˆμ„μ΄ μ“°κ³  μžˆλŠ” 이름이야 πŸ™€", cls: "text-[#b0472a]" }, - offline: { text: "μ„œλ²„μ— λ‹Ώμ§€ μ•Šμ•„β€¦ μž μ‹œ ν›„ λ‹€μ‹œ μ‹œλ„ν•΄μ€˜", cls: "text-[#b0472a]" }, + offline: { text: "확인은 λͺ» ν–ˆμ§€λ§Œ 일단 μ‹œμž‘ν•  수 μžˆμ–΄! (λ‚˜μ€‘μ— μžλ™ 확인)", cls: "text-[#8a6316]" }, }, recover: { idle: { text: "μ˜ˆμ „μ— μ“°λ˜ λ§ˆμ„ 이름을 μ•Œλ €μ€˜!", cls: "text-[#8a7551]" }, diff --git a/src/lib/game/engine.ts b/src/lib/game/engine.ts index bcf80cd..ccae08f 100644 --- a/src/lib/game/engine.ts +++ b/src/lib/game/engine.ts @@ -598,7 +598,8 @@ export const engine = { if (state.happinessUnlocked) { if (st.fullness >= 80) st.happiness = Math.min(100, st.happiness + (1 / 60) * gainMul * dt); - if (st.fullness <= 0) + // κ΅Άμ£Όλ¦Ό ν•˜λ½ β€” νŒŒμ—… 쀑엔 μ œμ™Έ (회볡이 ν•˜λ½μ„ λͺ» 이기면 영ꡬ νŒŒμ—… λ°λ“œλ½) + if (st.fullness <= 0 && cat.state !== "striking") st.happiness = Math.max(0, st.happiness - (4 / 60) * decayMul * dt); // 고양이 μ§‘ λΆ€μ‘±: ν•˜λ½ν•˜λ˜ 이 μš”μΈλ§ŒμœΌλ‘œλŠ” νŒŒμ—…κΉŒμ§€ κ°€μ§€ μ•Šλ„λ‘ λ°”λ‹₯ 25 μœ μ§€ if ( @@ -631,6 +632,9 @@ export const engine = { cat.assignedTo = null; cat.state = "striking"; } + // νŒŒμ—… 쀑엔 λ†€λ©΄μ„œ μ„œμ„œνžˆ 기뢄이 ν’€λ¦Ό (전원 νŒŒμ—… λ°λ“œλ½ λ°©μ§€) + if (cat.state === "striking") + st.happiness = Math.min(100, st.happiness + (2 / 60) * dt); if (cat.state === "striking" && st.happiness >= STRIKE_RESUME) tryReturn(cat); } // happinessUnlocked diff --git a/src/lib/game/sync.ts b/src/lib/game/sync.ts index 095900e..4f380c8 100644 --- a/src/lib/game/sync.ts +++ b/src/lib/game/sync.ts @@ -38,16 +38,27 @@ export async function registerNickname( export async function pushSave(): Promise { const s = engine.peek(); if (!s?.nickname || !s.syncToken) return; + const body = JSON.stringify({ + nickname: s.nickname, + token: s.syncToken, + data: s, + }); try { - await fetch("/api/village/save", { + const res = await fetch("/api/village/save", { method: "POST", headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ - nickname: s.nickname, - token: s.syncToken, - data: s, - }), + body, }); + if (res.status === 403) { + // μ˜€ν”„λΌμΈ μƒνƒœμ—μ„œ μ‹œμž‘ν•΄ μ„œλ²„μ— λ“±λ‘λ˜μ§€ μ•Šμ€ λ‹‰λ„€μž„ β€” μž¬λ“±λ‘ ν›„ μž¬μ‹œλ„ + const ok = await registerNickname(s.nickname, s.syncToken); + if (ok) + await fetch("/api/village/save", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body, + }); + } } catch { // μ˜€ν”„λΌμΈμ΄λ©΄ λ‹€μŒ 주기에 μž¬μ‹œλ„ }