Skip to content

Commit

Permalink
.setCosmetics() method
Browse files Browse the repository at this point in the history
  • Loading branch information
tnfAngel committed Dec 1, 2024
1 parent d557abd commit 9db0277
Show file tree
Hide file tree
Showing 2 changed files with 190 additions and 136 deletions.
7 changes: 7 additions & 0 deletions resources/structs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -994,6 +994,13 @@ export interface Island {
};
}

export interface Cosmetics {
outfit?: { id: string; variants?: CosmeticVariant[]; enlightment?: CosmeticEnlightment };
backpack?: { id: string; variants?: CosmeticVariant[]; path?: string } | null;
pickaxe?: { id: string; variants?: CosmeticVariant[]; path?: string };
shoes?: { id: string; path?: string } | null;
}

export interface CosmeticVariant {
channel: string;
variant: string;
Expand Down
319 changes: 183 additions & 136 deletions src/structures/party/ClientPartyMember.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import PartyMember from './PartyMember';
import { AuthSessionStoreKey } from '../../../resources/enums';
import EpicgamesAPIError from '../../exceptions/EpicgamesAPIError';
import type {
CosmeticEnlightment, CosmeticsVariantMeta, CosmeticVariant, PartyMemberData, PartyMemberSchema, Schema,
CosmeticEnlightment, Cosmetics, CosmeticsVariantMeta, CosmeticVariant, PartyMemberData, PartyMemberSchema, Schema,
} from '../../../resources/structs';
import type Party from './Party';

Expand Down Expand Up @@ -188,64 +188,203 @@ class ClientPartyMember extends PartyMember {
}

/**
* Updates the client party member's outfit
* @param id The outfit's ID
* @param variants The outfit's variants
* @param enlightment The outfit's enlightment
* Updates multiple cosmetics for the client party member.
* If a cosmetic is set to `null`, it will be cleared.
* If a cosmetic is set to `undefined` or not provided, it will remain unchanged.
*
* @param cosmetics An object specifying the cosmetics to update. Can be outfit, backpack, pickaxe or shoes.
* @throws {EpicgamesAPIError}
*/
public async setOutfit(id: string, variants: CosmeticVariant[] = [], enlightment?: CosmeticEnlightment) {
let data = this.meta.get('Default:AthenaCosmeticLoadout_j');
let variantData = this.meta.get('Default:AthenaCosmeticLoadoutVariants_j');

public async setCosmetics({
outfit,
backpack,
pickaxe,
shoes,
}: Cosmetics = {}) {
const patches: Schema = {};

const parsedVariants: CosmeticsVariantMeta = {
athenaCharacter: {
i: variants.map((v) => ({
c: v.channel,
v: v.variant,
dE: v.dE || 0,
})),
},
};
if (outfit !== undefined) {
let data = this.meta.get('Default:AthenaCosmeticLoadout_j');
let variantData = this.meta.get('Default:AthenaCosmeticLoadoutVariants_j');

const parsedVariants: CosmeticsVariantMeta = {
athenaCharacter: {
i: outfit.variants?.map((v) => ({
c: v.channel,
v: v.variant,
dE: v.dE || 0,
})) ?? [],
},
};

const scratchpad = [];
if (outfit.enlightment?.length === 2) {
scratchpad.push({
t: outfit.enlightment[0],
v: outfit.enlightment[1],
});
}

const scratchpad = [];
if (enlightment?.length === 2) {
scratchpad.push({
t: enlightment[0],
v: enlightment[1],
data = this.meta.set('Default:AthenaCosmeticLoadout_j', {
...data,
AthenaCosmeticLoadout: {
...data.AthenaCosmeticLoadout,
characterPrimaryAssetId: `AthenaCharacter:${outfit.id}`,
scratchpad,
},
});

patches['Default:AthenaCosmeticLoadout_j'] = data;

delete variantData.AthenaCosmeticLoadoutVariants.vL.AthenaCharacter;
if (parsedVariants.athenaCharacter?.i[0]) {
variantData = this.meta.set('Default:AthenaCosmeticLoadoutVariants_j', {
AthenaCosmeticLoadoutVariants: {
vL: {
...variantData.AthenaCosmeticLoadoutVariants.vL,
...parsedVariants,
},
},
});

patches['Default:AthenaCosmeticLoadoutVariants_j'] = variantData;
}
}

data = this.meta.set('Default:AthenaCosmeticLoadout_j', {
...data,
AthenaCosmeticLoadout: {
...data.AthenaCosmeticLoadout,
characterPrimaryAssetId: `AthenaCharacter:${id}`,
scratchpad,
},
});
if (backpack !== undefined) {
if (backpack === null) {
let data = this.meta.get('Default:AthenaCosmeticLoadout_j');

patches['Default:AthenaCosmeticLoadout_j'] = data;
data = this.meta.set('Default:AthenaCosmeticLoadout_j', {
...data,
AthenaCosmeticLoadout: {
...data.AthenaCosmeticLoadout,
backpackDef: '',
},
});

patches['Default:AthenaCosmeticLoadout_j'] = data;
} else {
let data = this.meta.get('Default:AthenaCosmeticLoadout_j');
let variantData = this.meta.get('Default:AthenaCosmeticLoadoutVariants_j');

const parsedVariants: CosmeticsVariantMeta = {
athenaBackpack: {
i: backpack.variants?.map((v) => ({
c: v.channel,
v: v.variant,
dE: v.dE || 0,
})) ?? [],
},
};

delete variantData.AthenaCosmeticLoadoutVariants.vL.AthenaCharacter;
if (parsedVariants.athenaCharacter?.i[0]) {
variantData = this.meta.set('Default:AthenaCosmeticLoadoutVariants_j', {
AthenaCosmeticLoadoutVariants: {
vL: {
...variantData.AthenaCosmeticLoadoutVariants.vL,
...parsedVariants,
data = this.meta.set('Default:AthenaCosmeticLoadout_j', {
...data,
AthenaCosmeticLoadout: {
...data.AthenaCosmeticLoadout,
backpackDef: `${backpack.path?.replace(/\/$/, '') ?? '/BRCosmetics/Athena/Items/Cosmetics/Backpacks'}/${backpack.id}.${backpack.id}`,
},
});

patches['Default:AthenaCosmeticLoadout_j'] = data;

delete variantData.AthenaCosmeticLoadoutVariants.vL.AthenaBackpack;
if (parsedVariants.athenaBackpack?.i[0]) {
variantData = this.meta.set('Default:AthenaCosmeticLoadoutVariants_j', {
AthenaCosmeticLoadoutVariants: {
vL: {
...variantData.AthenaCosmeticLoadoutVariants.vL,
...parsedVariants,
},
},
});

patches['Default:AthenaCosmeticLoadoutVariants_j'] = variantData;
}
}
}

if (pickaxe !== undefined) {
let data = this.meta.get('Default:AthenaCosmeticLoadout_j');
let variantData = this.meta.get('Default:AthenaCosmeticLoadoutVariants_j');

const parsedVariants: CosmeticsVariantMeta = {
athenaPickaxe: {
i: pickaxe.variants?.map((v) => ({
c: v.channel,
v: v.variant,
dE: v.dE || 0,
})) ?? [],
},
};

data = this.meta.set('Default:AthenaCosmeticLoadout_j', {
...data,
AthenaCosmeticLoadout: {
...data.AthenaCosmeticLoadout,
pickaxeDef: `${pickaxe.path?.replace(/\/$/, '') ?? '/BRCosmetics/Athena/Items/Cosmetics/Pickaxes'}/${pickaxe.id}.${pickaxe.id}`,
},
});

patches['Default:AthenaCosmeticLoadoutVariants_j'] = variantData;
patches['Default:AthenaCosmeticLoadout_j'] = data;

delete variantData.AthenaCosmeticLoadoutVariants.vL.AthenaPickaxe;
if (parsedVariants.athenaPickaxe?.i[0]) {
variantData = this.meta.set('Default:AthenaCosmeticLoadoutVariants_j', {
AthenaCosmeticLoadoutVariants: {
vL: {
...variantData.AthenaCosmeticLoadoutVariants.vL,
...parsedVariants,
},
},
});

patches['Default:AthenaCosmeticLoadoutVariants_j'] = variantData;
}
}

if (shoes !== undefined) {
if (shoes === null) {
let data = this.meta.get('Default:AthenaCosmeticLoadout_j');

data = this.meta.set('Default:AthenaCosmeticLoadout_j', {
...data,
AthenaCosmeticLoadout: {
...data.AthenaCosmeticLoadout,
shoesDef: '',
},
});

patches['Default:AthenaCosmeticLoadout_j'] = data;
} else {
let data = this.meta.get('Default:AthenaCosmeticLoadout_j');

data = this.meta.set('Default:AthenaCosmeticLoadout_j', {
...data,
AthenaCosmeticLoadout: {
...data.AthenaCosmeticLoadout,
shoesDef: `${shoes.path?.replace(/\/$/, '') ?? '/CosmeticShoes/Assets/Items/Cosmetics'}/${shoes.id}.${shoes.id}`,
},
});

patches['Default:AthenaCosmeticLoadout_j'] = data;
}
}

await this.sendPatch(patches);
}

/**
* Updates the client party member's outfit
* @param id The outfit's ID
* @param variants The outfit's variants
* @param enlightment The outfit's enlightment
* @throws {EpicgamesAPIError}
*/
public async setOutfit(id: string, variants: CosmeticVariant[] = [], enlightment?: CosmeticEnlightment) {
return this.setCosmetics({ outfit: { id, variants, enlightment } });
}

/**
* Updates the client party member's backpack
* @param id The backpack's ID
Expand All @@ -254,46 +393,7 @@ class ClientPartyMember extends PartyMember {
* @throws {EpicgamesAPIError}
*/
public async setBackpack(id: string, variants: CosmeticVariant[] = [], path?: string) {
let data = this.meta.get('Default:AthenaCosmeticLoadout_j');
let variantData = this.meta.get('Default:AthenaCosmeticLoadoutVariants_j');

const patches: Schema = {};

const parsedVariants: CosmeticsVariantMeta = {
athenaBackpack: {
i: variants.map((v) => ({
c: v.channel,
v: v.variant,
dE: v.dE || 0,
})),
},
};

data = this.meta.set('Default:AthenaCosmeticLoadout_j', {
...data,
AthenaCosmeticLoadout: {
...data.AthenaCosmeticLoadout,
backpackDef: `${path?.replace(/\/$/, '') ?? '/BRCosmetics/Athena/Items/Cosmetics/Backpacks'}/${id}.${id}`,
},
});

patches['Default:AthenaCosmeticLoadout_j'] = data;

delete variantData.AthenaCosmeticLoadoutVariants.vL.AthenaBackpack;
if (parsedVariants.athenaBackpack?.i[0]) {
variantData = this.meta.set('Default:AthenaCosmeticLoadoutVariants_j', {
AthenaCosmeticLoadoutVariants: {
vL: {
...variantData.AthenaCosmeticLoadoutVariants.vL,
...parsedVariants,
},
},
});

patches['Default:AthenaCosmeticLoadoutVariants_j'] = variantData;
}

await this.sendPatch(patches);
return this.setCosmetics({ backpack: { id, variants, path } });
}

/**
Expand All @@ -303,7 +403,7 @@ class ClientPartyMember extends PartyMember {
* @param path The pet's path in the game files
*/
public async setPet(id: string, variants: CosmeticVariant[] = [], path?: string) {
return this.setBackpack(id, variants, path ?? '/BRCosmetics/Athena/Items/Cosmetics/PetCarriers');
return this.setCosmetics({ backpack: { id, variants, path: path ?? '/BRCosmetics/Athena/Items/Cosmetics/PetCarriers' } });
}

/**
Expand All @@ -314,46 +414,7 @@ class ClientPartyMember extends PartyMember {
* @throws {EpicgamesAPIError}
*/
public async setPickaxe(id: string, variants: CosmeticVariant[] = [], path?: string) {
let data = this.meta.get('Default:AthenaCosmeticLoadout_j');
let variantData = this.meta.get('Default:AthenaCosmeticLoadoutVariants_j');

const patches: Schema = {};

const parsedVariants: CosmeticsVariantMeta = {
athenaPickaxe: {
i: variants.map((v) => ({
c: v.channel,
v: v.variant,
dE: v.dE || 0,
})),
},
};

data = this.meta.set('Default:AthenaCosmeticLoadout_j', {
...data,
AthenaCosmeticLoadout: {
...data.AthenaCosmeticLoadout,
pickaxeDef: `${path?.replace(/\/$/, '') ?? '/BRCosmetics/Athena/Items/Cosmetics/Pickaxes'}/${id}.${id}`,
},
});

patches['Default:AthenaCosmeticLoadout_j'] = data;

delete variantData.AthenaCosmeticLoadoutVariants.vL.AthenaPickaxe;
if (parsedVariants.athenaPickaxe?.i[0]) {
variantData = this.meta.set('Default:AthenaCosmeticLoadoutVariants_j', {
AthenaCosmeticLoadoutVariants: {
vL: {
...variantData.AthenaCosmeticLoadoutVariants.vL,
...parsedVariants,
},
},
});

patches['Default:AthenaCosmeticLoadoutVariants_j'] = variantData;
}

await this.sendPatch(patches);
return this.setCosmetics({ pickaxe: { id, variants, path } });
}

/**
Expand All @@ -363,21 +424,7 @@ class ClientPartyMember extends PartyMember {
* @throws {EpicgamesAPIError}
*/
public async setShoes(id: string, path?: string) {
let data = this.meta.get('Default:AthenaCosmeticLoadout_j');

data = this.meta.set('Default:AthenaCosmeticLoadout_j', {
...data,
AthenaCosmeticLoadout: {
...data.AthenaCosmeticLoadout,
shoesDef: `${
path?.replace(/\/$/, '') ?? '/CosmeticShoes/Assets/Items/Cosmetics'
}/${id}.${id}`,
},
});

await this.sendPatch({
'Default:AthenaCosmeticLoadout_j': data,
});
return this.setCosmetics({ shoes: { id, path } });
}

/**
Expand Down

0 comments on commit 9db0277

Please sign in to comment.