WIP(shops): cShop reconciled to schedule backend

This commit is contained in:
Sabe Jones
2024-04-19 20:11:17 -05:00
parent 5f64b2fb25
commit 28b936e2d1
9 changed files with 190 additions and 202 deletions

View File

@@ -911,7 +911,7 @@ export default {
if (['base', 'beard', 'color', 'mustache'].includes(item.type)) { if (['base', 'beard', 'color', 'mustache'].includes(item.type)) {
return { return {
hair: { hair: {
[item.type]: item.option, [item.type]: item.key,
}, },
head: 'head_base_0', head: 'head_base_0',
}; };

View File

@@ -64,7 +64,7 @@
> >
<shop-item <shop-item
:item="ctx.item" :item="ctx.item"
:key="ctx.item.key" :key="ctx.item.path"
:price="ctx.item.value" :price="ctx.item.value"
:price-type="ctx.item.currency" :price-type="ctx.item.currency"
:empty-item="false" :empty-item="false"
@@ -197,7 +197,7 @@ export default {
this.$store.state.avatarEditorOptions.startingPage = 'extra'; this.$store.state.avatarEditorOptions.startingPage = 'extra';
this.$store.state.avatarEditorOptions.subpage = 'tails'; this.$store.state.avatarEditorOptions.subpage = 'tails';
break; break;
case 'background': case 'backgrounds':
this.$store.state.avatarEditorOptions.startingPage = 'background'; this.$store.state.avatarEditorOptions.startingPage = 'background';
this.$store.state.avatarEditorOptions.subpage = '2024'; this.$store.state.avatarEditorOptions.subpage = '2024';
break; break;
@@ -205,19 +205,19 @@ export default {
this.$store.state.avatarEditorOptions.startingPage = 'hair'; this.$store.state.avatarEditorOptions.startingPage = 'hair';
this.$store.state.avatarEditorOptions.subpage = 'beard'; this.$store.state.avatarEditorOptions.subpage = 'beard';
break; break;
case 'hairColors': case 'color':
this.$store.state.avatarEditorOptions.startingPage = 'hair'; this.$store.state.avatarEditorOptions.startingPage = 'hair';
this.$store.state.avatarEditorOptions.subpage = 'color'; this.$store.state.avatarEditorOptions.subpage = 'color';
break; break;
case 'hairStyles': case 'base':
this.$store.state.avatarEditorOptions.startingPage = 'hair'; this.$store.state.avatarEditorOptions.startingPage = 'hair';
this.$store.state.avatarEditorOptions.subpage = 'style'; this.$store.state.avatarEditorOptions.subpage = 'style';
break; break;
case 'shirts': case 'shirt':
this.$store.state.avatarEditorOptions.startingPage = 'body'; this.$store.state.avatarEditorOptions.startingPage = 'body';
this.$store.state.avatarEditorOptions.subpage = 'shirt'; this.$store.state.avatarEditorOptions.subpage = 'shirt';
break; break;
case 'skins': case 'skin':
this.$store.state.avatarEditorOptions.startingPage = 'skin'; this.$store.state.avatarEditorOptions.startingPage = 'skin';
this.$store.state.avatarEditorOptions.subpage = 'color'; this.$store.state.avatarEditorOptions.subpage = 'color';
break; break;
@@ -233,17 +233,17 @@ export default {
return $t('allCustomizationsOwned'); return $t('allCustomizationsOwned');
case 'animalTails': case 'animalTails':
return $t('allCustomizationsOwned'); return $t('allCustomizationsOwned');
case 'background': case 'backgrounds':
return `${$t('allCustomizationsOwned')} ${$t('checkNextMonth')}`; return `${$t('allCustomizationsOwned')} ${$t('checkNextMonth')}`;
case 'facialHair': case 'facialHair':
return $t('allCustomizationsOwned'); return $t('allCustomizationsOwned');
case 'hairColors': case 'color':
return `${$t('allCustomizationsOwned')} ${$t('checkNextSeason')}`; return `${$t('allCustomizationsOwned')} ${$t('checkNextSeason')}`;
case 'hairStyles': case 'base':
return $t('allCustomizationsOwned'); return $t('allCustomizationsOwned');
case 'shirts': case 'shirt':
return $t('allCustomizationsOwned'); return $t('allCustomizationsOwned');
case 'skins': case 'skin':
return `${$t('allCustomizationsOwned')} ${$t('checkNextSeason')}`; return `${$t('allCustomizationsOwned')} ${$t('checkNextSeason')}`;
default: default:
return `Unknown identifier ${identifier}`; return `Unknown identifier ${identifier}`;

View File

@@ -24,6 +24,7 @@
"shirt": "Shirt", "shirt": "Shirt",
"specialShirts": "Special Shirts", "specialShirts": "Special Shirts",
"skin": "Skin", "skin": "Skin",
"skins": "Skins",
"color": "Color", "color": "Color",
"hair": "Hair", "hair": "Hair",
"bangs": "Bangs", "bangs": "Bangs",
@@ -31,12 +32,11 @@
"hairSet1": "Hairstyle Set 1", "hairSet1": "Hairstyle Set 1",
"hairSet2": "Hairstyle Set 2", "hairSet2": "Hairstyle Set 2",
"hairSet3": "Hairstyle Set 3", "hairSet3": "Hairstyle Set 3",
"bodyFacialHair": "Facial Hair",
"beard": "Beard", "beard": "Beard",
"mustache": "Mustache", "mustache": "Mustache",
"titleFacialHair": "Facial Hair", "titleFacialHair": "Facial Hair",
"titleHaircolor": "Hair Colors", "titleHaircolor": "Hair Colors",
"titleHairbase": "Hair styles", "titleHairbase": "Hair Styles",
"flower": "Flower", "flower": "Flower",
"accent": "Accent", "accent": "Accent",
"headband": "Headband", "headband": "Headband",
@@ -191,9 +191,5 @@
"offHand": "Off-Hand", "offHand": "Off-Hand",
"statPoints": "Stat Points", "statPoints": "Stat Points",
"pts": "pts", "pts": "pts",
"customizations": "Customizations", "customizations": "Customizations"
"hairColors": "Hair Colors",
"hairStyles": "Hair Styles",
"skins": "Skins",
"facialHairs": "Facial Hair"
} }

View File

@@ -5,7 +5,7 @@ export default prefill({
baseHair1: { setPrice: 5, text: t('hairSet1') }, baseHair1: { setPrice: 5, text: t('hairSet1') },
baseHair2: { setPrice: 5, text: t('hairSet2') }, baseHair2: { setPrice: 5, text: t('hairSet2') },
baseHair3: { setPrice: 5, text: t('hairSet3') }, baseHair3: { setPrice: 5, text: t('hairSet3') },
facialHair: { setPrice: 5, text: t('bodyFacialHair') }, facialHair: { setPrice: 5, text: t('titleFacialHair') },
specialShirts: { setPrice: 5, text: t('specialShirts') }, specialShirts: { setPrice: 5, text: t('specialShirts') },
winterHairColors: { setPrice: 5 }, winterHairColors: { setPrice: 5 },
pastelHairColors: { setPrice: 5 }, pastelHairColors: { setPrice: 5 },

View File

@@ -745,6 +745,19 @@ export const GALA_SCHEDULE = {
}, },
}; };
export const TYPE_SCHEDULE = {
timeTravelers: FIRST_RELEASE_DAY,
backgrounds: SECOND_RELEASE_DAY,
petQuests: THIRD_RELEASE_DAY,
hatchingPotionQuests: THIRD_RELEASE_DAY,
bundles: THIRD_RELEASE_DAY,
premiumHatchingPotions: FOURTH_RELEASE_DAY,
seasonalGear: GALA_SWITCHOVER_DAY,
seasonalSpells: GALA_SWITCHOVER_DAY,
seasonalQuests: GALA_SWITCHOVER_DAY,
customizations: GALA_SWITCHOVER_DAY,
};
function getDay (date) { function getDay (date) {
if (date === undefined) { if (date === undefined) {
return 0; return 0;
@@ -804,6 +817,7 @@ let cacheDate = null;
function makeMatcherClass () { function makeMatcherClass () {
return { return {
matchers: [], matchers: [],
end: new Date(),
items: [], items: [],
match (key) { match (key) {
if (this.matchers.length === 0) { if (this.matchers.length === 0) {
@@ -818,9 +832,6 @@ function makeMatcherClass () {
} }
return false; return false;
}, },
getEndDate () {
return new Date();
},
}; };
} }
@@ -846,7 +857,12 @@ export function getScheduleMatchingGroup (type, date) {
}); });
} }
if (!cachedScheduleMatchers[type]) { if (!cachedScheduleMatchers[type]) {
let end = moment(checkedDate).date(TYPE_SCHEDULE[type]);
if (end.date() <= checkedDate.date()) {
end = moment(end).add(1, 'months');
}
return { return {
end: end.toDate(),
items: [], items: [],
match () { match () {
return true; return true;

View File

@@ -773,6 +773,7 @@ const back = {
text: t('backBearTailText'), text: t('backBearTailText'),
notes: t('backBearTailNotes'), notes: t('backBearTailNotes'),
value: 20, value: 20,
canBuy: () => true,
canOwn: ownsItem('back_special_bearTail'), canOwn: ownsItem('back_special_bearTail'),
}, },
cactusTail: { cactusTail: {
@@ -780,6 +781,7 @@ const back = {
text: t('backCactusTailText'), text: t('backCactusTailText'),
notes: t('backCactusTailNotes'), notes: t('backCactusTailNotes'),
value: 20, value: 20,
canBuy: () => true,
canOwn: ownsItem('back_special_cactusTail'), canOwn: ownsItem('back_special_cactusTail'),
}, },
foxTail: { foxTail: {
@@ -787,6 +789,7 @@ const back = {
text: t('backFoxTailText'), text: t('backFoxTailText'),
notes: t('backFoxTailNotes'), notes: t('backFoxTailNotes'),
value: 20, value: 20,
canBuy: () => true,
canOwn: ownsItem('back_special_foxTail'), canOwn: ownsItem('back_special_foxTail'),
}, },
lionTail: { lionTail: {
@@ -794,6 +797,7 @@ const back = {
text: t('backLionTailText'), text: t('backLionTailText'),
notes: t('backLionTailNotes'), notes: t('backLionTailNotes'),
value: 20, value: 20,
canBuy: () => true,
canOwn: ownsItem('back_special_lionTail'), canOwn: ownsItem('back_special_lionTail'),
}, },
pandaTail: { pandaTail: {
@@ -801,6 +805,7 @@ const back = {
text: t('backPandaTailText'), text: t('backPandaTailText'),
notes: t('backPandaTailNotes'), notes: t('backPandaTailNotes'),
value: 20, value: 20,
canBuy: () => true,
canOwn: ownsItem('back_special_pandaTail'), canOwn: ownsItem('back_special_pandaTail'),
}, },
pigTail: { pigTail: {
@@ -808,6 +813,7 @@ const back = {
text: t('backPigTailText'), text: t('backPigTailText'),
notes: t('backPigTailNotes'), notes: t('backPigTailNotes'),
value: 20, value: 20,
canBuy: () => true,
canOwn: ownsItem('back_special_pigTail'), canOwn: ownsItem('back_special_pigTail'),
}, },
tigerTail: { tigerTail: {
@@ -815,6 +821,7 @@ const back = {
text: t('backTigerTailText'), text: t('backTigerTailText'),
notes: t('backTigerTailNotes'), notes: t('backTigerTailNotes'),
value: 20, value: 20,
canBuy: () => true,
canOwn: ownsItem('back_special_tigerTail'), canOwn: ownsItem('back_special_tigerTail'),
}, },
wolfTail: { wolfTail: {
@@ -822,6 +829,7 @@ const back = {
text: t('backWolfTailText'), text: t('backWolfTailText'),
notes: t('backWolfTailNotes'), notes: t('backWolfTailNotes'),
value: 20, value: 20,
canBuy: () => true,
canOwn: ownsItem('back_special_wolfTail'), canOwn: ownsItem('back_special_wolfTail'),
}, },
turkeyTailGilded: { turkeyTailGilded: {
@@ -1868,6 +1876,7 @@ const headAccessory = {
text: t('headAccessoryBearEarsText'), text: t('headAccessoryBearEarsText'),
notes: t('headAccessoryBearEarsNotes'), notes: t('headAccessoryBearEarsNotes'),
value: 20, value: 20,
canBuy: () => true,
canOwn: ownsItem('headAccessory_special_bearEars'), canOwn: ownsItem('headAccessory_special_bearEars'),
}, },
cactusEars: { cactusEars: {
@@ -1875,6 +1884,7 @@ const headAccessory = {
text: t('headAccessoryCactusEarsText'), text: t('headAccessoryCactusEarsText'),
notes: t('headAccessoryCactusEarsNotes'), notes: t('headAccessoryCactusEarsNotes'),
value: 20, value: 20,
canBuy: () => true,
canOwn: ownsItem('headAccessory_special_cactusEars'), canOwn: ownsItem('headAccessory_special_cactusEars'),
}, },
foxEars: { foxEars: {
@@ -1882,6 +1892,7 @@ const headAccessory = {
text: t('headAccessoryFoxEarsText'), text: t('headAccessoryFoxEarsText'),
notes: t('headAccessoryFoxEarsNotes'), notes: t('headAccessoryFoxEarsNotes'),
value: 20, value: 20,
canBuy: () => true,
canOwn: ownsItem('headAccessory_special_foxEars'), canOwn: ownsItem('headAccessory_special_foxEars'),
}, },
lionEars: { lionEars: {
@@ -1889,6 +1900,7 @@ const headAccessory = {
text: t('headAccessoryLionEarsText'), text: t('headAccessoryLionEarsText'),
notes: t('headAccessoryLionEarsNotes'), notes: t('headAccessoryLionEarsNotes'),
value: 20, value: 20,
canBuy: () => true,
canOwn: ownsItem('headAccessory_special_lionEars'), canOwn: ownsItem('headAccessory_special_lionEars'),
}, },
pandaEars: { pandaEars: {
@@ -1896,6 +1908,7 @@ const headAccessory = {
text: t('headAccessoryPandaEarsText'), text: t('headAccessoryPandaEarsText'),
notes: t('headAccessoryPandaEarsNotes'), notes: t('headAccessoryPandaEarsNotes'),
value: 20, value: 20,
canBuy: () => true,
canOwn: ownsItem('headAccessory_special_pandaEars'), canOwn: ownsItem('headAccessory_special_pandaEars'),
}, },
pigEars: { pigEars: {
@@ -1903,6 +1916,7 @@ const headAccessory = {
text: t('headAccessoryPigEarsText'), text: t('headAccessoryPigEarsText'),
notes: t('headAccessoryPigEarsNotes'), notes: t('headAccessoryPigEarsNotes'),
value: 20, value: 20,
canBuy: () => true,
canOwn: ownsItem('headAccessory_special_pigEars'), canOwn: ownsItem('headAccessory_special_pigEars'),
}, },
tigerEars: { tigerEars: {
@@ -1910,6 +1924,7 @@ const headAccessory = {
text: t('headAccessoryTigerEarsText'), text: t('headAccessoryTigerEarsText'),
notes: t('headAccessoryTigerEarsNotes'), notes: t('headAccessoryTigerEarsNotes'),
value: 20, value: 20,
canBuy: () => true,
canOwn: ownsItem('headAccessory_special_tigerEars'), canOwn: ownsItem('headAccessory_special_tigerEars'),
}, },
wolfEars: { wolfEars: {
@@ -1917,6 +1932,7 @@ const headAccessory = {
text: t('headAccessoryWolfEarsText'), text: t('headAccessoryWolfEarsText'),
notes: t('headAccessoryWolfEarsNotes'), notes: t('headAccessoryWolfEarsNotes'),
value: 20, value: 20,
canBuy: () => true,
canOwn: ownsItem('headAccessory_special_wolfEars'), canOwn: ownsItem('headAccessory_special_wolfEars'),
}, },
spring2016Rogue: { spring2016Rogue: {

View File

@@ -56,7 +56,7 @@ function getDefaultGearProps (item, language) {
}; };
} }
export default function getItemInfo (user, type, item, officialPinnedItems, language = 'en') { export default function getItemInfo (user, type, item, officialPinnedItems, language = 'en', matcher = null) {
if (officialPinnedItems === undefined) { if (officialPinnedItems === undefined) {
officialPinnedItems = getOfficialPinnedItems(user); // eslint-disable-line no-param-reassign officialPinnedItems = getOfficialPinnedItems(user); // eslint-disable-line no-param-reassign
} }
@@ -235,7 +235,7 @@ export default function getItemInfo (user, type, item, officialPinnedItems, lang
case 'gear': case 'gear':
// spread operator not available // spread operator not available
itemInfo = Object.assign(getDefaultGearProps(item, language), { itemInfo = Object.assign(getDefaultGearProps(item, language), {
value: item.twoHanded || item.gearSet === 'animal' ? 2 : 1, value: item.twoHanded ? 2 : 1,
currency: 'gems', currency: 'gems',
pinType: 'gear', pinType: 'gear',
}); });
@@ -379,71 +379,70 @@ export default function getItemInfo (user, type, item, officialPinnedItems, lang
}; };
break; break;
} }
case 'hairColor': { case 'haircolor': {
itemInfo = { itemInfo = {
key: item.key, key: item.key,
class: `hair hair_bangs_${user.preferences.hair.bangs}_${item.key}`, class: `hair hair_bangs_${user.preferences.hair.bangs}_${item.key}`,
currency: 'gems', currency: 'gems',
option: item.key, locked: false,
notes: '',
path: `hair.color.${item.key}`, path: `hair.color.${item.key}`,
purchaseType: 'customization', purchaseType: 'customization',
pinType: 'timeTravelersStable',
set: item.set,
text: item.text(language), text: item.text(language),
type: 'color', type: 'color',
value: item.price, value: item.price,
}; };
break; break;
} }
case 'hairBase': { case 'hairbase': {
itemInfo = { itemInfo = {
key: `hair-base-${item.key}`, key: item.key,
class: `hair hair_base_${item.key}_${user.preferences.hair.color}`, class: `hair hair_base_${item.key}_${user.preferences.hair.color}`,
currency: 'gems', currency: 'gems',
option: item.key, locked: false,
notes: '',
path: `hair.base.${item.key}`, path: `hair.base.${item.key}`,
pinType: 'timeTravelersStable',
purchaseType: 'customization', purchaseType: 'customization',
set: item.set,
text: item.text(language), text: item.text(language),
type: 'base', type: 'base',
value: item.price, value: item.price,
}; };
break; break;
} }
case 'mustache': { case 'hairmustache': {
itemInfo = { itemInfo = {
key: `mustache-${item.key}`, key: item.key,
class: `facial-hair hair_mustache_${item.key}_${user.preferences.hair.color}`, class: `hair hair_mustache_${item.key}_${user.preferences.hair.color}`,
currency: 'gems', currency: 'gems',
option: item.key, locked: false,
notes: '',
path: `hair.mustache.${item.key}`, path: `hair.mustache.${item.key}`,
pinType: 'timeTravelersStable',
purchaseType: 'customization', purchaseType: 'customization',
set: item.set,
text: item.text(language), text: item.text(language),
type: 'mustache', type: 'mustache',
value: item.price, value: item.price,
}; };
break; break;
} }
case 'beard': { case 'hairbeard': {
itemInfo = {
key: `beard-${item.key}`,
class: `facial-hair hair_beard_${item.key}_${user.preferences.hair.color}`,
currency: 'gems',
option: item.key,
path: `hair.beard.${item.key}`,
purchaseType: 'customization',
text: item.text(language),
type: 'beard',
value: item.price,
};
break;
}
case 'skin': {
itemInfo = { itemInfo = {
key: item.key, key: item.key,
class: `skin skin_${item.key}`, class: `hair hair_beard_${item.key}_${user.preferences.hair.color}`,
currency: 'gems', currency: 'gems',
path: `skin.${item.key}`, locked: false,
notes: '',
path: `hair.beard.${item.key}`,
pinType: 'timeTravelersStable',
purchaseType: 'customization', purchaseType: 'customization',
set: item.set,
text: item.text(language), text: item.text(language),
type: 'skin', type: 'beard',
value: item.price, value: item.price,
}; };
break; break;
@@ -453,14 +452,35 @@ export default function getItemInfo (user, type, item, officialPinnedItems, lang
key: item.key, key: item.key,
class: `shirt ${user.preferences.size}_shirt_${item.key}`, class: `shirt ${user.preferences.size}_shirt_${item.key}`,
currency: 'gems', currency: 'gems',
locked: false,
notes: '',
path: `shirt.${item.key}`, path: `shirt.${item.key}`,
pinType: 'timeTravelersStable',
purchaseType: 'customization', purchaseType: 'customization',
set: item.set,
text: item.text(language), text: item.text(language),
type: 'shirt', type: 'shirt',
value: item.price, value: item.price,
}; };
break; break;
} }
case 'skin': {
itemInfo = {
key: item.key,
class: `skin skin_${item.key}`,
currency: 'gems',
locked: false,
path: `skin.${item.key}`,
notes: '',
pinType: 'timeTravelersStable',
purchaseType: 'customization',
set: item.set,
text: item.text(language),
type: 'skin',
value: item.price,
};
break;
}
} }
if (itemInfo) { if (itemInfo) {
@@ -470,5 +490,9 @@ export default function getItemInfo (user, type, item, officialPinnedItems, lang
throw new BadRequest(i18n.t('wrongItemType', { type }, language)); throw new BadRequest(i18n.t('wrongItemType', { type }, language));
} }
if (matcher) {
itemInfo.end = { matcher };
}
return itemInfo; return itemInfo;
} }

View File

@@ -549,135 +549,105 @@ shops.getBackgroundShopSets = function getBackgroundShopSets (language) {
return sets; return sets;
}; };
/* Customization Shop */
shops.getCustomizationsShop = function getCustomizationsShop (user, language) {
return {
identifier: 'customizationsShop',
text: i18n.t('titleCustomizations'),
notes: i18n.t('timeTravelersPopover'),
imageName: 'npc_timetravelers_active',
categories: shops.getCustomizationsShopCategories(user, language),
};
};
shops.getCustomizationsShopCategories = function getCustomizationsShopCategories (user, language) { shops.getCustomizationsShopCategories = function getCustomizationsShopCategories (user, language) {
const categories = []; const categories = [];
const officialPinnedItems = getOfficialPinnedItems(); const officialPinnedItems = getOfficialPinnedItems(user);
const backgroundsCategory = { const backgroundCategory = {
identifier: 'background', identifier: 'backgrounds',
text: i18n.t('backgrounds', language), text: i18n.t('backgrounds', language),
items: [],
}; };
backgroundsCategory.items = values(content.backgroundsFlat)
.filter(bg => !user.purchased.background[bg.key] && (!bg.currency || bg.currency === 'gems')
&& !(bg.price === 0))
.map(bg => getItemInfo(user, 'background', bg, officialPinnedItems, language));
categories.push(backgroundsCategory);
const hairColorsCategory = { const matchers = getScheduleMatchingGroup('backgrounds');
identifier: 'hairColors', eachRight(content.backgrounds, (group, key) => {
text: i18n.t('hairColors', language), if (matchers.match(key)) {
}; each(group, bg => {
hairColorsCategory.items = values(content.appearances.hair.color) if (!user.purchased.background[bg.key]) {
.filter(color => { const item = getItemInfo(
const { hair } = user.purchased; user,
if (hair && hair.color && hair.color[color.key]) { 'background',
return false; bg,
officialPinnedItems,
language,
);
backgroundCategory.items.push(item);
} }
if (color.set) { });
if (color.set.availableFrom) {
return moment().isBetween(color.set.availableFrom, color.set.availableUntil);
} }
if (color.set.availableUntil) { });
return moment().isBefore(color.set.availableUntil); categories.push(backgroundCategory);
}
return true;
}
return false;
})
.map(color => getItemInfo(user, 'hairColor', color, officialPinnedItems, language));
categories.push(hairColorsCategory);
const hairStylesCategory = {
identifier: 'hairStyles',
text: i18n.t('hairStyles', language),
};
hairStylesCategory.items = values(content.appearances.hair.base)
.filter(style => {
const { hair } = user.purchased;
if (hair && hair.base && hair.base[style.key]) {
return false;
}
if (style.set) {
if (style.set.availableFrom) {
return moment().isBetween(style.set.availableFrom, style.set.availableUntil);
}
if (style.set.availableUntil) {
return moment().isBefore(style.set.availableUntil);
}
return true;
}
return false;
})
.map(style => getItemInfo(user, 'hairBase', style, officialPinnedItems, language));
categories.push(hairStylesCategory);
const facialHairCategory = { const facialHairCategory = {
identifier: 'facialHair', identifier: 'facialHair',
text: i18n.t('facialHairs', language), text: i18n.t('titleFacialHair', language),
items: [],
};
const customizationMatcher = getScheduleMatchingGroup('customizations');
each(['color', 'base', 'mustache', 'beard'], hairType => {
let category;
if (hairType === 'beard' || hairType === 'mustache') {
category = facialHairCategory;
} else {
category = {
identifier: hairType,
text: i18n.t(`titleHair${hairType}`, language),
items: [],
}; };
facialHairCategory.items = values(content.appearances.hair.mustache)
.filter(style => {
const { hair } = user.purchased;
if (hair && hair.mustache && hair.mustache[style.key]) {
return false;
} }
if (style.set) { eachRight(content.appearances.hair[hairType], (hairStyle, key) => {
if (style.set.availableFrom) { if (hairStyle.price > 0 && (!user.purchased.hair || !user.purchased.hair[hairType]
return moment().isBetween(style.set.availableFrom, style.set.availableUntil); || !user.purchased.hair[hairType][key])
} && customizationMatcher.match(hairStyle.set.key)) {
if (style.set.availableUntil) { const item = getItemInfo(
return moment().isBefore(style.set.availableUntil); user,
} `hair${hairType}`,
return true; hairStyle,
} officialPinnedItems,
return false; language,
})
.map(style => getItemInfo(user, 'mustache', style, officialPinnedItems, language))
.concat(
values(content.appearances.hair.beard)
.filter(style => {
const { hair } = user.purchased;
if (hair && hair.beard && hair.beard[style.key]) {
return false;
}
if (style.set) {
if (style.set.availableFrom) {
return moment().isBetween(style.set.availableFrom, style.set.availableUntil);
}
if (style.set.availableUntil) {
return moment().isBefore(style.set.availableUntil);
}
return true;
}
return false;
})
.map(style => getItemInfo(user, 'beard', style, officialPinnedItems, language)),
); );
categories.push(facialHairCategory); category.items.push(item);
}
});
// only add the facial hair category once
if (hairType !== 'beard') {
categories.push(category);
}
});
const skinsCategory = { each(['shirt', 'skin'], type => {
identifier: 'skins', const category = {
text: i18n.t('skins', language), identifier: type,
text: i18n.t(`${type}s`, language),
items: [],
}; };
skinsCategory.items = values(content.appearances.skin) eachRight(content.appearances[type], (appearance, key) => {
.filter(color => { if (appearance.price > 0 && (!user.purchased[type] || !user.purchased[type][key])
const { skin } = user.purchased; && customizationMatcher.match(appearance.set.key)) {
if (skin && skin[color.key]) { const item = getItemInfo(
return false; user,
type,
appearance,
officialPinnedItems,
language,
);
category.items.push(item);
} }
if (color.set) { });
if (color.set.availableFrom) { categories.push(category);
return moment().isBetween(color.set.availableFrom, color.set.availableUntil); });
}
if (color.set.availableUntil) {
return moment().isBefore(color.set.availableUntil);
}
return true;
}
return false;
})
.map(color => getItemInfo(user, 'skin', color, officialPinnedItems, language));
categories.push(skinsCategory);
const animalEarsCategory = { const animalEarsCategory = {
identifier: 'animalEars', identifier: 'animalEars',
@@ -709,41 +679,7 @@ shops.getCustomizationsShopCategories = function getCustomizationsShopCategories
.map(gearItem => getItemInfo(user, 'gear', gearItem, officialPinnedItems, language)); .map(gearItem => getItemInfo(user, 'gear', gearItem, officialPinnedItems, language));
categories.push(animalTailsCategory); categories.push(animalTailsCategory);
const shirtsCategory = {
identifier: 'shirts',
text: i18n.t('shirts', language),
};
shirtsCategory.items = values(content.appearances.shirt)
.filter(color => {
const { shirt } = user.purchased;
if (shirt && shirt[color.key]) {
return false;
}
if (color.set) {
if (color.set.availableFrom) {
return moment().isBetween(color.set.availableFrom, color.set.availableUntil);
}
if (color.set.availableUntil) {
return moment().isBefore(color.set.availableUntil);
}
return true;
}
return false;
})
.map(color => getItemInfo(user, 'shirt', color, officialPinnedItems, language));
categories.push(shirtsCategory);
return categories; return categories;
}; };
shops.getCustomizationsShop = function getCustomizationsShop (user, language) {
return {
identifier: 'customizations',
text: i18n.t('customizations'),
// notes: i18n.t('customizations'),
imageName: 'npc_alex',
categories: shops.getCustomizationsShopCategories(user, language),
};
};
export default shops; export default shops;

View File

@@ -150,7 +150,7 @@ api.getBackgroundShopItems = {
* @apiName GetCustomizationShopItems * @apiName GetCustomizationShopItems
* @apiGroup Shops * @apiGroup Shops
* *
* @apiSuccess {Object} data List of available backgrounds * @apiSuccess {Object} data List of available avatar customizations
* @apiSuccess {string} message Success message * @apiSuccess {string} message Success message
*/ */
api.getCustomizationsShop = { api.getCustomizationsShop = {