aboutsummaryrefslogtreecommitdiff
path: root/src/cleaners/skyblock
diff options
context:
space:
mode:
Diffstat (limited to 'src/cleaners/skyblock')
-rw-r--r--src/cleaners/skyblock/member.ts4
-rw-r--r--src/cleaners/skyblock/pets.ts87
-rw-r--r--src/cleaners/skyblock/profile.ts3
-rw-r--r--src/cleaners/skyblock/skills.ts4
4 files changed, 94 insertions, 4 deletions
diff --git a/src/cleaners/skyblock/member.ts b/src/cleaners/skyblock/member.ts
index 364e8b3..161f5cc 100644
--- a/src/cleaners/skyblock/member.ts
+++ b/src/cleaners/skyblock/member.ts
@@ -15,6 +15,7 @@ import * as constants from '../../constants.js'
import { Included } from '../../hypixel.js'
import { CleanPlayer } from '../player.js'
import { CleanRank } from '../rank.js'
+import { cleanPets, Pet, PetsData } from './pets.js'
export interface CleanBasicMember {
uuid: string
@@ -37,6 +38,7 @@ export interface CleanMember extends CleanBasicMember {
zones: Zone[]
collections: Collection[]
slayers: SlayerData
+ pets: PetsData
/** Whether the user left the coop */
left: boolean
}
@@ -87,6 +89,7 @@ export async function cleanSkyBlockProfileMemberResponse(member: typedHypixelApi
zones: await cleanVisitedZones(member),
collections: cleanCollections(member),
slayers: cleanSlayers(member),
+ pets: await cleanPets(member),
left: (player.profiles?.find(profile => profile.uuid === profileId) === undefined) ?? false
}
@@ -109,6 +112,7 @@ export interface CleanMemberProfilePlayer extends CleanPlayer {
zones: Zone[]
collections: Collection[]
slayers: SlayerData
+ pets: PetsData
}
export interface CleanMemberProfile {
diff --git a/src/cleaners/skyblock/pets.ts b/src/cleaners/skyblock/pets.ts
new file mode 100644
index 0000000..d6265e5
--- /dev/null
+++ b/src/cleaners/skyblock/pets.ts
@@ -0,0 +1,87 @@
+import typedHypixelApi from 'typed-hypixel-api'
+import { fetchPets } from '../../constants.js'
+import { levelFromXpTable } from '../../util.js'
+
+// https://hypixel-skyblock.fandom.com/wiki/Module:Pet/LevelingData?action=edit
+
+const PET_LEVELS = [
+ 100, 110, 120, 130, 145, 160, 175, 190, 210, 230, 250, 275, 300, 330, 360, 400, 440, 490, 540, 600, 660, 730, 800, 880, 960, 1050, 1150, 1260, 1380, 1510, 1650, 1800, 1960, 2130, 2310, 2500, 2700, 2920, 3160, 3420, 3700, 4000, 4350, 4750, 5200, 5700, 6300, 7000, 7800, 8700, 9700, 10800, 12000, 13300, 14700, 16200, 17800, 19500, 21300, 23200, 25200, 27400, 29800, 32400, 35200, 38200, 41400, 44800, 48400, 52200, 56200, 60400, 64800, 69400, 74200, 79200, 84700, 90700, 97200, 104200, 111700, 119700, 128200, 137200, 146700, 156700, 167700, 179700, 192700, 206700, 221700, 237700, 254700, 272700, 291700, 311700, 333700, 357700, 383700, 411700, 441700, 476700, 516700, 561700, 611700, 666700, 726700, 791700, 861700, 936700, 1016700, 1101700, 1191700, 1286700, 1386700, 1496700, 1616700, 1746700, 1886700
+]
+
+const PET_RARITY_OFFSET: Record<typedHypixelApi.Pet['tier'], number> = {
+ COMMON: 0,
+ UNCOMMON: 6,
+ RARE: 11,
+ EPIC: 16,
+ LEGENDARY: 20,
+ MYTHIC: 20
+}
+
+function calculateXpTable(rarity: keyof typeof PET_RARITY_OFFSET) {
+ const data = [0]
+ let current = 0
+ for (let i = 0; i < 100; i++) {
+ current += PET_LEVELS[i + PET_RARITY_OFFSET[rarity]]
+ data.push(current)
+ }
+ return data
+}
+
+const RARITY_XP_TABLES = {
+ COMMON: calculateXpTable('COMMON'),
+ UNCOMMON: calculateXpTable('UNCOMMON'),
+ RARE: calculateXpTable('RARE'),
+ EPIC: calculateXpTable('EPIC'),
+ LEGENDARY: calculateXpTable('LEGENDARY'),
+ MYTHIC: calculateXpTable('MYTHIC')
+}
+
+
+export interface Pet {
+ id: string
+ xp: number
+ level: number
+ tier: typedHypixelApi.Pet['tier']
+ skin: string | null
+ item: string | null
+}
+
+export interface PetsData {
+ active: Pet | null
+ list: Pet[]
+ missingIds: string[]
+}
+
+export async function cleanPets(data: typedHypixelApi.SkyBlockProfileMember): Promise<PetsData> {
+ const obtainedPets: Pet[] = []
+ let activePet: Pet | null = null
+
+ const allPetIds = await fetchPets()
+ const obtainedPetIds: string[] = []
+
+ for (const petData of data.pets ?? []) {
+ const xpTable = RARITY_XP_TABLES[petData.tier]
+ const level = levelFromXpTable(petData.exp, xpTable)
+ const pet: Pet = {
+ id: petData.type,
+ // we round down xp because there's no point in showing decimals
+ xp: Math.floor(petData.exp),
+ level,
+ tier: petData.tier,
+ skin: petData.skin ?? null,
+ item: petData.heldItem
+ }
+ obtainedPetIds.push(pet.id)
+ obtainedPets.push(pet)
+ if (petData.active)
+ activePet = pet
+ }
+
+ const missingPetIds = allPetIds.filter(id => !obtainedPetIds.includes(id))
+
+ return {
+ active: activePet,
+ list: obtainedPets,
+ missingIds: missingPetIds
+ }
+} \ No newline at end of file
diff --git a/src/cleaners/skyblock/profile.ts b/src/cleaners/skyblock/profile.ts
index fe9b558..04d848a 100644
--- a/src/cleaners/skyblock/profile.ts
+++ b/src/cleaners/skyblock/profile.ts
@@ -108,8 +108,7 @@ export async function cleanSkyblockProfileResponse<O extends ApiOptions>(
minionCount: uniqueMinions,
maxUniqueMinions: maxUniqueMinions ?? 0,
}
- // we have to do this because of the basic checking typing
- return cleanFullProfile as any
+ return cleanFullProfile
}
/** A basic profile that only includes the profile uuid and name */
diff --git a/src/cleaners/skyblock/skills.ts b/src/cleaners/skyblock/skills.ts
index c69acd0..a186232 100644
--- a/src/cleaners/skyblock/skills.ts
+++ b/src/cleaners/skyblock/skills.ts
@@ -1,4 +1,5 @@
import typedHypixelApi from 'typed-hypixel-api'
+import { levelFromXpTable } from '../../util'
export interface Skill {
name: string
@@ -131,8 +132,7 @@ const skillsDefaultMaxLevel: number = 50
*/
export function levelForSkillXp(xp: number, maxLevel: number) {
const xpTable = (maxLevel <= 25 ? skillXpTableEasier : skillXpTable).slice(0, maxLevel)
- const skillLevel = [...xpTable].reverse().findIndex(levelXp => xp >= levelXp)
- return skillLevel === -1 ? 0 : xpTable.length - skillLevel
+ return levelFromXpTable(xp, xpTable)
}
export async function cleanSkills(data: typedHypixelApi.SkyBlockProfileMember): Promise<Skill[]> {