mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-12-16 14:55:22 +01:00
* Introduce custom ordering of ribbons * Displaying classic ribbon for mons that have at least one classic win --------- Co-authored-by: damocleas <damocleas25@gmail.com>
217 lines
5.7 KiB
TypeScript
217 lines
5.7 KiB
TypeScript
import { pokemonEvolutions } from "#balance/pokemon-evolutions";
|
||
import type { PokemonSpecies } from "#data/pokemon-species";
|
||
import { PokemonType } from "#enums/pokemon-type";
|
||
import { RibbonData, type RibbonFlag } from "#system/ribbons/ribbon-data";
|
||
import { getPokemonSpecies } from "./pokemon-utils";
|
||
|
||
export function getRibbonForType(type: PokemonType): RibbonFlag {
|
||
// Valid types: 0–17, excluding UNKNOWN (-1) and STELLAR (19)
|
||
if (type < PokemonType.NORMAL || type > PokemonType.FAIRY) {
|
||
return 0n;
|
||
}
|
||
return (1n << BigInt(type)) as RibbonFlag;
|
||
}
|
||
|
||
export function getRibbonForGeneration(gen: number): RibbonFlag {
|
||
// Valid generations: 1–9
|
||
if (gen < 1 || gen > 9) {
|
||
return 0n;
|
||
}
|
||
return (1n << BigInt(17 + gen)) as RibbonFlag;
|
||
}
|
||
|
||
export function extractRibbons(data: bigint): RibbonFlag[] {
|
||
const ribbons: RibbonFlag[] = [];
|
||
let bit = 1n;
|
||
|
||
while (bit <= data) {
|
||
if ((data & bit) !== 0n) {
|
||
ribbons.push(bit as RibbonFlag);
|
||
}
|
||
bit <<= 1n; // move to the next bit
|
||
}
|
||
|
||
return ribbons;
|
||
}
|
||
|
||
export function getAvailableRibbons(species: PokemonSpecies): RibbonFlag[] {
|
||
const ribbons: RibbonFlag[] = [
|
||
RibbonData.CLASSIC,
|
||
RibbonData.NUZLOCKE,
|
||
RibbonData.FRIENDSHIP,
|
||
RibbonData.FLIP_STATS,
|
||
RibbonData.INVERSE,
|
||
RibbonData.FRESH_START,
|
||
RibbonData.HARDCORE,
|
||
RibbonData.LIMITED_CATCH,
|
||
RibbonData.NO_HEAL,
|
||
RibbonData.NO_SHOP,
|
||
RibbonData.NO_SUPPORT,
|
||
];
|
||
|
||
let data = 0n;
|
||
|
||
const speciesToCheck = [species.speciesId];
|
||
while (speciesToCheck.length > 0) {
|
||
const checking = speciesToCheck.pop();
|
||
if (checking == null) {
|
||
continue;
|
||
}
|
||
const checkingSpecies = getPokemonSpecies(checking);
|
||
|
||
data |= getRibbonForGeneration(checkingSpecies.generation);
|
||
data |= getRibbonForType(checkingSpecies.type1);
|
||
if (checkingSpecies.type2 != null) {
|
||
data |= getRibbonForType(checkingSpecies.type2);
|
||
}
|
||
|
||
for (const form of checkingSpecies.forms) {
|
||
data |= getRibbonForType(form.type1);
|
||
if (form.type2 != null) {
|
||
data |= getRibbonForType(form.type2);
|
||
}
|
||
}
|
||
|
||
if (checking && pokemonEvolutions.hasOwnProperty(checking)) {
|
||
pokemonEvolutions[checking].forEach(e => {
|
||
speciesToCheck.push(e.speciesId);
|
||
});
|
||
}
|
||
}
|
||
|
||
const extraRibbons = extractRibbons(data);
|
||
|
||
return ribbons.concat(extraRibbons);
|
||
}
|
||
|
||
/**
|
||
* Get the locale key for the given ribbon flag
|
||
* @param flag - The ribbon flag to get the key for
|
||
*/
|
||
export function getRibbonKey(flag: RibbonFlag): string {
|
||
switch (flag) {
|
||
case RibbonData.CLASSIC:
|
||
return "classic";
|
||
case RibbonData.NUZLOCKE:
|
||
return "nuzlocke";
|
||
case RibbonData.FRIENDSHIP:
|
||
return "friendship";
|
||
case RibbonData.FLIP_STATS:
|
||
return "flipStats";
|
||
case RibbonData.INVERSE:
|
||
return "inverse";
|
||
case RibbonData.FRESH_START:
|
||
return "freshStart";
|
||
case RibbonData.HARDCORE:
|
||
return "hardcore";
|
||
case RibbonData.LIMITED_CATCH:
|
||
return "limitedCatch";
|
||
case RibbonData.NO_HEAL:
|
||
return "noHeal";
|
||
case RibbonData.NO_SHOP:
|
||
return "noShop";
|
||
case RibbonData.NO_SUPPORT:
|
||
return "noSupport";
|
||
case RibbonData.MONO_NORMAL:
|
||
return "monoNormal";
|
||
case RibbonData.MONO_FIGHTING:
|
||
return "monoFighting";
|
||
case RibbonData.MONO_FLYING:
|
||
return "monoFlying";
|
||
case RibbonData.MONO_POISON:
|
||
return "monoPoison";
|
||
case RibbonData.MONO_GROUND:
|
||
return "monoGround";
|
||
case RibbonData.MONO_ROCK:
|
||
return "monoRock";
|
||
case RibbonData.MONO_BUG:
|
||
return "monoBug";
|
||
case RibbonData.MONO_GHOST:
|
||
return "monoGhost";
|
||
case RibbonData.MONO_STEEL:
|
||
return "monoSteel";
|
||
case RibbonData.MONO_FIRE:
|
||
return "monoFire";
|
||
case RibbonData.MONO_WATER:
|
||
return "monoWater";
|
||
case RibbonData.MONO_GRASS:
|
||
return "monoGrass";
|
||
case RibbonData.MONO_ELECTRIC:
|
||
return "monoElectric";
|
||
case RibbonData.MONO_PSYCHIC:
|
||
return "monoPsychic";
|
||
case RibbonData.MONO_ICE:
|
||
return "monoIce";
|
||
case RibbonData.MONO_DRAGON:
|
||
return "monoDragon";
|
||
case RibbonData.MONO_DARK:
|
||
return "monoDark";
|
||
case RibbonData.MONO_FAIRY:
|
||
return "monoFairy";
|
||
case RibbonData.MONO_GEN_1:
|
||
return "monoGen1";
|
||
case RibbonData.MONO_GEN_2:
|
||
return "monoGen2";
|
||
case RibbonData.MONO_GEN_3:
|
||
return "monoGen3";
|
||
case RibbonData.MONO_GEN_4:
|
||
return "monoGen4";
|
||
case RibbonData.MONO_GEN_5:
|
||
return "monoGen5";
|
||
case RibbonData.MONO_GEN_6:
|
||
return "monoGen6";
|
||
case RibbonData.MONO_GEN_7:
|
||
return "monoGen7";
|
||
case RibbonData.MONO_GEN_8:
|
||
return "monoGen8";
|
||
case RibbonData.MONO_GEN_9:
|
||
return "monoGen9";
|
||
default:
|
||
return "";
|
||
}
|
||
}
|
||
|
||
/**
|
||
* This list is used to determined the display order of ribbons in the Pokédex.
|
||
*/
|
||
export const orderedRibbons: RibbonFlag[] = [
|
||
RibbonData.CLASSIC,
|
||
RibbonData.FRIENDSHIP,
|
||
RibbonData.FRESH_START,
|
||
RibbonData.HARDCORE,
|
||
RibbonData.LIMITED_CATCH,
|
||
RibbonData.NUZLOCKE,
|
||
RibbonData.NO_HEAL,
|
||
RibbonData.NO_SHOP,
|
||
RibbonData.NO_SUPPORT,
|
||
RibbonData.MONO_GEN_1,
|
||
RibbonData.MONO_GEN_2,
|
||
RibbonData.MONO_GEN_3,
|
||
RibbonData.MONO_GEN_4,
|
||
RibbonData.MONO_GEN_5,
|
||
RibbonData.MONO_GEN_6,
|
||
RibbonData.MONO_GEN_7,
|
||
RibbonData.MONO_GEN_8,
|
||
RibbonData.MONO_GEN_9,
|
||
RibbonData.MONO_NORMAL,
|
||
RibbonData.MONO_FIGHTING,
|
||
RibbonData.MONO_FLYING,
|
||
RibbonData.MONO_POISON,
|
||
RibbonData.MONO_GROUND,
|
||
RibbonData.MONO_ROCK,
|
||
RibbonData.MONO_BUG,
|
||
RibbonData.MONO_GHOST,
|
||
RibbonData.MONO_STEEL,
|
||
RibbonData.MONO_FIRE,
|
||
RibbonData.MONO_WATER,
|
||
RibbonData.MONO_GRASS,
|
||
RibbonData.MONO_ELECTRIC,
|
||
RibbonData.MONO_PSYCHIC,
|
||
RibbonData.MONO_ICE,
|
||
RibbonData.MONO_DRAGON,
|
||
RibbonData.MONO_DARK,
|
||
RibbonData.MONO_FAIRY,
|
||
RibbonData.INVERSE,
|
||
RibbonData.FLIP_STATS,
|
||
];
|