# retoor <retoor@molodetz.nl>
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