From a22e89b3f2ca8cfc2d3bb14674d0ec6013240db2 Mon Sep 17 00:00:00 2001 From: Avior Date: Thu, 30 Jan 2025 22:25:14 +0100 Subject: [PATCH] tmp Signed-off-by: Avior --- data/Pokémon TCG Pocket/Genetic Apex.ts | 56 +++++++++++++++++++++ data/Pokémon TCG Pocket/Genetic Apex/001.ts | 4 ++ data/Pokémon TCG Pocket/Mythical Island.ts | 41 +++++++++++++++ interfaces.d.ts | 21 ++++++++ meta/definitions/api.d.ts | 25 +++++++++ server/compiler/utils/cardUtil.ts | 35 +++++++++++++ server/compiler/utils/setUtil.ts | 4 +- 7 files changed, 185 insertions(+), 1 deletion(-) diff --git a/data/Pokémon TCG Pocket/Genetic Apex.ts b/data/Pokémon TCG Pocket/Genetic Apex.ts index a147f5551..b5779addc 100644 --- a/data/Pokémon TCG Pocket/Genetic Apex.ts +++ b/data/Pokémon TCG Pocket/Genetic Apex.ts @@ -19,6 +19,62 @@ const set: Set = { official: 226 }, + boosters: { + charizard: { + en: 'Charizard', + fr: 'Dracaufeu' + }, + mewtwo: { + en: 'Mewtwo', + fr: 'Mewtwo' + }, + pikachu: { + en: 'Pikachu', + fr: 'Pikachu' + } + }, + + // data fetched from the Pokemon TCG Pocket app + pullRates: { + 'normal': { + rate: 99.95, + slots: [ + { 'One Diamond': 100 }, + { 'One Diamond': 100 }, + { 'One Diamond': 100 }, + { + 'Crown': 0.04, + 'Three Star': 0.222, + 'Two Star': 0.5, + 'One Star': 2.572, + 'Four Diamond': 1.666, + 'Three Diamond': 5, + 'Two Diamond': 90 + }, + { + 'Crown': 0.16, + 'Three Star': 0.888, + 'Two Star': 2, + 'One Star': 10.288, + 'Four Diamond': 6.664, + 'Three Diamond': 20, + 'Two Diamond': 60 + } + ] + }, + godpack: { + rate: 0.05, + slots: [ + { + 'Crown': 5, + 'Three Star': 5, + 'Two Star': 50, + 'One Star': 40 + } + ] + } + }, + releaseDate: "2024-10-30" } diff --git a/data/Pokémon TCG Pocket/Genetic Apex/001.ts b/data/Pokémon TCG Pocket/Genetic Apex/001.ts index 80afa2fb8..1abb8230e 100644 --- a/data/Pokémon TCG Pocket/Genetic Apex/001.ts +++ b/data/Pokémon TCG Pocket/Genetic Apex/001.ts @@ -8,6 +8,10 @@ const card: Card = { en: "Bulbasaur" }, + boosters: [ + 'mewtwo' + ], + illustrator: "Narumi Sato", category: "Pokemon", hp: 70, diff --git a/data/Pokémon TCG Pocket/Mythical Island.ts b/data/Pokémon TCG Pocket/Mythical Island.ts index 11d472b73..4bf5c54e8 100644 --- a/data/Pokémon TCG Pocket/Mythical Island.ts +++ b/data/Pokémon TCG Pocket/Mythical Island.ts @@ -19,6 +19,47 @@ const set: Set = { official: 68 }, + // data fetched from the Pokemon TCG Pocket app + pullRates: { + 'normal': { + rate: 99.95, + slots: [ + { 'One Diamond': 100 }, + { 'One Diamond': 100 }, + { 'One Diamond': 100 }, + { + 'Crown': 0.04, + 'Three Star': 0.222, + 'Two Star': 0.5, + 'One Star': 2.572, + 'Four Diamond': 1.666, + 'Three Diamond': 5, + 'Two Diamond': 90 + }, + { + 'Crown': 0.16, + 'Three Star': 0.888, + 'Two Star': 2, + 'One Star': 10.288, + 'Four Diamond': 6.664, + 'Three Diamond': 20, + 'Two Diamond': 60 + } + ] + }, + godpack: { + rate: 0.05, + slots: [ + { + 'Crown': 5, + 'Three Star': 5, + 'Two Star': 50, + 'One Star': 40 + } + ] + } + }, + releaseDate: "2024-12-17" } diff --git a/interfaces.d.ts b/interfaces.d.ts index 7a5f8c8be..82412dd4d 100644 --- a/interfaces.d.ts +++ b/interfaces.d.ts @@ -74,9 +74,25 @@ export interface Set { official: number } + /** + * the names of the booster packs the set has + */ + boosters?: Record + + /** + * list of pull rates by slot (from frontmost card to backmost card) + */ + pullRates?: Partial> + + releaseDate: ISODate | Languages } +interface Pull { + slots: Array>> + rate: number +} + export interface Card { /** * Card Name (Including the suffix if next to card name) @@ -88,6 +104,11 @@ export interface Card { */ illustrator?: string + /** + * indicate in which booster pack the card can be pulled + */ + boosters?: Array + /** * Card Rarity * diff --git a/meta/definitions/api.d.ts b/meta/definitions/api.d.ts index 33ef55d73..29b977fa9 100644 --- a/meta/definitions/api.d.ts +++ b/meta/definitions/api.d.ts @@ -95,6 +95,11 @@ export interface Set extends SetResume { */ firstEd?: number; }; + boosters?: Array + pullRates?: Partial>> + rate: number + }>> cards: Array; abbreviation: { official: string, localized: string }; } @@ -113,6 +118,26 @@ export interface CardResume { * /sets/:set/:localId */ export interface Card extends CardResume { + /** + * indicate in which booster the card is openable from + * + * note1: if boosters is empty (`length == 0`) the card is unobtainable from boosters (ex: `A1` Mew that is obtainable from an hidden mission) + * + * note2: if boosters is not set, the card is available in every boosters + */ + boosters?: Array + + pullRates?: Record + /** + * rate including the base rate + */ + total_slots: Array + }> /** * Card illustrator */ diff --git a/server/compiler/utils/cardUtil.ts b/server/compiler/utils/cardUtil.ts index 9e953336e..acfe10237 100644 --- a/server/compiler/utils/cardUtil.ts +++ b/server/compiler/utils/cardUtil.ts @@ -5,6 +5,7 @@ import { CardResume, Card as CardSingle } from '../../../meta/definitions/api' import { getSet, setToSetSimple } from './setUtil' import translate from './translationUtil' import { DB_PATH, cardIsLegal, fetchRemoteFile, getDataFolder, getLastEdit, smartGlob } from './util' +import { objectRemap, objectSize } from '@dzeio/object-util' export async function getCardPictures(cardId: string, card: Card, lang: SupportedLanguages): Promise { try { @@ -41,6 +42,21 @@ export async function cardToCardSingle(localId: string, card: Card, lang: Suppor throw new Error(`Card (${localId}) dont exist in (${lang})`) } + const set = card.set + + const pullRates: CardSingle['pullRates'] = {} + + if (set.pullRates) { + for (const type of Object.keys(set.pullRates)) { + const value = set.pullRates[type] + pullRates[type] = { + rate: value.rate, + slots: await Promise.all(value.slots.map(async (it) => it[card.rarity] ? await getPullRate(set, card, it[card.rarity], lang) : 0)), + total_slots: await Promise.all(value.slots.map(async (it) => it[card.rarity] ? await getPullRate(set, card, it[card.rarity] * (value.rate / 100), lang) : 0)), + } + } + } + return { category: translate('category', card.category, lang) as any, id: `${card.set.id}-${localId}`, @@ -59,6 +75,8 @@ export async function cardToCardSingle(localId: string, card: Card, lang: Suppor wPromo: typeof card.variants?.wPromo === 'boolean' ? card.variants.wPromo : false }, + boosters: card.boosters, + pullRates: objectSize(pullRates) > 0 ? pullRates : undefined, dexId: card.dexId, hp: card.hp, @@ -126,6 +144,23 @@ export async function getCard(set: Set, id: string, lang: SupportedLanguages): P } } +function arrayIntersect(first: Array, second: Array) { + return !!first.find((it) => second.includes(it)) +} + +async function getPullRate(set: Set, card: Card, totalRate: number, lang: SupportedLanguages) { + const otherCards = await getCards(lang, set) + .then((cards) => cards + .map((it) => it[1]) + // filter cards with same rarity + // exclude cards that is only avialable in other boosters + .filter((it) => it.rarity === card.rarity && (!it.boosters || !card.boosters || arrayIntersect(card.boosters, it.boosters))) + ) + const count = otherCards.length // remove one to exclude current card as it ill match itself + + return 1 * (totalRate / 100) / count * 100 +} + /** * Get cards filtered by the language they are available in * @param lang the language of the cards diff --git a/server/compiler/utils/setUtil.ts b/server/compiler/utils/setUtil.ts index 667d878c7..3aa8db69d 100644 --- a/server/compiler/utils/setUtil.ts +++ b/server/compiler/utils/setUtil.ts @@ -1,4 +1,4 @@ -import { objectKeys } from '@dzeio/object-util' +import { objectKeys, objectMap } from '@dzeio/object-util' import { Set, SupportedLanguages } from '../../../interfaces' import { SetResume, Set as SetSingle } from '../../../meta/definitions/api' import { cardToCardSimple, getCards } from './cardUtil' @@ -101,6 +101,8 @@ export async function setToSetSingle(set: Set, lang: SupportedLanguages): Promis id: set.serie.id, name: set.serie.name[lang] as string }, + boosters: set.boosters ? objectMap(set.boosters, (v, k) => v[lang]) : undefined, + pullRates: set.pullRates, symbol: pics[1], tcgOnline: set.tcgOnline, abbreviation: (set.abbreviations?.official || set.abbreviations?.[lang]) ? {