|
# 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}
|