refactor: split game store.py into subpackage (ref.md 3.11)
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
# retoor <retoor@molodetz.nl>
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from devplacepy.utils import generate_uid
|
||||
|
||||
from .. import economy
|
||||
from .common import GameError, _farms, _iso, _now, _plots, _update_farm
|
||||
|
||||
|
||||
def get_farm(user_uid: str) -> dict | None:
|
||||
return _farms().find_one(user_uid=user_uid)
|
||||
|
||||
|
||||
def ensure_farm(user_uid: str) -> dict:
|
||||
farm = get_farm(user_uid)
|
||||
if farm:
|
||||
return farm
|
||||
now = _iso(_now())
|
||||
uid = generate_uid()
|
||||
_farms().insert(
|
||||
{
|
||||
"uid": uid,
|
||||
"user_uid": user_uid,
|
||||
"coins": economy.STARTING_COINS,
|
||||
"xp": 0,
|
||||
"level": 1,
|
||||
"ci_tier": 1,
|
||||
"plot_count": economy.STARTING_PLOTS,
|
||||
"total_harvests": 0,
|
||||
"created_at": now,
|
||||
"updated_at": now,
|
||||
}
|
||||
)
|
||||
for slot_index in range(economy.STARTING_PLOTS):
|
||||
_create_plot(uid, user_uid, slot_index, now)
|
||||
return get_farm(user_uid)
|
||||
|
||||
|
||||
def _create_plot(farm_uid: str, user_uid: str, slot_index: int, now: str) -> None:
|
||||
_plots().insert(
|
||||
{
|
||||
"uid": generate_uid(),
|
||||
"farm_uid": farm_uid,
|
||||
"user_uid": user_uid,
|
||||
"slot_index": slot_index,
|
||||
"crop_key": "",
|
||||
"planted_at": "",
|
||||
"ready_at": "",
|
||||
"watered_by": "[]",
|
||||
"created_at": now,
|
||||
"updated_at": now,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def get_plots(farm_uid: str) -> list[dict]:
|
||||
rows = list(_plots().find(farm_uid=farm_uid))
|
||||
rows.sort(key=lambda row: row.get("slot_index", 0))
|
||||
return rows
|
||||
|
||||
|
||||
def _plot_at(farm_uid: str, slot_index: int) -> dict | None:
|
||||
return _plots().find_one(farm_uid=farm_uid, slot_index=slot_index)
|
||||
|
||||
|
||||
def buy_plot(user: dict) -> dict:
|
||||
farm = ensure_farm(user["uid"])
|
||||
plot_count = int(farm.get("plot_count", economy.STARTING_PLOTS))
|
||||
if plot_count >= economy.MAX_PLOTS:
|
||||
raise GameError("All plots are already unlocked.")
|
||||
cost = economy.plot_cost(plot_count)
|
||||
coins = int(farm.get("coins", 0))
|
||||
if coins < cost:
|
||||
raise GameError("Not enough coins for a new plot.")
|
||||
_create_plot(farm["uid"], user["uid"], plot_count, _iso(_now()))
|
||||
_update_farm(farm["uid"], {"coins": coins - cost, "plot_count": plot_count + 1})
|
||||
return {"plot_count": plot_count + 1, "spent": cost}
|
||||
|
||||
|
||||
def upgrade_ci(user: dict) -> dict:
|
||||
farm = ensure_farm(user["uid"])
|
||||
ci_tier = int(farm.get("ci_tier", 1))
|
||||
next_tier = economy.next_ci_tier(ci_tier)
|
||||
if not next_tier:
|
||||
raise GameError("CI is already at the top tier.")
|
||||
coins = int(farm.get("coins", 0))
|
||||
if coins < next_tier.upgrade_cost:
|
||||
raise GameError("Not enough coins to upgrade CI.")
|
||||
_update_farm(
|
||||
farm["uid"],
|
||||
{"coins": coins - next_tier.upgrade_cost, "ci_tier": next_tier.tier},
|
||||
)
|
||||
return {"ci_tier": next_tier.tier, "spent": next_tier.upgrade_cost}
|
||||
|
||||
|
||||
def leaderboard(limit: int = 25) -> list[dict]:
|
||||
farms = sorted(
|
||||
_farms().find(),
|
||||
key=economy.farm_score,
|
||||
reverse=True,
|
||||
)[:limit]
|
||||
if not farms:
|
||||
return []
|
||||
from devplacepy.database import get_users_by_uids
|
||||
|
||||
users = get_users_by_uids([farm["user_uid"] for farm in farms])
|
||||
entries = []
|
||||
for rank, farm in enumerate(farms, start=1):
|
||||
owner = users.get(farm["user_uid"])
|
||||
if not owner:
|
||||
continue
|
||||
entries.append(
|
||||
{
|
||||
"rank": rank,
|
||||
"username": owner.get("username", ""),
|
||||
"level": int(farm.get("level", 1)),
|
||||
"xp": int(farm.get("xp", 0)),
|
||||
"coins": int(farm.get("coins", 0)),
|
||||
"total_harvests": int(farm.get("total_harvests", 0)),
|
||||
"prestige": int(farm.get("prestige") or 0),
|
||||
"score": economy.farm_score(farm),
|
||||
}
|
||||
)
|
||||
return entries
|
||||
Reference in New Issue
Block a user