item pinning (#8918)
* toggle pinned state of items server + client * pin quests / add pin src * add officially pinned items and api to get in app rewards * update schema and get items deatils * update pin actions to the new logic * show countBadge only with a number * extract getPinKey - pin seasonal items * togglePinned in buy-dialogs * add pinKey to shop items * wip * wip * fix path * togglePinnedItem as common.op / use in client * fix linting * pinning: getItemInfo and save in db path and type * make api more consistent, fix bugs * updates * fix bugs * update actions to current api * marketGear * change to pinType * add mystery_set to getItemInfo * fix isPinned * ignore animals * list shopItems (initial) * shopItem now has default popoverconent, itemclass and price / currency - list pinned items as rewards - attributes to gear * show buyModal for the rewards * show mystery_set icon * add info whether item is suggested * write migration, fix style issues * pin potion and armoire * make potion, armoire not unpinnable * show notes for armoire and potion, add default items for new users * show unpin notification * add/remove pinned gear on class-change * remove pinned & add new gear on purchase - refactoring pinning methods - fixes * always allow to purchase armoire * highlight item if suggested
This commit is contained in:
@@ -584,9 +584,11 @@ let backgrounds = {
|
||||
};
|
||||
/* eslint-enable quote-props */
|
||||
|
||||
forOwn(backgrounds, function prefillBackgroundSet (value) {
|
||||
forOwn(value, function prefillBackground (bgObject) {
|
||||
bgObject.price = 7;
|
||||
forOwn(backgrounds, function prefillBackgroundSet (backgroundsInSet, set) {
|
||||
forOwn(backgroundsInSet, function prefillBackground (background, bgKey) {
|
||||
background.key = bgKey;
|
||||
background.set = set;
|
||||
background.price = 7;
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import defaults from 'lodash/defaults';
|
||||
import each from 'lodash/each';
|
||||
import includes from 'lodash/includes';
|
||||
import moment from 'moment';
|
||||
import t from './translation';
|
||||
|
||||
@@ -33,6 +32,8 @@ import timeTravelers from './time-travelers';
|
||||
|
||||
import loginIncentives from './loginIncentives';
|
||||
|
||||
import officialPinnedItems from './officialPinnedItems';
|
||||
|
||||
api.achievements = achievements;
|
||||
|
||||
api.quests = quests;
|
||||
@@ -48,6 +49,8 @@ api.subscriptionBlocks = subscriptionBlocks;
|
||||
api.mystery = timeTravelers.mystery;
|
||||
api.timeTravelerStore = timeTravelers.timeTravelerStore;
|
||||
|
||||
api.officialPinnedItems = officialPinnedItems;
|
||||
|
||||
/*
|
||||
---------------------------------------------------------------
|
||||
Discounted Item Bundles
|
||||
@@ -112,8 +115,8 @@ api.armoire = {
|
||||
},
|
||||
value: 100,
|
||||
key: 'armoire',
|
||||
canOwn (u) {
|
||||
return includes(u.achievements.ultimateGearSets, true);
|
||||
canOwn () {
|
||||
return true;
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -196,6 +196,7 @@ let mysterySets = {
|
||||
each(mysterySets, (value, key) => {
|
||||
value.key = key;
|
||||
value.text = t(`mysterySet${key}`);
|
||||
value.class = `shop_set_mystery_${key}`;
|
||||
});
|
||||
|
||||
module.exports = mysterySets;
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export default [];
|
||||
@@ -64,6 +64,9 @@ api.preenTodos = preenTodos;
|
||||
import updateStore from './libs/updateStore';
|
||||
api.updateStore = updateStore;
|
||||
|
||||
import inAppRewards from './libs/inAppRewards';
|
||||
api.inAppRewards = inAppRewards;
|
||||
|
||||
import uuid from './libs/uuid';
|
||||
api.uuid = uuid;
|
||||
|
||||
@@ -161,6 +164,7 @@ import deletePM from './ops/deletePM';
|
||||
import reroll from './ops/reroll';
|
||||
import reset from './ops/reset';
|
||||
import markPmsRead from './ops/markPMSRead';
|
||||
import pinnedGearUtils from './ops/pinnedGearUtils';
|
||||
|
||||
api.ops = {
|
||||
scoreTask,
|
||||
@@ -198,6 +202,7 @@ api.ops = {
|
||||
reroll,
|
||||
reset,
|
||||
markPmsRead,
|
||||
pinnedGearUtils,
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -0,0 +1,247 @@
|
||||
import i18n from '../i18n';
|
||||
import content from '../content/index';
|
||||
import { BadRequest } from './errors';
|
||||
import count from '../count';
|
||||
|
||||
function lockQuest (quest, user) {
|
||||
if (quest.lvl && user.stats.lvl < quest.lvl) return true;
|
||||
if (quest.unlockCondition && (quest.key === 'moon1' || quest.key === 'moon2' || quest.key === 'moon3')) {
|
||||
return user.loginIncentives < quest.unlockCondition.incentiveThreshold;
|
||||
}
|
||||
if (user.achievements.quests) return quest.previous && !user.achievements.quests[quest.previous];
|
||||
return quest.previous;
|
||||
}
|
||||
|
||||
const officialPinnedItems = content.officialPinnedItems;
|
||||
|
||||
function isItemSuggested (itemInfo) {
|
||||
return officialPinnedItems.findIndex(officialItem => {
|
||||
return officialItem.type === itemInfo.pinType && officialItem.path === itemInfo.path;
|
||||
}) > -1;
|
||||
}
|
||||
|
||||
function getDefaultGearProps (item, language) {
|
||||
return {
|
||||
key: item.key,
|
||||
text: item.text(language),
|
||||
notes: item.notes(language),
|
||||
type: item.type,
|
||||
specialClass: item.specialClass,
|
||||
locked: false,
|
||||
purchaseType: 'gear',
|
||||
class: `shop_${item.key}`,
|
||||
path: `gear.flat.${item.key}`,
|
||||
str: item.str,
|
||||
int: item.int,
|
||||
per: item.per,
|
||||
con: item.con,
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = function getItemInfo (user, type, item, language = 'en') {
|
||||
let itemInfo;
|
||||
|
||||
switch (type) {
|
||||
case 'egg':
|
||||
itemInfo = {
|
||||
key: item.key,
|
||||
text: i18n.t('egg', {eggType: item.text(language)}, language),
|
||||
notes: item.notes(language),
|
||||
value: item.value,
|
||||
class: `Pet_Egg_${item.key}`,
|
||||
locked: false,
|
||||
currency: 'gems',
|
||||
purchaseType: 'eggs',
|
||||
path: `eggs.${item.key}`,
|
||||
pinType: 'egg',
|
||||
};
|
||||
break;
|
||||
case 'hatchingPotion':
|
||||
itemInfo = {
|
||||
key: item.key,
|
||||
text: i18n.t('potion', {potionType: item.text(language)}),
|
||||
notes: item.notes(language),
|
||||
class: `Pet_HatchingPotion_${item.key}`,
|
||||
value: item.value,
|
||||
locked: false,
|
||||
currency: 'gems',
|
||||
purchaseType: 'hatchingPotions',
|
||||
path: `hatchingPotions.${item.key}`,
|
||||
pinType: 'hatchingPotion',
|
||||
};
|
||||
break;
|
||||
case 'premiumHatchingPotion':
|
||||
itemInfo = {
|
||||
key: item.key,
|
||||
text: i18n.t('potion', {potionType: item.text(language)}),
|
||||
notes: `${item.notes(language)} ${item._addlNotes(language)}`,
|
||||
class: `Pet_HatchingPotion_${item.key}`,
|
||||
value: item.value,
|
||||
locked: false,
|
||||
currency: 'gems',
|
||||
purchaseType: 'hatchingPotions',
|
||||
path: `premiumHatchingPotions.${item.key}`,
|
||||
pinType: 'premiumHatchingPotion',
|
||||
};
|
||||
break;
|
||||
case 'food':
|
||||
itemInfo = {
|
||||
key: item.key,
|
||||
text: item.text(language),
|
||||
notes: item.notes(language),
|
||||
class: `Pet_Food_${item.key}`,
|
||||
value: item.value,
|
||||
locked: false,
|
||||
currency: 'gems',
|
||||
purchaseType: 'food',
|
||||
path: `food.${item.key}`,
|
||||
pinType: 'food',
|
||||
};
|
||||
break;
|
||||
case 'questBundle':
|
||||
itemInfo = {
|
||||
key: item.key,
|
||||
text: item.text(language),
|
||||
notes: item.notes(language),
|
||||
value: item.value,
|
||||
currency: 'gems',
|
||||
class: `quest_bundle_${item.key}`,
|
||||
purchaseType: 'bundles',
|
||||
path: `bundles.${item.key}`,
|
||||
pinType: 'questBundle',
|
||||
};
|
||||
break;
|
||||
case 'quest': // eslint-disable-line no-case-declarations
|
||||
const locked = lockQuest(item, user);
|
||||
|
||||
itemInfo = {
|
||||
key: item.key,
|
||||
text: item.text(language),
|
||||
notes: item.notes(language),
|
||||
group: item.group,
|
||||
value: item.goldValue ? item.goldValue : item.value,
|
||||
currency: item.goldValue ? 'gold' : 'gems',
|
||||
locked,
|
||||
unlockCondition: item.unlockCondition,
|
||||
drop: item.drop,
|
||||
boss: item.boss,
|
||||
collect: item.collect,
|
||||
lvl: item.lvl,
|
||||
class: locked ? `inventory_quest_scroll_locked inventory_quest_scroll_${item.key}_locked` : `inventory_quest_scroll inventory_quest_scroll_${item.key}`,
|
||||
purchaseType: 'quests',
|
||||
path: `quests.${item.key}`,
|
||||
pinType: 'quest',
|
||||
};
|
||||
break;
|
||||
case 'timeTravelers':
|
||||
// TODO
|
||||
itemInfo = {};
|
||||
break;
|
||||
case 'seasonalSpell':
|
||||
itemInfo = {
|
||||
key: item.keyspellKey,
|
||||
text: item.text(language),
|
||||
notes: item.notes(language),
|
||||
value: item.value,
|
||||
type: 'special',
|
||||
currency: 'gold',
|
||||
locked: false,
|
||||
purchaseType: 'spells',
|
||||
class: `inventory_special_${item.key}`,
|
||||
path: `spells.special.${item.key}`,
|
||||
pinType: 'seasonalSpell',
|
||||
};
|
||||
break;
|
||||
case 'seasonalQuest':
|
||||
itemInfo = {
|
||||
key: item.key,
|
||||
text: item.text(language),
|
||||
notes: item.notes(language),
|
||||
value: item.value,
|
||||
type: 'quests',
|
||||
currency: 'gems',
|
||||
locked: false,
|
||||
drop: item.drop,
|
||||
boss: item.boss,
|
||||
collect: item.collect,
|
||||
class: `inventory_quest_scroll_${item.key}`,
|
||||
purchaseType: 'quests',
|
||||
path: `quests.${item.key}`,
|
||||
pinType: 'seasonalQuest',
|
||||
};
|
||||
break;
|
||||
case 'gear':
|
||||
// spread operator not available
|
||||
itemInfo = Object.assign(getDefaultGearProps(item, language), {
|
||||
value: item.twoHanded ? 2 : 1,
|
||||
currency: 'gems',
|
||||
pinType: 'gear',
|
||||
});
|
||||
break;
|
||||
case 'marketGear':
|
||||
itemInfo = Object.assign(getDefaultGearProps(item, language), {
|
||||
value: item.value,
|
||||
currency: 'gold',
|
||||
pinType: 'marketGear',
|
||||
});
|
||||
break;
|
||||
case 'background':
|
||||
itemInfo = {
|
||||
key: item.key,
|
||||
text: item.text(language),
|
||||
notes: item.notes(language),
|
||||
class: `icon_background_${item.key}`,
|
||||
value: item.price,
|
||||
currency: item.currency || 'gems',
|
||||
purchaseType: 'backgrounds',
|
||||
path: `backgrounds.${item.set}.${item.key}`,
|
||||
pinType: 'background',
|
||||
};
|
||||
break;
|
||||
case 'mystery_set':
|
||||
itemInfo = {
|
||||
key: item.key,
|
||||
text: item.text(language),
|
||||
value: 1,
|
||||
currency: 'hourglasses',
|
||||
purchaseType: 'mystery_set',
|
||||
class: `shop_set_mystery_${item.key}`,
|
||||
path: `mystery.${item.key}`,
|
||||
pinType: 'mystery_set',
|
||||
};
|
||||
break;
|
||||
case 'potion':
|
||||
itemInfo = {
|
||||
key: item.key,
|
||||
text: item.text(language),
|
||||
notes: item.notes(language),
|
||||
value: item.value,
|
||||
currency: 'gold',
|
||||
purchaseType: 'potions',
|
||||
class: `shop_${item.key}`,
|
||||
path: 'potion',
|
||||
pinType: 'potion',
|
||||
};
|
||||
break;
|
||||
case 'armoire':
|
||||
itemInfo = {
|
||||
key: item.key,
|
||||
text: item.text(language),
|
||||
notes: item.notes(user, count.remainingGearInSet(user.items.gear.owned, 'armoire')), // TODO count
|
||||
value: item.value,
|
||||
currency: 'gold',
|
||||
purchaseType: 'armoire',
|
||||
class: `shop_${item.key}`,
|
||||
path: 'armoire',
|
||||
pinType: 'armoire',
|
||||
};
|
||||
}
|
||||
|
||||
if (itemInfo) {
|
||||
itemInfo.isSuggested = isItemSuggested(itemInfo);
|
||||
} else {
|
||||
throw new BadRequest(i18n.t('wrongItemType', {type}, language));
|
||||
}
|
||||
|
||||
return itemInfo;
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
import content from '../content/index';
|
||||
import get from 'lodash/get';
|
||||
import getItemInfo from './getItemInfo';
|
||||
|
||||
const officialPinnedItems = content.officialPinnedItems;
|
||||
|
||||
module.exports = function getPinnedItems (user) {
|
||||
const officialPinnedItemsNotUnpinned = officialPinnedItems.filter(officialPin => {
|
||||
const isUnpinned = user.unpinnedItems.findIndex(unpinned => unpinned.path === officialPin.path) > -1;
|
||||
return !isUnpinned;
|
||||
});
|
||||
|
||||
const pinnedItems = officialPinnedItemsNotUnpinned.concat(user.pinnedItems);
|
||||
|
||||
return pinnedItems.map(({type, path}) => {
|
||||
return getItemInfo(user, type, get(content, path));
|
||||
});
|
||||
};
|
||||
@@ -8,18 +8,10 @@ import pickBy from 'lodash/pickBy';
|
||||
import sortBy from 'lodash/sortBy';
|
||||
import content from '../content/index';
|
||||
import i18n from '../i18n';
|
||||
import getItemInfo from './getItemInfo';
|
||||
|
||||
let shops = {};
|
||||
|
||||
function lockQuest (quest, user) {
|
||||
if (quest.lvl && user.stats.lvl < quest.lvl) return true;
|
||||
if (quest.unlockCondition && (quest.key === 'moon1' || quest.key === 'moon2' || quest.key === 'moon3')) {
|
||||
return user.loginIncentives < quest.unlockCondition.incentiveThreshold;
|
||||
}
|
||||
if (user.achievements.quests) return quest.previous && !user.achievements.quests[quest.previous];
|
||||
return quest.previous;
|
||||
}
|
||||
|
||||
shops.getMarketCategories = function getMarket (user, language) {
|
||||
let categories = [];
|
||||
let eggsCategory = {
|
||||
@@ -32,16 +24,7 @@ shops.getMarketCategories = function getMarket (user, language) {
|
||||
.filter(egg => egg.canBuy(user))
|
||||
.concat(values(content.dropEggs))
|
||||
.map(egg => {
|
||||
return {
|
||||
key: egg.key,
|
||||
text: i18n.t('egg', {eggType: egg.text()}, language),
|
||||
notes: egg.notes(language),
|
||||
value: egg.value,
|
||||
class: `Pet_Egg_${egg.key}`,
|
||||
locked: false,
|
||||
currency: 'gems',
|
||||
purchaseType: 'eggs',
|
||||
};
|
||||
return getItemInfo(user, 'egg', egg, language);
|
||||
}), 'key');
|
||||
categories.push(eggsCategory);
|
||||
|
||||
@@ -53,16 +36,7 @@ shops.getMarketCategories = function getMarket (user, language) {
|
||||
hatchingPotionsCategory.items = sortBy(values(content.hatchingPotions)
|
||||
.filter(hp => !hp.limited)
|
||||
.map(hatchingPotion => {
|
||||
return {
|
||||
key: hatchingPotion.key,
|
||||
text: i18n.t('potion', {potionType: hatchingPotion.text(language)}),
|
||||
notes: hatchingPotion.notes(language),
|
||||
class: `Pet_HatchingPotion_${hatchingPotion.key}`,
|
||||
value: hatchingPotion.value,
|
||||
locked: false,
|
||||
currency: 'gems',
|
||||
purchaseType: 'hatchingPotions',
|
||||
};
|
||||
return getItemInfo(user, 'hatchingPotion', hatchingPotion, language);
|
||||
}), 'key');
|
||||
categories.push(hatchingPotionsCategory);
|
||||
|
||||
@@ -74,16 +48,7 @@ shops.getMarketCategories = function getMarket (user, language) {
|
||||
premiumHatchingPotionsCategory.items = sortBy(values(content.hatchingPotions)
|
||||
.filter(hp => hp.limited && hp.canBuy())
|
||||
.map(premiumHatchingPotion => {
|
||||
return {
|
||||
key: premiumHatchingPotion.key,
|
||||
text: i18n.t('potion', {potionType: premiumHatchingPotion.text(language)}),
|
||||
notes: `${premiumHatchingPotion.notes(language)} ${premiumHatchingPotion._addlNotes(language)}`,
|
||||
class: `Pet_HatchingPotion_${premiumHatchingPotion.key}`,
|
||||
value: premiumHatchingPotion.value,
|
||||
locked: false,
|
||||
currency: 'gems',
|
||||
purchaseType: 'hatchingPotions',
|
||||
};
|
||||
return getItemInfo(user, 'premiumHatchingPotion', premiumHatchingPotion, language);
|
||||
}), 'key');
|
||||
if (premiumHatchingPotionsCategory.items.length > 0) {
|
||||
categories.push(premiumHatchingPotionsCategory);
|
||||
@@ -97,16 +62,7 @@ shops.getMarketCategories = function getMarket (user, language) {
|
||||
foodCategory.items = sortBy(values(content.food)
|
||||
.filter(food => food.canDrop || food.key === 'Saddle')
|
||||
.map(foodItem => {
|
||||
return {
|
||||
key: foodItem.key,
|
||||
text: foodItem.text(language),
|
||||
notes: foodItem.notes(language),
|
||||
class: `Pet_Food_${foodItem.key}`,
|
||||
value: foodItem.value,
|
||||
locked: false,
|
||||
currency: 'gems',
|
||||
purchaseType: 'food',
|
||||
};
|
||||
return getItemInfo(user, 'food', foodItem, language);
|
||||
}), 'key');
|
||||
categories.push(foodCategory);
|
||||
|
||||
@@ -178,15 +134,7 @@ shops.getQuestShopCategories = function getQuestShopCategories (user, language)
|
||||
bundleCategory.items = sortBy(values(content.bundles)
|
||||
.filter(bundle => bundle.type === 'quests' && bundle.canBuy())
|
||||
.map(bundle => {
|
||||
return {
|
||||
key: bundle.key,
|
||||
text: bundle.text(language),
|
||||
notes: bundle.notes(language),
|
||||
value: bundle.value,
|
||||
currency: 'gems',
|
||||
class: `quest_bundle_${bundle.key}`,
|
||||
purchaseType: 'bundles',
|
||||
};
|
||||
return getItemInfo(user, 'questBundle', bundle, language);
|
||||
}));
|
||||
|
||||
if (bundleCategory.items.length > 0) {
|
||||
@@ -202,23 +150,7 @@ shops.getQuestShopCategories = function getQuestShopCategories (user, language)
|
||||
category.items = content.questsByLevel
|
||||
.filter(quest => quest.canBuy(user) && quest.category === type)
|
||||
.map(quest => {
|
||||
let locked = lockQuest(quest, user);
|
||||
return {
|
||||
key: quest.key,
|
||||
text: quest.text(language),
|
||||
notes: quest.notes(language),
|
||||
group: quest.group,
|
||||
value: quest.goldValue ? quest.goldValue : quest.value,
|
||||
currency: quest.goldValue ? 'gold' : 'gems',
|
||||
locked,
|
||||
unlockCondition: quest.unlockCondition,
|
||||
drop: quest.drop,
|
||||
boss: quest.boss,
|
||||
collect: quest.collect,
|
||||
lvl: quest.lvl,
|
||||
class: locked ? `inventory_quest_scroll_locked inventory_quest_scroll_${quest.key}_locked` : `inventory_quest_scroll inventory_quest_scroll_${quest.key}`,
|
||||
purchaseType: 'quests',
|
||||
};
|
||||
return getItemInfo(user, 'quest', quest, language);
|
||||
});
|
||||
|
||||
categories.push(category);
|
||||
@@ -251,6 +183,7 @@ shops.getTimeTravelersCategories = function getTimeTravelersCategories (user, la
|
||||
notes: '',
|
||||
locked: false,
|
||||
currency: 'hourglasses',
|
||||
pinType: 'IGNORE',
|
||||
};
|
||||
category.items.push(item);
|
||||
}
|
||||
@@ -269,6 +202,8 @@ shops.getTimeTravelersCategories = function getTimeTravelersCategories (user, la
|
||||
let category = {
|
||||
identifier: set.key,
|
||||
text: set.text(language),
|
||||
path: `mystery.${set.key}`,
|
||||
pinType: 'mystery_set',
|
||||
purchaseAll: true,
|
||||
};
|
||||
|
||||
@@ -283,6 +218,7 @@ shops.getTimeTravelersCategories = function getTimeTravelersCategories (user, la
|
||||
locked: false,
|
||||
currency: 'hourglasses',
|
||||
class: `shop_${item.key}`,
|
||||
pinKey: `timeTravelers!gear.flat.${item.key}`,
|
||||
};
|
||||
});
|
||||
if (category.items.length > 0) {
|
||||
@@ -322,18 +258,8 @@ shops.getSeasonalShopCategories = function getSeasonalShopCategories (user, lang
|
||||
text: i18n.t('seasonalItems', language),
|
||||
};
|
||||
|
||||
category.items = map(spells, (spell, key) => {
|
||||
return {
|
||||
key,
|
||||
text: spell.text(language),
|
||||
notes: spell.notes(language),
|
||||
value: spell.value,
|
||||
type: 'special',
|
||||
currency: 'gold',
|
||||
locked: false,
|
||||
purchaseType: 'spells',
|
||||
class: `inventory_special_${key}`,
|
||||
};
|
||||
category.items = map(spells, (spell) => {
|
||||
return getItemInfo(user, 'seasonalSpell', spell, language);
|
||||
});
|
||||
|
||||
categories.push(category);
|
||||
@@ -349,21 +275,8 @@ shops.getSeasonalShopCategories = function getSeasonalShopCategories (user, lang
|
||||
text: i18n.t('quests', language),
|
||||
};
|
||||
|
||||
category.items = map(quests, (quest, key) => {
|
||||
return {
|
||||
key,
|
||||
text: quest.text(language),
|
||||
notes: quest.notes(language),
|
||||
value: quest.value,
|
||||
type: 'quests',
|
||||
currency: 'gems',
|
||||
locked: false,
|
||||
drop: quest.drop,
|
||||
boss: quest.boss,
|
||||
collect: quest.collect,
|
||||
class: `inventory_quest_scroll_${key}`,
|
||||
purchaseType: 'quests',
|
||||
};
|
||||
category.items = map(quests, (quest) => {
|
||||
return getItemInfo(user, 'seasonalQuest', quest, language);
|
||||
});
|
||||
|
||||
categories.push(category);
|
||||
@@ -379,18 +292,7 @@ shops.getSeasonalShopCategories = function getSeasonalShopCategories (user, lang
|
||||
category.items = flatGearArray.filter((gear) => {
|
||||
return user.items.gear.owned[gear.key] === undefined && gear.index === key;
|
||||
}).map(gear => {
|
||||
return {
|
||||
key: gear.key,
|
||||
text: gear.text(language),
|
||||
notes: gear.notes(language),
|
||||
value: gear.twoHanded ? 2 : 1,
|
||||
type: gear.type,
|
||||
specialClass: gear.specialClass,
|
||||
locked: false,
|
||||
currency: 'gems',
|
||||
purchaseType: 'gear',
|
||||
class: `shop_${gear.key}`,
|
||||
};
|
||||
return getItemInfo(null, 'gear', gear, language);
|
||||
});
|
||||
|
||||
if (category.items.length > 0) {
|
||||
@@ -412,15 +314,8 @@ shops.getBackgroundShopSets = function getBackgroundShopSets (language) {
|
||||
text: i18n.t(key, language),
|
||||
};
|
||||
|
||||
set.items = map(group, (background, bgKey) => {
|
||||
return {
|
||||
key: bgKey,
|
||||
text: background.text(language),
|
||||
notes: background.notes(language),
|
||||
value: background.price,
|
||||
currency: background.currency || 'gems',
|
||||
purchaseType: 'backgrounds',
|
||||
};
|
||||
set.items = map(group, (background) => {
|
||||
return getItemInfo(null, 'background', background, language);
|
||||
});
|
||||
|
||||
sets.push(set);
|
||||
|
||||
@@ -11,6 +11,8 @@ import {
|
||||
import handleTwoHanded from '../fns/handleTwoHanded';
|
||||
import ultimateGear from '../fns/ultimateGear';
|
||||
|
||||
import { removePinnedGearAddPossibleNewOnes } from './pinnedGearUtils';
|
||||
|
||||
module.exports = function buyGear (user, req = {}, analytics) {
|
||||
let key = get(req, 'params.key');
|
||||
if (!key) throw new BadRequest(i18n.t('missingKeyParam', req.language));
|
||||
@@ -38,6 +40,7 @@ module.exports = function buyGear (user, req = {}, analytics) {
|
||||
message = handleTwoHanded(user, item, undefined, req);
|
||||
}
|
||||
|
||||
removePinnedGearAddPossibleNewOnes(user, `gear.flat.${item.key}`);
|
||||
user.items.gear.owned[item.key] = true;
|
||||
|
||||
if (item.last) ultimateGear(user);
|
||||
|
||||
@@ -7,8 +7,11 @@ import {
|
||||
NotAuthorized,
|
||||
BadRequest,
|
||||
} from '../libs/errors';
|
||||
import { removePinnedGearByClass, addPinnedGearByClass } from './pinnedGearUtils';
|
||||
|
||||
function resetClass (user, req = {}) {
|
||||
removePinnedGearByClass(user);
|
||||
|
||||
if (user.preferences.disableClasses) {
|
||||
user.preferences.disableClasses = false;
|
||||
user.preferences.autoAllocate = false;
|
||||
@@ -41,6 +44,8 @@ module.exports = function changeClass (user, req = {}, analytics) {
|
||||
user.stats.class = klass;
|
||||
user.flags.classSelected = true;
|
||||
|
||||
addPinnedGearByClass(user);
|
||||
|
||||
user.items.gear.owned[`weapon_${klass}_0`] = true;
|
||||
if (klass === 'rogue') user.items.gear.owned[`shield_${klass}_0`] = true;
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ import readCard from './readCard';
|
||||
import openMysteryItem from './openMysteryItem';
|
||||
import scoreTask from './scoreTask';
|
||||
import markPmsRead from './markPMSRead';
|
||||
import * as pinnedGearUtils from './pinnedGearUtils';
|
||||
|
||||
module.exports = {
|
||||
sleep,
|
||||
@@ -84,4 +85,5 @@ module.exports = {
|
||||
openMysteryItem,
|
||||
scoreTask,
|
||||
markPmsRead,
|
||||
pinnedGearUtils,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
import content from '../content/index';
|
||||
import getItemInfo from '../libs/getItemInfo';
|
||||
import get from 'lodash/get';
|
||||
import { BadRequest } from '../libs/errors';
|
||||
import i18n from '../i18n';
|
||||
|
||||
const officialPinnedItems = content.officialPinnedItems;
|
||||
|
||||
import updateStore from '../libs/updateStore';
|
||||
|
||||
function addPinnedGearByClass (user) {
|
||||
if (user.flags.classSelected) {
|
||||
let newPinnedItems = updateStore(user);
|
||||
|
||||
for (let item of newPinnedItems) {
|
||||
let itemInfo = getItemInfo(user, 'marketGear', item);
|
||||
|
||||
user.pinnedItems.push({
|
||||
type: 'marketGear',
|
||||
path: itemInfo.path,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function removeItemByPath (user, path) {
|
||||
const foundIndex = user.pinnedItems.findIndex(pinnedItem => {
|
||||
return pinnedItem.path === path;
|
||||
});
|
||||
|
||||
if (foundIndex >= 0) {
|
||||
user.pinnedItems.splice(foundIndex, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function removePinnedGearByClass (user) {
|
||||
if (user.flags.classSelected) {
|
||||
let currentPinnedItems = updateStore(user);
|
||||
|
||||
for (let item of currentPinnedItems) {
|
||||
let itemInfo = getItemInfo(user, 'marketGear', item);
|
||||
|
||||
removeItemByPath(user, itemInfo.path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function removePinnedGearAddPossibleNewOnes (user, itemPath) {
|
||||
let currentPinnedItems = updateStore(user);
|
||||
let removeAndAddAllItems = false;
|
||||
|
||||
for (let item of currentPinnedItems) {
|
||||
let itemInfo = getItemInfo(user, 'marketGear', item);
|
||||
|
||||
if (itemInfo.path === itemPath) {
|
||||
removeAndAddAllItems = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
removeItemByPath(user, itemPath);
|
||||
|
||||
if (removeAndAddAllItems) {
|
||||
// an item of the users current "new" gear was bought
|
||||
// remove the old pinned gear items and add the new gear back
|
||||
removePinnedGearByClass(user);
|
||||
addPinnedGearByClass(user);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {boolean} TRUE added the item / FALSE removed it
|
||||
*/
|
||||
function togglePinnedItem (user, {item, type, path}, req = {}) {
|
||||
let arrayToChange;
|
||||
|
||||
if (!path) { // If path isn't passed it means an item was passed
|
||||
path = getItemInfo(user, type, item, req.language).path;
|
||||
}
|
||||
|
||||
if (!item) item = get(content, path);
|
||||
|
||||
if (path === 'armoire' || path === 'potion') {
|
||||
throw new BadRequest(i18n.t('cannotUpinArmoirPotion', req.language));
|
||||
}
|
||||
|
||||
let isOfficialPinned = officialPinnedItems.find(officialPinnedItem => {
|
||||
return officialPinnedItem.path === path;
|
||||
}) !== undefined;
|
||||
|
||||
if (isOfficialPinned) {
|
||||
arrayToChange = user.unpinnedItems;
|
||||
} else {
|
||||
arrayToChange = user.pinnedItems;
|
||||
}
|
||||
|
||||
const foundIndex = arrayToChange.findIndex(pinnedItem => {
|
||||
return pinnedItem.path === path;
|
||||
});
|
||||
|
||||
if (foundIndex >= 0) {
|
||||
arrayToChange.splice(foundIndex, 1);
|
||||
return isOfficialPinned;
|
||||
} else {
|
||||
arrayToChange.push({path, type});
|
||||
return !isOfficialPinned;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
addPinnedGearByClass,
|
||||
removePinnedGearByClass,
|
||||
removePinnedGearAddPossibleNewOnes,
|
||||
togglePinnedItem,
|
||||
removeItemByPath,
|
||||
};
|
||||
Reference in New Issue
Block a user