# retoor <retoor@molodetz.nl>
from __future__ import annotations
from sqlalchemy.exc import IntegrityError
from devplacepy.database import get_table
from devplacepy.utils import generate_uid
from .. import economy
from .common import GameError, _iso, _now, _update_farm, conditional_update_farm
from .farm import ensure_farm
def _cosmetics():
return get_table("game_cosmetics")
def owned_cosmetic_keys(user_uid: str) -> set[str]:
return {row["cosmetic_key"] for row in _cosmetics().find(user_uid=user_uid)}
def buy_cosmetic(user: dict, key: str) -> dict:
cosmetic = economy.cosmetic_for(key)
if not cosmetic:
raise GameError("Unknown cosmetic.")
farm = ensure_farm(user["uid"])
now = _iso(_now())
row_uid = generate_uid()
try:
_cosmetics().insert(
{
"uid": row_uid,
"user_uid": user["uid"],
"cosmetic_key": key,
"purchased_at": now,
"created_at": now,
}
)
except IntegrityError:
raise GameError("You already own that cosmetic.")
rows = conditional_update_farm(
farm["uid"],
set_clause="coins = coins - :cost",
where_clause="coins >= :cost",
params={"cost": cosmetic.cost_coins},
)
if rows == 0:
_cosmetics().delete(uid=row_uid)
raise GameError("Not enough coins for that cosmetic.")
return {"key": key, "spent": cosmetic.cost_coins}
def equip_title(user: dict, key: str) -> dict:
cosmetic = economy.cosmetic_for(key)
if not cosmetic or cosmetic.kind != "title":
raise GameError("Unknown title.")
if key not in owned_cosmetic_keys(user["uid"]):
raise GameError("You do not own that title.")
farm = ensure_farm(user["uid"])
_update_farm(farm["uid"], {"active_title": key})
return {"active_title": key}