feat: add steal mechanic to Code Farm with 60s protection window and half-coin reward

This commit is contained in:
2026-06-22 17:33:03 +00:00
parent ebf6bf7f82
commit 412dbe3a3d
13 changed files with 302 additions and 14 deletions
+43 -1
View File
@@ -9,7 +9,12 @@ from devplacepy.models import GameSlotForm
from devplacepy.responses import json_error, respond, wants_json
from devplacepy.schemas import GameFarmViewOut
from devplacepy.services.game import GameError, store
from devplacepy.utils import get_current_user, require_user, track_action
from devplacepy.utils import (
create_notification,
get_current_user,
require_user,
track_action,
)
from ._shared import game_seo, notify_farm, owner_by_username
@@ -65,3 +70,40 @@ async def water_farm(
)
return JSONResponse(GameFarmViewOut(farm=payload).model_dump(mode="json"))
return RedirectResponse(url=f"/game/farm/{username}", status_code=302)
@router.post("/farm/{username}/steal")
async def steal_farm(
request: Request, username: str, data: Annotated[GameSlotForm, Form()]
):
viewer = require_user(request)
owner = owner_by_username(username)
if not owner:
raise HTTPException(status_code=404, detail="Farm not found")
try:
result = store.steal(viewer, owner, data.slot)
except GameError as exc:
if wants_json(request):
return json_error(400, str(exc))
return RedirectResponse(url=f"/game/farm/{username}", status_code=302)
track_action(viewer["uid"], "harvest_stolen")
track_action(owner["uid"], "got_stolen_from")
create_notification(
owner["uid"],
"harvest_stolen",
"Someone raided your Code Farm and stole a ready build.",
viewer["uid"],
"/game",
)
await notify_farm(owner["username"])
await notify_farm(viewer["username"])
if wants_json(request):
payload = store.serialize_farm(
store.ensure_farm(owner["uid"]), viewer=viewer, owner=owner
)
return JSONResponse(
GameFarmViewOut(farm=payload, stole_coins=result["coins"]).model_dump(
mode="json"
)
)
return RedirectResponse(url=f"/game/farm/{username}", status_code=302)