feat: obtížnější chytání motýlků + zloděj, housenka a agresivní škůdci
CI / Generate TypeScript types (push) Successful in 12s
CI / Server unit tests (push) Successful in 22s
CI / Build server (push) Successful in 29s
CI / Build client (push) Successful in 41s
CI / Playwright E2E tests (push) Successful in 1m25s
CI / Build and push Docker image (push) Successful in 45s
CI / Notify (push) Successful in 2s

- 60 úrovní se strmou křivkou, dražší vylepšení, vzácnější zlatý motýl
- ochrana proti podvádění (rate cap + cooldown chytání)
- perzistentní škůdci přibývají rychleji; vosy nalétávají do síťky, ptáci ji protrhnou vždy
- protržená síťka se sama zašije za minutu (nebo okamžitě za mince)
- zloděj krade mince a housenka žere úlovky – oba se plíží k počítadlu a jdou zaklikat
- plašič ptáků s odpočtem, level progress bar, nová sezóna (reset statistik)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Stánek Pavel
2026-07-22 14:10:29 +02:00
co-authored by Claude Opus 4.8
parent c5ca6c9d41
commit e3f439bde0
14 changed files with 918 additions and 347 deletions
+36
View File
@@ -8,6 +8,10 @@ import {
killWasp,
buyRepellent,
reportNetTorn,
robbery,
defeatThief,
caterpillarAte,
defeatCaterpillar,
getLeaderboard,
InsufficientCoinsError,
} from "../butterflies";
@@ -76,6 +80,38 @@ router.post("/tear", async (req: Request, res, next) => {
} catch (e: any) { next(e) }
});
router.post("/robbery", async (req: Request, res, next) => {
try {
const login = getLogin(parseToken(req));
const data = await robbery(login);
res.status(200).json(data);
} catch (e: any) { next(e) }
});
router.post("/defeatThief", async (req: Request, res, next) => {
try {
const login = getLogin(parseToken(req));
const data = await defeatThief(login);
res.status(200).json(data);
} catch (e: any) { next(e) }
});
router.post("/caterpillarAte", async (req: Request, res, next) => {
try {
const login = getLogin(parseToken(req));
const data = await caterpillarAte(login);
res.status(200).json(data);
} catch (e: any) { next(e) }
});
router.post("/defeatCaterpillar", async (req: Request, res, next) => {
try {
const login = getLogin(parseToken(req));
const data = await defeatCaterpillar(login);
res.status(200).json(data);
} catch (e: any) { next(e) }
});
router.get("/leaderboard", async (req: Request, res, next) => {
try {
getLogin(parseToken(req));