Files
devplacepy/devplacepy/services/game/store/quests.py
T
retoorandClaude Sonnet 5 34f76aad65 Code Farm economy rebalance: market saturation, infrastructure/defense/cosmetics, mastery track, secondary leaderboards, admin eras, underdog bonus and weekly contracts
Every purchase/upgrade path (new and pre-existing) is now race-safe against concurrent requests via atomic conditional SQL updates.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-22 23:55:46 +02:00

98 lines
3.0 KiB
Python

# retoor <retoor@molodetz.nl>
from __future__ import annotations
from devplacepy.utils import generate_uid
from .. import economy
from .common import _iso, _iso_week, _lvl, _now, _quests, _today
from .farm import get_farm
WEEKLY_SLOT_INDEX = 3
def ensure_quests(farm: dict, day: str) -> None:
if _quests().find_one(farm_uid=farm["uid"], day=day, scope="daily"):
return
now = _iso(_now())
for index, quest in enumerate(economy.daily_quests(farm["user_uid"], day)):
_quests().insert(
{
"uid": generate_uid(),
"farm_uid": farm["uid"],
"user_uid": farm["user_uid"],
"day": day,
"scope": "daily",
"slot_index": index,
"kind": quest["kind"],
"label": quest["label"],
"goal": quest["goal"],
"progress": 0,
"reward_coins": quest["reward_coins"],
"reward_xp": quest["reward_xp"],
"reward_stars": 0,
"claimed": 0,
"created_at": now,
"updated_at": now,
}
)
def ensure_weekly_contract(farm: dict, iso_week: str) -> None:
if not _lvl(farm, "mastery_contracts"):
return
if _quests().find_one(farm_uid=farm["uid"], day=iso_week, scope="weekly"):
return
now = _iso(_now())
contract = economy.weekly_contract(farm["user_uid"], iso_week)
_quests().insert(
{
"uid": generate_uid(),
"farm_uid": farm["uid"],
"user_uid": farm["user_uid"],
"day": iso_week,
"scope": "weekly",
"slot_index": WEEKLY_SLOT_INDEX,
"kind": contract["kind"],
"label": contract["label"],
"goal": contract["goal"],
"progress": 0,
"reward_coins": 0,
"reward_xp": contract["reward_xp"],
"reward_stars": contract["reward_stars"],
"claimed": 0,
"created_at": now,
"updated_at": now,
}
)
def advance_quests(user_uid: str, kind: str, amount: int) -> None:
if amount <= 0:
return
try:
farm = get_farm(user_uid)
if not farm:
return
now = _now()
day = _today()
ensure_quests(farm, day)
iso_week = _iso_week(now)
ensure_weekly_contract(farm, iso_week)
rows = list(_quests().find(farm_uid=farm["uid"], day=day, kind=kind, scope="daily"))
rows += list(
_quests().find(farm_uid=farm["uid"], day=iso_week, kind=kind, scope="weekly")
)
for row in rows:
if row.get("claimed"):
continue
goal = int(row.get("goal") or 0)
progress = min(goal, int(row.get("progress") or 0) + amount)
_quests().update(
{"uid": row["uid"], "progress": progress, "updated_at": _iso(now)},
["uid"],
)
except Exception:
return