465 lines
15 KiB
Python
465 lines
15 KiB
Python
from __future__ import annotations
|
|
|
|
from functools import partial
|
|
from typing import Literal, cast
|
|
|
|
from app.database.beatmap import calculate_beatmap_attributes
|
|
from app.database.score import Beatmap, Score
|
|
from app.dependencies.database import get_redis
|
|
from app.dependencies.fetcher import get_fetcher
|
|
from app.models.achievement import Achievement, Medals
|
|
from app.models.mods import API_MODS, mods_can_get_pp_vanilla
|
|
from app.models.score import GameMode
|
|
|
|
from sqlmodel.ext.asyncio.session import AsyncSession
|
|
|
|
|
|
async def process_skill(
|
|
target_gamemode: GameMode,
|
|
star: int,
|
|
type: Literal["pass", "fc"],
|
|
session: AsyncSession,
|
|
score: Score,
|
|
beatmap: Beatmap,
|
|
) -> bool:
|
|
if target_gamemode != score.gamemode:
|
|
return False
|
|
ruleset_id = int(score.gamemode)
|
|
if not score.passed:
|
|
return False
|
|
if not beatmap.beatmap_status.has_pp():
|
|
return False
|
|
if not mods_can_get_pp_vanilla(ruleset_id, score.mods):
|
|
return False
|
|
difficulty_reduction_mods = [
|
|
mod["Acronym"]
|
|
for mod in API_MODS[cast(Literal[0, 1, 2, 3], ruleset_id)].values()
|
|
if mod["Type"] == "DifficultyReduction"
|
|
]
|
|
for mod in score.mods:
|
|
if mod["acronym"] in difficulty_reduction_mods:
|
|
return False
|
|
|
|
fetcher = await get_fetcher()
|
|
redis = get_redis()
|
|
mods_ = score.mods.copy()
|
|
mods_.sort(key=lambda x: x["acronym"])
|
|
attribute = await calculate_beatmap_attributes(beatmap.id, score.gamemode, mods_, redis, fetcher)
|
|
if attribute.star_rating < star or attribute.star_rating >= star + 1:
|
|
return False
|
|
if type == "fc" and not score.is_perfect_combo:
|
|
return False
|
|
return True
|
|
|
|
|
|
MEDALS: Medals = {
|
|
Achievement(
|
|
id=1,
|
|
name="Rising Star",
|
|
desc="Can't go forward without the first steps.",
|
|
assets_id="osu-skill-pass-1",
|
|
): partial(process_skill, GameMode.OSU, 1, "pass"),
|
|
Achievement(
|
|
id=2,
|
|
name="Constellation Prize",
|
|
desc="Definitely not a consolation prize. Now things start getting hard!",
|
|
assets_id="osu-skill-pass-2",
|
|
): partial(process_skill, GameMode.OSU, 2, "pass"),
|
|
Achievement(
|
|
id=3,
|
|
name="Building Confidence",
|
|
desc="Oh, you've SO got this.",
|
|
assets_id="osu-skill-pass-3",
|
|
): partial(process_skill, GameMode.OSU, 3, "pass"),
|
|
Achievement(
|
|
id=4,
|
|
name="Insanity Approaches",
|
|
desc="You're not twitching, you're just ready.",
|
|
assets_id="osu-skill-pass-4",
|
|
): partial(process_skill, GameMode.OSU, 4, "pass"),
|
|
Achievement(
|
|
id=5,
|
|
name="These Clarion Skies",
|
|
desc="Everything seems so clear now.",
|
|
assets_id="osu-skill-pass-5",
|
|
): partial(process_skill, GameMode.OSU, 5, "pass"),
|
|
Achievement(
|
|
id=6,
|
|
name="Above and Beyond",
|
|
desc="A cut above the rest.",
|
|
assets_id="osu-skill-pass-6",
|
|
): partial(process_skill, GameMode.OSU, 6, "pass"),
|
|
Achievement(
|
|
id=7,
|
|
name="Supremacy",
|
|
desc="All marvel before your prowess.",
|
|
assets_id="osu-skill-pass-7",
|
|
): partial(process_skill, GameMode.OSU, 7, "pass"),
|
|
Achievement(
|
|
id=8,
|
|
name="Absolution",
|
|
desc="My god, you're full of stars!",
|
|
assets_id="osu-skill-pass-8",
|
|
): partial(process_skill, GameMode.OSU, 8, "pass"),
|
|
Achievement(
|
|
id=9,
|
|
name="Event Horizon",
|
|
desc="No force dares to pull you under.",
|
|
assets_id="osu-skill-pass-9",
|
|
): partial(process_skill, GameMode.OSU, 9, "pass"),
|
|
Achievement(
|
|
id=10,
|
|
name="Phantasm",
|
|
desc="Fevered is your passion, extraordinary is your skill.",
|
|
assets_id="osu-skill-pass-10",
|
|
): partial(process_skill, GameMode.OSU, 10, "pass"),
|
|
Achievement(
|
|
id=11,
|
|
name="Totality",
|
|
desc="All the notes. Every single one.",
|
|
assets_id="osu-skill-fc-1",
|
|
): partial(process_skill, GameMode.OSU, 1, "fc"),
|
|
Achievement(
|
|
id=12,
|
|
name="Business As Usual",
|
|
desc="Two to go, please.",
|
|
assets_id="osu-skill-fc-2",
|
|
): partial(process_skill, GameMode.OSU, 2, "fc"),
|
|
Achievement(
|
|
id=13,
|
|
name="Building Steam",
|
|
desc="Hey, this isn't so bad.",
|
|
assets_id="osu-skill-fc-3",
|
|
): partial(process_skill, GameMode.OSU, 3, "fc"),
|
|
Achievement(
|
|
id=14,
|
|
name="Moving Forward",
|
|
desc="Bet you feel good about that.",
|
|
assets_id="osu-skill-fc-4",
|
|
): partial(process_skill, GameMode.OSU, 4, "fc"),
|
|
Achievement(
|
|
id=15,
|
|
name="Paradigm Shift",
|
|
desc="Surprisingly difficult.",
|
|
assets_id="osu-skill-fc-5",
|
|
): partial(process_skill, GameMode.OSU, 5, "fc"),
|
|
Achievement(
|
|
id=16,
|
|
name="Anguish Quelled",
|
|
desc="Don't choke.",
|
|
assets_id="osu-skill-fc-6",
|
|
): partial(process_skill, GameMode.OSU, 6, "fc"),
|
|
Achievement(
|
|
id=17,
|
|
name="Never Give Up",
|
|
desc="Excellence is its own reward.",
|
|
assets_id="osu-skill-fc-7",
|
|
): partial(process_skill, GameMode.OSU, 7, "fc"),
|
|
Achievement(
|
|
id=18,
|
|
name="Aberration",
|
|
desc="They said it couldn't be done. They were wrong.",
|
|
assets_id="osu-skill-fc-8",
|
|
): partial(process_skill, GameMode.OSU, 8, "fc"),
|
|
Achievement(
|
|
id=19,
|
|
name="Chosen",
|
|
desc="Reign among the Prometheans, where you belong.",
|
|
assets_id="osu-skill-fc-9",
|
|
): partial(process_skill, GameMode.OSU, 9, "fc"),
|
|
Achievement(
|
|
id=20,
|
|
name="Unfathomable",
|
|
desc="You have no equal.",
|
|
assets_id="osu-skill-fc-10",
|
|
): partial(process_skill, GameMode.OSU, 10, "fc"),
|
|
Achievement(
|
|
id=25,
|
|
name="My First Don",
|
|
desc="Marching to the beat of your own drum. Literally.",
|
|
assets_id="taiko-skill-pass-1",
|
|
): partial(process_skill, GameMode.TAIKO, 1, "pass"),
|
|
Achievement(
|
|
id=26,
|
|
name="Katsu Katsu Katsu",
|
|
desc="Hora! Izuko!",
|
|
assets_id="taiko-skill-pass-2",
|
|
): partial(process_skill, GameMode.TAIKO, 2, "pass"),
|
|
Achievement(
|
|
id=27,
|
|
name="Not Even Trying",
|
|
desc="Muzukashii? Not even.",
|
|
assets_id="taiko-skill-pass-3",
|
|
): partial(process_skill, GameMode.TAIKO, 3, "pass"),
|
|
Achievement(
|
|
id=28,
|
|
name="Face Your Demons",
|
|
desc="The first trials are now behind you, but are you a match for the Oni?",
|
|
assets_id="taiko-skill-pass-4",
|
|
): partial(process_skill, GameMode.TAIKO, 4, "pass"),
|
|
Achievement(
|
|
id=29,
|
|
name="The Demon Within",
|
|
desc="No rest for the wicked.",
|
|
assets_id="taiko-skill-pass-5",
|
|
): partial(process_skill, GameMode.TAIKO, 5, "pass"),
|
|
Achievement(
|
|
id=30,
|
|
name="Drumbreaker",
|
|
desc="Too strong.",
|
|
assets_id="taiko-skill-pass-6",
|
|
): partial(process_skill, GameMode.TAIKO, 6, "pass"),
|
|
Achievement(
|
|
id=31,
|
|
name="The Godfather",
|
|
desc="You are the Don of Dons.",
|
|
assets_id="taiko-skill-pass-7",
|
|
): partial(process_skill, GameMode.TAIKO, 7, "pass"),
|
|
Achievement(
|
|
id=32,
|
|
name="Rhythm Incarnate",
|
|
desc="Feel the beat. Become the beat.",
|
|
assets_id="taiko-skill-pass-8",
|
|
): partial(process_skill, GameMode.TAIKO, 8, "pass"),
|
|
Achievement(
|
|
id=33,
|
|
name="Keeping Time",
|
|
desc="Don, then katsu. Don, then katsu..",
|
|
assets_id="taiko-skill-fc-1",
|
|
): partial(process_skill, GameMode.TAIKO, 1, "fc"),
|
|
Achievement(
|
|
id=34,
|
|
name="To Your Own Beat",
|
|
desc="Straight and steady.",
|
|
assets_id="taiko-skill-fc-2",
|
|
): partial(process_skill, GameMode.TAIKO, 2, "fc"),
|
|
Achievement(
|
|
id=35,
|
|
name="Big Drums",
|
|
desc="Bigger scores to match.",
|
|
assets_id="taiko-skill-fc-3",
|
|
): partial(process_skill, GameMode.TAIKO, 3, "fc"),
|
|
Achievement(
|
|
id=36,
|
|
name="Adversity Overcome",
|
|
desc="Difficult? Not for you.",
|
|
assets_id="taiko-skill-fc-4",
|
|
): partial(process_skill, GameMode.TAIKO, 4, "fc"),
|
|
Achievement(
|
|
id=37,
|
|
name="Demonslayer",
|
|
desc="An Oni felled forevermore.",
|
|
assets_id="taiko-skill-fc-5",
|
|
): partial(process_skill, GameMode.TAIKO, 5, "fc"),
|
|
Achievement(
|
|
id=38,
|
|
name="Rhythm's Call",
|
|
desc="Heralding true skill.",
|
|
assets_id="taiko-skill-fc-6",
|
|
): partial(process_skill, GameMode.TAIKO, 6, "fc"),
|
|
Achievement(
|
|
id=39,
|
|
name="Time Everlasting",
|
|
desc="Not a single beat escapes you.",
|
|
assets_id="taiko-skill-fc-7",
|
|
): partial(process_skill, GameMode.TAIKO, 7, "fc"),
|
|
Achievement(
|
|
id=40,
|
|
name="The Drummer's Throne",
|
|
desc="Percussive brilliance befitting royalty alone.",
|
|
assets_id="taiko-skill-fc-8",
|
|
): partial(process_skill, GameMode.TAIKO, 8, "fc"),
|
|
Achievement(
|
|
id=41,
|
|
name="A Slice Of Life",
|
|
desc="Hey, this fruit catching business isn't bad.",
|
|
assets_id="fruits-skill-pass-1",
|
|
): partial(process_skill, GameMode.FRUITS, 1, "pass"),
|
|
Achievement(
|
|
id=42,
|
|
name="Dashing Ever Forward",
|
|
desc="Fast is how you do it.",
|
|
assets_id="fruits-skill-pass-2",
|
|
): partial(process_skill, GameMode.FRUITS, 2, "pass"),
|
|
Achievement(
|
|
id=43,
|
|
name="Zesty Disposition",
|
|
desc="No scurvy for you, not with that much fruit.",
|
|
assets_id="fruits-skill-pass-3",
|
|
): partial(process_skill, GameMode.FRUITS, 3, "pass"),
|
|
Achievement(
|
|
id=44,
|
|
name="Hyperdash ON!",
|
|
desc="Time and distance is no obstacle to you.",
|
|
assets_id="fruits-skill-pass-4",
|
|
): partial(process_skill, GameMode.FRUITS, 4, "pass"),
|
|
Achievement(
|
|
id=45,
|
|
name="It's Raining Fruit",
|
|
desc="And you can catch them all.",
|
|
assets_id="fruits-skill-pass-5",
|
|
): partial(process_skill, GameMode.FRUITS, 5, "pass"),
|
|
Achievement(
|
|
id=46,
|
|
name="Fruit Ninja",
|
|
desc="Legendary techniques.",
|
|
assets_id="fruits-skill-pass-6",
|
|
): partial(process_skill, GameMode.FRUITS, 6, "pass"),
|
|
Achievement(
|
|
id=47,
|
|
name="Dreamcatcher",
|
|
desc="No fruit, only dreams now.",
|
|
assets_id="fruits-skill-pass-7",
|
|
): partial(process_skill, GameMode.FRUITS, 7, "pass"),
|
|
Achievement(
|
|
id=48,
|
|
name="Lord of the Catch",
|
|
desc="Your kingdom kneels before you.",
|
|
assets_id="fruits-skill-pass-8",
|
|
): partial(process_skill, GameMode.FRUITS, 8, "pass"),
|
|
Achievement(
|
|
id=49,
|
|
name="Sweet And Sour",
|
|
desc="Apples and oranges, literally.",
|
|
assets_id="fruits-skill-fc-1",
|
|
): partial(process_skill, GameMode.FRUITS, 1, "fc"),
|
|
Achievement(
|
|
id=50,
|
|
name="Reaching The Core",
|
|
desc="The seeds of future success.",
|
|
assets_id="fruits-skill-fc-2",
|
|
): partial(process_skill, GameMode.FRUITS, 2, "fc"),
|
|
Achievement(
|
|
id=51,
|
|
name="Clean Platter",
|
|
desc="Clean only of failure. It is completely full, otherwise.",
|
|
assets_id="fruits-skill-fc-3",
|
|
): partial(process_skill, GameMode.FRUITS, 3, "fc"),
|
|
Achievement(
|
|
id=52,
|
|
name="Between The Rain",
|
|
desc="No umbrella needed.",
|
|
assets_id="fruits-skill-fc-4",
|
|
): partial(process_skill, GameMode.FRUITS, 4, "fc"),
|
|
Achievement(
|
|
id=53,
|
|
name="Addicted",
|
|
desc="That was an overdose?",
|
|
assets_id="fruits-skill-fc-5",
|
|
): partial(process_skill, GameMode.FRUITS, 5, "fc"),
|
|
Achievement(
|
|
id=54,
|
|
name="Quickening",
|
|
desc="A dash above normal limits.",
|
|
assets_id="fruits-skill-fc-6",
|
|
): partial(process_skill, GameMode.FRUITS, 6, "fc"),
|
|
Achievement(
|
|
id=55,
|
|
name="Supersonic",
|
|
desc="Faster than is reasonably necessary.",
|
|
assets_id="fruits-skill-fc-7",
|
|
): partial(process_skill, GameMode.FRUITS, 7, "fc"),
|
|
Achievement(
|
|
id=56,
|
|
name="Dashing Scarlet",
|
|
desc="Speed beyond mortal reckoning.",
|
|
assets_id="fruits-skill-fc-8",
|
|
): partial(process_skill, GameMode.FRUITS, 8, "fc"),
|
|
Achievement(
|
|
id=57,
|
|
name="First Steps",
|
|
desc="It isn't 9-to-5, but 1-to-9. Keys, that is.",
|
|
assets_id="mania-skill-pass-1",
|
|
): partial(process_skill, GameMode.MANIA, 1, "pass"),
|
|
Achievement(
|
|
id=58,
|
|
name="No Normal Player",
|
|
desc="Not anymore, at least.",
|
|
assets_id="mania-skill-pass-2",
|
|
): partial(process_skill, GameMode.MANIA, 2, "pass"),
|
|
Achievement(
|
|
id=59,
|
|
name="Impulse Drive",
|
|
desc="Not quite hyperspeed, but getting close.",
|
|
assets_id="mania-skill-pass-3",
|
|
): partial(process_skill, GameMode.MANIA, 3, "pass"),
|
|
Achievement(
|
|
id=60,
|
|
name="Hyperspeed",
|
|
desc="Woah.",
|
|
assets_id="mania-skill-pass-4",
|
|
): partial(process_skill, GameMode.MANIA, 4, "pass"),
|
|
Achievement(
|
|
id=61,
|
|
name="Ever Onwards",
|
|
desc="Another challenge is just around the corner.",
|
|
assets_id="mania-skill-pass-5",
|
|
): partial(process_skill, GameMode.MANIA, 5, "pass"),
|
|
Achievement(
|
|
id=62,
|
|
name="Another Surpassed",
|
|
desc="Is there no limit to your skills?",
|
|
assets_id="mania-skill-pass-6",
|
|
): partial(process_skill, GameMode.MANIA, 6, "pass"),
|
|
Achievement(
|
|
id=63,
|
|
name="Extra Credit",
|
|
desc="See me after class.",
|
|
assets_id="mania-skill-pass-7",
|
|
): partial(process_skill, GameMode.MANIA, 7, "pass"),
|
|
Achievement(
|
|
id=64,
|
|
name="Maniac",
|
|
desc="There's just no stopping you.",
|
|
assets_id="mania-skill-pass-8",
|
|
): partial(process_skill, GameMode.MANIA, 8, "pass"),
|
|
Achievement(
|
|
id=65,
|
|
name="Keystruck",
|
|
desc="The beginning of a new story",
|
|
assets_id="mania-skill-fc-1",
|
|
): partial(process_skill, GameMode.MANIA, 1, "fc"),
|
|
Achievement(
|
|
id=66,
|
|
name="Keying In",
|
|
desc="Finding your groove.",
|
|
assets_id="mania-skill-fc-2",
|
|
): partial(process_skill, GameMode.MANIA, 2, "fc"),
|
|
Achievement(
|
|
id=67,
|
|
name="Hyperflow",
|
|
desc="You can *feel* the rhythm.",
|
|
assets_id="mania-skill-fc-3",
|
|
): partial(process_skill, GameMode.MANIA, 3, "fc"),
|
|
Achievement(
|
|
id=68,
|
|
name="Breakthrough",
|
|
desc="Many skills mastered, rolled into one.",
|
|
assets_id="mania-skill-fc-4",
|
|
): partial(process_skill, GameMode.MANIA, 4, "fc"),
|
|
Achievement(
|
|
id=69,
|
|
name="Everything Extra",
|
|
desc="Giving your all is giving everything you have.",
|
|
assets_id="mania-skill-fc-5",
|
|
): partial(process_skill, GameMode.MANIA, 5, "fc"),
|
|
Achievement(
|
|
id=70,
|
|
name="Level Breaker",
|
|
desc="Finesse beyond reason",
|
|
assets_id="mania-skill-fc-6",
|
|
): partial(process_skill, GameMode.MANIA, 6, "fc"),
|
|
Achievement(
|
|
id=71,
|
|
name="Step Up",
|
|
desc="A precipice rarely seen.",
|
|
assets_id="mania-skill-fc-7",
|
|
): partial(process_skill, GameMode.MANIA, 7, "fc"),
|
|
Achievement(
|
|
id=72,
|
|
name="Behind The Veil",
|
|
desc="Supernatural!",
|
|
assets_id="mania-skill-fc-8",
|
|
): partial(process_skill, GameMode.MANIA, 8, "fc"),
|
|
}
|