# retoor from __future__ import annotations import random from .. import economy from .common import GameError, _lvl, conditional_update_farm from .farm import ensure_farm, get_farm INFRA_COLUMN = {i.key: f"infra_{i.key}" for i in economy.INFRASTRUCTURE} def buy_infrastructure(user: dict, key: str) -> dict: infra = economy.infra_for(key) if not infra: raise GameError("Unknown infrastructure.") farm = ensure_farm(user["uid"]) column = INFRA_COLUMN[infra.key] rows = conditional_update_farm( farm["uid"], set_clause=f"coins = coins - :cost, {column} = 1", where_clause=( f"COALESCE({column}, 0) = 0 AND coins >= :cost " f"AND COALESCE(prestige, 0) >= :min_prestige" ), params={"cost": infra.cost, "min_prestige": infra.min_prestige}, ) if rows == 0: farm = get_farm(user["uid"]) if _lvl(farm, column): raise GameError("You already own that infrastructure.") if _lvl(farm, "prestige") < infra.min_prestige: raise GameError(f"{infra.name} requires prestige {infra.min_prestige}.") raise GameError("Not enough coins for that infrastructure.") return {"key": infra.key, "spent": infra.cost} def owns_infrastructure(farm: dict, key: str) -> bool: column = INFRA_COLUMN.get(key) return bool(column and _lvl(farm, column)) def roll_canary(coins_gain: int, plant_cost: int) -> int: roll = random.random() if roll < economy.CANARY_DOUBLE_CHANCE: return coins_gain * 2 if roll < economy.CANARY_DOUBLE_CHANCE + economy.CANARY_FAIL_CHANCE: return min(coins_gain, plant_cost) return coins_gain