# 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, conditional_update_row
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
conditional_update_row(
"game_quests",
row["uid"],
"progress = MIN(COALESCE(goal, 0), COALESCE(progress, 0) + :amount)",
"COALESCE(claimed, 0) = 0",
{"amount": amount},
)
except Exception:
return