Add type restriction rule (monolocke)
Adds allowedTypes: string[] to NuzlockeRules. When set, the encounter selector hides non-matching Pokemon and the routes endpoint filters out routes with no matching encounters, so only eligible locations appear. Type picker UI in RulesConfiguration; active restriction shown in RuleBadges. Backend accepts allowed_types query param and joins through RouteEncounter.pokemon to filter by type. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
from sqlalchemy import delete, select, update
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import selectinload
|
||||
@@ -131,6 +131,7 @@ async def get_game(game_id: int, session: AsyncSession = Depends(get_session)):
|
||||
async def list_game_routes(
|
||||
game_id: int,
|
||||
flat: bool = False,
|
||||
allowed_types: list[str] | None = Query(None),
|
||||
session: AsyncSession = Depends(get_session),
|
||||
):
|
||||
"""
|
||||
@@ -138,13 +139,18 @@ async def list_game_routes(
|
||||
|
||||
By default, returns a hierarchical structure with top-level routes containing
|
||||
nested children. Use `flat=True` to get a flat list of all routes.
|
||||
|
||||
When `allowed_types` is provided, routes with no encounters matching any of
|
||||
those Pokemon types are excluded.
|
||||
"""
|
||||
vg_id = await _get_version_group_id(session, game_id)
|
||||
|
||||
result = await session.execute(
|
||||
select(Route)
|
||||
.where(Route.version_group_id == vg_id)
|
||||
.options(selectinload(Route.route_encounters))
|
||||
.options(
|
||||
selectinload(Route.route_encounters).selectinload(RouteEncounter.pokemon)
|
||||
)
|
||||
.order_by(Route.order)
|
||||
)
|
||||
all_routes = result.scalars().all()
|
||||
@@ -170,7 +176,14 @@ async def list_game_routes(
|
||||
|
||||
# Determine which routes have encounters for this game
|
||||
def has_encounters(route: Route) -> bool:
|
||||
return any(re.game_id == game_id for re in route.route_encounters)
|
||||
encounters = [re for re in route.route_encounters if re.game_id == game_id]
|
||||
if not encounters:
|
||||
return False
|
||||
if allowed_types:
|
||||
return any(
|
||||
t in allowed_types for re in encounters for t in re.pokemon.types
|
||||
)
|
||||
return True
|
||||
|
||||
# Collect IDs of parent routes that have at least one child with encounters
|
||||
parents_with_children = set()
|
||||
|
||||
@@ -154,6 +154,7 @@ DEFAULT_RULES = {
|
||||
"egglocke": False,
|
||||
"wonderlocke": False,
|
||||
"randomizer": False,
|
||||
"allowedTypes": [],
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user