mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-18 07:07:35 +01:00
wip(shared): port buy ops and linked fns
This commit is contained in:
@@ -77,6 +77,7 @@
|
||||
"guildQuestsNotSupported": "Guilds cannot be invited on quests.",
|
||||
"questNotFound": "Quest \"<%= key %>\" not found.",
|
||||
"questNotOwned": "You don't own that quest scroll.",
|
||||
"questNotGoldPurchasable": "Quest \"<%= key %>\" is not a Gold-purchasable quest.",
|
||||
"questLevelTooHigh": "You must be level <%= level %> to begin this quest.",
|
||||
"questAlreadyUnderway": "Your party is already on a quest. Try again when the current quest has ended.",
|
||||
"questAlreadyAccepted": "You already accepted the quest invitation.",
|
||||
@@ -102,5 +103,9 @@
|
||||
"spellNotOwned": "You don't own this spell.",
|
||||
"spellLevelTooHigh": "You must be level <%= level %> to use this spell.",
|
||||
"invalidAttribute": "\"<%= attr %>\" is not a valid attribute.",
|
||||
"notEnoughAttrPoints": "You don't have enough attribute points."
|
||||
"notEnoughAttrPoints": "You don't have enough attribute points.",
|
||||
"missingKeyParam": "\"req.params.key\" is required.",
|
||||
"mysterySetNotFound": "Mystery set not found, or set already owned",
|
||||
"itemNotFound": "Item \"<%= key %>\" not found.",
|
||||
"cannoyBuyItem": "You can't buy this item"
|
||||
}
|
||||
|
||||
@@ -1,24 +1,23 @@
|
||||
import content from '../content/index';
|
||||
import i18n from '../i18n';
|
||||
|
||||
module.exports = function(user, item, type, req) {
|
||||
var message, currentWeapon, currentShield;
|
||||
if (type == null) {
|
||||
type = 'equipped';
|
||||
}
|
||||
currentShield = content.gear.flat[user.items.gear[type].shield];
|
||||
currentWeapon = content.gear.flat[user.items.gear[type].weapon];
|
||||
module.exports = function handleTwoHanded (user, item, type = 'equipped', req) {
|
||||
let currentShield = content.gear.flat[user.items.gear[type].shield];
|
||||
let currentWeapon = content.gear.flat[user.items.gear[type].weapon];
|
||||
|
||||
if (item.type === "shield" && (currentWeapon ? currentWeapon.twoHanded : false)) {
|
||||
let message;
|
||||
|
||||
if (item.type === 'shield' && (currentWeapon ? currentWeapon.twoHanded : false)) {
|
||||
user.items.gear[type].weapon = 'weapon_base_0';
|
||||
message = i18n.t('messageTwoHandedUnequip', {
|
||||
twoHandedText: currentWeapon.text(req.language), offHandedText: item.text(req.language),
|
||||
}, req.language);
|
||||
} else if (item.twoHanded && (currentShield && user.items.gear[type].shield != "shield_base_0")) {
|
||||
user.items.gear[type].shield = "shield_base_0";
|
||||
} else if (item.twoHanded && (currentShield && user.items.gear[type].shield !== 'shield_base_0')) {
|
||||
user.items.gear[type].shield = 'shield_base_0';
|
||||
message = i18n.t('messageTwoHandedEquip', {
|
||||
twoHandedText: item.text(req.language), offHandedText: currentShield.text(req.language),
|
||||
}, req.language);
|
||||
}
|
||||
|
||||
return message;
|
||||
};
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
import _ from 'lodash';
|
||||
/*
|
||||
Because the same op needs to be performed on the client and the server (critical hits, item drops, etc),
|
||||
we need things to be "random", but technically predictable so that they don't go out-of-sync
|
||||
*/
|
||||
|
||||
module.exports = function(user, seed) {
|
||||
var x;
|
||||
// Because the same op needs to be performed on the client and the server (critical hits, item drops, etc),
|
||||
// we need things to be "random", but technically predictable so that they don't go out-of-sync
|
||||
|
||||
module.exports = function predictableRandom (user, seed) {
|
||||
if (!seed || seed === Math.PI) {
|
||||
seed = _.reduce(user.stats, (function(m, v) {
|
||||
if (_.isNumber(v)) {
|
||||
return m + v;
|
||||
seed = _.reduce(user.stats, (accumulator, val) => {
|
||||
if (_.isNumber(val)) {
|
||||
return accumulator + val;
|
||||
} else {
|
||||
return m;
|
||||
return accumulator;
|
||||
}
|
||||
}), 0);
|
||||
}, 0);
|
||||
}
|
||||
x = Math.sin(seed++) * 10000;
|
||||
|
||||
let x = Math.sin(seed++) * 10000;
|
||||
return x - Math.floor(x);
|
||||
};
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
import _ from 'lodash';
|
||||
import predictableRandom from './predictableRandom';
|
||||
|
||||
/*
|
||||
Get a random property from an object
|
||||
returns random property (the value)
|
||||
*/
|
||||
// Get a random property from an object
|
||||
// returns random property (the value)
|
||||
|
||||
module.exports = function(user, obj, options) {
|
||||
var array, rand;
|
||||
array = (options != null ? options.key : void 0) ? _.keys(obj) : _.values(obj);
|
||||
rand = user.fns.predictableRandom(options != null ? options.seed : void 0);
|
||||
module.exports = function randomVal (user, obj, options = {}) {
|
||||
let array = options.key ? _.keys(obj) : _.values(obj);
|
||||
let rand = predictableRandom(user, options.seed);
|
||||
array.sort();
|
||||
return array[Math.floor(rand * array.length)];
|
||||
};
|
||||
|
||||
@@ -1,33 +1,35 @@
|
||||
import content from '../content/index';
|
||||
import _ from 'lodash';
|
||||
|
||||
module.exports = function(user) {
|
||||
var base, owned;
|
||||
owned = typeof window !== "undefined" && window !== null ? user.items.gear.owned : user.items.gear.owned.toObject();
|
||||
if ((base = user.achievements).ultimateGearSets == null) {
|
||||
base.ultimateGearSets = {
|
||||
module.exports = function ultimateGear (user) {
|
||||
let owned = window ? user.items.gear.owned : user.items.gear.owned.toObject();
|
||||
|
||||
if (!user.achievements.ultimateGearSets) {
|
||||
user.achievements.ultimateGearSets = {
|
||||
healer: false,
|
||||
wizard: false,
|
||||
rogue: false,
|
||||
warrior: false
|
||||
warrior: false,
|
||||
};
|
||||
}
|
||||
content.classes.forEach(function(klass) {
|
||||
|
||||
content.classes.forEach((klass) => {
|
||||
if (user.achievements.ultimateGearSets[klass] !== true) {
|
||||
return user.achievements.ultimateGearSets[klass] = _.reduce(['armor', 'shield', 'head', 'weapon'], function(soFarGood, type) {
|
||||
var found;
|
||||
found = _.find(content.gear.tree[type][klass], {
|
||||
last: true
|
||||
user.achievements.ultimateGearSets[klass] = _.reduce(['armor', 'shield', 'head', 'weapon'], (soFarGood, type) => {
|
||||
let found = _.find(content.gear.tree[type][klass], {
|
||||
last: true,
|
||||
});
|
||||
return soFarGood && (!found || owned[found.key] === true);
|
||||
}, true);
|
||||
}
|
||||
});
|
||||
if (typeof user.markModified === "function") {
|
||||
user.markModified('achievements.ultimateGearSets');
|
||||
}
|
||||
|
||||
// TODO
|
||||
if (user.markModified) user.markModified('achievements.ultimateGearSets');
|
||||
|
||||
if (_.contains(user.achievements.ultimateGearSets, true) && user.flags.armoireEnabled !== true) {
|
||||
user.flags.armoireEnabled = true;
|
||||
return typeof user.markModified === "function" ? user.markModified('flags') : void 0;
|
||||
}
|
||||
|
||||
return;
|
||||
};
|
||||
|
||||
@@ -3,117 +3,133 @@ import i18n from '../i18n';
|
||||
import _ from 'lodash';
|
||||
import count from '../count';
|
||||
import splitWhitespace from '../libs/splitWhitespace';
|
||||
import {
|
||||
BadRequest,
|
||||
NotAuthorized,
|
||||
NotFound,
|
||||
} from '../libs/errors';
|
||||
import predictableRandom from '../fns/predictableRandom';
|
||||
import randomVal from '../fns/randomVal';
|
||||
import handleTwoHanded from '../fns/handleTwoHanded';
|
||||
import ultimateGear from '../fns/ultimateGear';
|
||||
|
||||
module.exports = function(user, req, cb, analytics) {
|
||||
var analyticsData, armoireExp, armoireResp, armoireResult, base, buyResp, drop, eligibleEquipment, item, key, message, name;
|
||||
key = req.params.key;
|
||||
item = key === 'potion' ? content.potion : key === 'armoire' ? content.armoire : content.gear.flat[key];
|
||||
if (!item) {
|
||||
return typeof cb === "function" ? cb({
|
||||
code: 404,
|
||||
message: "Item '" + key + " not found (see https://github.com/HabitRPG/habitrpg/blob/develop/common/script/content/index.js)"
|
||||
}) : void 0;
|
||||
module.exports = function buy (user, req = {}, analytics) {
|
||||
let key = _.get(req, 'params.key');
|
||||
if (!key) throw new BadRequest(i18n.t('missingKeyParam', req.language));
|
||||
|
||||
let item;
|
||||
if (key === 'potion') {
|
||||
item = content.potion;
|
||||
} else if (key === 'armoire') {
|
||||
item = content.armoire;
|
||||
} else {
|
||||
item = content.gear.flat[key];
|
||||
}
|
||||
if (!item) throw new NotFound(i18n.t('itemNotFound', {key}, req.language));
|
||||
|
||||
if (user.stats.gp < item.value) {
|
||||
return typeof cb === "function" ? cb({
|
||||
code: 401,
|
||||
message: i18n.t('messageNotEnoughGold', req.language)
|
||||
}) : void 0;
|
||||
throw new NotAuthorized(i18n.t('messageNotEnoughGold', req.language));
|
||||
}
|
||||
if ((item.canOwn != null) && !item.canOwn(user)) {
|
||||
return typeof cb === "function" ? cb({
|
||||
code: 401,
|
||||
message: "You can't buy this item"
|
||||
}) : void 0;
|
||||
|
||||
if (item.canOwn && !item.canOwn(user)) {
|
||||
throw new NotAuthorized(i18n.t('cannoyBuyItem', req.language));
|
||||
}
|
||||
armoireResp = void 0;
|
||||
|
||||
let armoireResp;
|
||||
let armoireResult;
|
||||
let eligibleEquipment;
|
||||
let drop;
|
||||
let message;
|
||||
|
||||
if (item.key === 'potion') {
|
||||
user.stats.hp += 15;
|
||||
if (user.stats.hp > 50) {
|
||||
user.stats.hp = 50;
|
||||
}
|
||||
} else if (item.key === 'armoire') {
|
||||
armoireResult = user.fns.predictableRandom(user.stats.gp);
|
||||
eligibleEquipment = _.filter(content.gear.flat, (function(i) {
|
||||
return i.klass === 'armoire' && !user.items.gear.owned[i.key];
|
||||
}));
|
||||
if (!_.isEmpty(eligibleEquipment) && (armoireResult < .6 || !user.flags.armoireOpened)) {
|
||||
armoireResult = predictableRandom(user, user.stats.gp);
|
||||
eligibleEquipment = _.filter(content.gear.flat, (eligible) => {
|
||||
return eligible.klass === 'armoire' && !user.items.gear.owned[eligible.key];
|
||||
});
|
||||
|
||||
if (!_.isEmpty(eligibleEquipment) && (armoireResult < 0.6 || !user.flags.armoireOpened)) {
|
||||
eligibleEquipment.sort();
|
||||
drop = user.fns.randomVal(eligibleEquipment);
|
||||
drop = randomVal(user, eligibleEquipment);
|
||||
|
||||
user.items.gear.owned[drop.key] = true;
|
||||
user.flags.armoireOpened = true;
|
||||
message = i18n.t('armoireEquipment', {
|
||||
image: '<span class="shop_' + drop.key + ' pull-left"></span>',
|
||||
dropText: drop.text(req.language)
|
||||
image: `<span class="shop_${drop.key} pull-left"></span>`,
|
||||
dropText: drop.text(req.language),
|
||||
}, req.language);
|
||||
|
||||
if (count.remainingGearInSet(user.items.gear.owned, 'armoire') === 0) {
|
||||
user.flags.armoireEmpty = true;
|
||||
}
|
||||
|
||||
armoireResp = {
|
||||
type: "gear",
|
||||
type: 'gear',
|
||||
dropKey: drop.key,
|
||||
dropText: drop.text(req.language)
|
||||
dropText: drop.text(req.language),
|
||||
};
|
||||
} else if ((!_.isEmpty(eligibleEquipment) && armoireResult < .8) || armoireResult < .5) {
|
||||
drop = user.fns.randomVal(_.where(content.food, {
|
||||
canDrop: true
|
||||
} else if ((!_.isEmpty(eligibleEquipment) && armoireResult < 0.8) || armoireResult < 0.5) { // eslint-disable-line no-extra-parens
|
||||
drop = randomVal(_.where(content.food, {
|
||||
canDrop: true,
|
||||
}));
|
||||
if ((base = user.items.food)[name = drop.key] == null) {
|
||||
base[name] = 0;
|
||||
}
|
||||
user.items.food[drop.key] = user.items.food[drop.key] || 0;
|
||||
user.items.food[drop.key] += 1;
|
||||
|
||||
message = i18n.t('armoireFood', {
|
||||
image: '<span class="Pet_Food_' + drop.key + ' pull-left"></span>',
|
||||
image: `<span class="Pet_Food_${drop.key} pull-left"></span>`,
|
||||
dropArticle: drop.article,
|
||||
dropText: drop.text(req.language)
|
||||
dropText: drop.text(req.language),
|
||||
}, req.language);
|
||||
armoireResp = {
|
||||
type: "food",
|
||||
type: 'food',
|
||||
dropKey: drop.key,
|
||||
dropArticle: drop.article,
|
||||
dropText: drop.text(req.language)
|
||||
dropText: drop.text(req.language),
|
||||
};
|
||||
} else {
|
||||
armoireExp = Math.floor(user.fns.predictableRandom(user.stats.exp) * 40 + 10);
|
||||
let armoireExp = Math.floor(predictableRandom(user, user.stats.exp) * 40 + 10);
|
||||
user.stats.exp += armoireExp;
|
||||
message = i18n.t('armoireExp', req.language);
|
||||
armoireResp = {
|
||||
"type": "experience",
|
||||
"value": armoireExp
|
||||
type: 'experience',
|
||||
value: armoireExp,
|
||||
};
|
||||
}
|
||||
} else {
|
||||
if (user.preferences.autoEquip) {
|
||||
user.items.gear.equipped[item.type] = item.key;
|
||||
message = user.fns.handleTwoHanded(item, null, req);
|
||||
message = handleTwoHanded(user, item, null, req);
|
||||
}
|
||||
user.items.gear.owned[item.key] = true;
|
||||
if (message == null) {
|
||||
|
||||
if (!message) {
|
||||
message = i18n.t('messageBought', {
|
||||
itemText: item.text(req.language)
|
||||
itemText: item.text(req.language),
|
||||
}, req.language);
|
||||
}
|
||||
if (item.last) {
|
||||
user.fns.ultimateGear();
|
||||
}
|
||||
if (item.last) ultimateGear(user);
|
||||
}
|
||||
|
||||
user.stats.gp -= item.value;
|
||||
analyticsData = {
|
||||
uuid: user._id,
|
||||
itemKey: key,
|
||||
acquireMethod: 'Gold',
|
||||
goldCost: item.value,
|
||||
category: 'behavior'
|
||||
if (analytics) {
|
||||
analytics.track('acquire item', {
|
||||
uuid: user._id,
|
||||
itemKey: key,
|
||||
acquireMethod: 'Gold',
|
||||
goldCost: item.value,
|
||||
category: 'behavior',
|
||||
});
|
||||
}
|
||||
|
||||
let buyResp = _.pick(user, splitWhitespace('items achievements stats flags'));
|
||||
if (armoireResp) buyResp.armoire = armoireResp;
|
||||
|
||||
return {
|
||||
data: buyResp,
|
||||
message,
|
||||
};
|
||||
if (analytics != null) {
|
||||
analytics.track('acquire item', analyticsData);
|
||||
}
|
||||
buyResp = _.pick(user, splitWhitespace('items achievements stats flags'));
|
||||
if (armoireResp) {
|
||||
buyResp["armoire"] = armoireResp;
|
||||
}
|
||||
return typeof cb === "function" ? cb({
|
||||
code: 200,
|
||||
message: message
|
||||
}, buyResp) : void 0;
|
||||
};
|
||||
|
||||
@@ -2,42 +2,48 @@ import i18n from '../i18n';
|
||||
import content from '../content/index';
|
||||
import _ from 'lodash';
|
||||
import splitWhitespace from '../libs/splitWhitespace';
|
||||
import {
|
||||
BadRequest,
|
||||
NotAuthorized,
|
||||
NotFound,
|
||||
} from '../libs/errors';
|
||||
|
||||
module.exports = function buyMysterySet (user, req = {}, analytics) {
|
||||
let key = _.get(req, 'params.key');
|
||||
if (!key) throw new BadRequest(i18n.t('missingKeyParam', req.language));
|
||||
|
||||
module.exports = function(user, req, cb, analytics) {
|
||||
var mysterySet, ref;
|
||||
if (!(user.purchased.plan.consecutive.trinkets > 0)) {
|
||||
return typeof cb === "function" ? cb({
|
||||
code: 401,
|
||||
message: i18n.t('notEnoughHourglasses', req.language)
|
||||
}) : void 0;
|
||||
}
|
||||
mysterySet = (ref = content.timeTravelerStore(user.items.gear.owned)) != null ? ref[req.params.key] : void 0;
|
||||
if ((typeof window !== "undefined" && window !== null ? window.confirm : void 0) != null) {
|
||||
if (!window.confirm(i18n.t('hourglassBuyEquipSetConfirm'))) {
|
||||
return;
|
||||
}
|
||||
throw new NotAuthorized(i18n.t('notEnoughHourglasses', req.language));
|
||||
}
|
||||
|
||||
let ref = content.timeTravelerStore(user.items.gear.owned);
|
||||
let mysterySet = ref ? ref[key] : undefined;
|
||||
|
||||
if (!mysterySet) {
|
||||
return typeof cb === "function" ? cb({
|
||||
code: 404,
|
||||
message: "Mystery set not found, or set already owned"
|
||||
}) : void 0;
|
||||
throw new NotFound(i18n.t('mysterySetNotFound', req.language));
|
||||
}
|
||||
_.each(mysterySet.items, function(i) {
|
||||
var analyticsData;
|
||||
user.items.gear.owned[i.key] = true;
|
||||
analyticsData = {
|
||||
uuid: user._id,
|
||||
itemKey: i.key,
|
||||
itemType: 'Subscriber Gear',
|
||||
acquireMethod: 'Hourglass',
|
||||
category: 'behavior'
|
||||
};
|
||||
return analytics != null ? analytics.track('acquire item', analyticsData) : void 0;
|
||||
|
||||
if (window && window.confirm) { // TODO move to client
|
||||
if (!window.confirm(i18n.t('hourglassBuyEquipSetConfirm'))) return;
|
||||
}
|
||||
|
||||
_.each(mysterySet.items, item => {
|
||||
user.items.gear.owned[item.key] = true;
|
||||
if (analytics) {
|
||||
analytics.track('acquire item', {
|
||||
uuid: user._id,
|
||||
itemKey: item.key,
|
||||
itemType: 'Subscriber Gear',
|
||||
acquireMethod: 'Hourglass',
|
||||
category: 'behavior',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
user.purchased.plan.consecutive.trinkets--;
|
||||
return typeof cb === "function" ? cb({
|
||||
code: 200,
|
||||
message: i18n.t('hourglassPurchaseSet', req.language)
|
||||
}, _.pick(user, splitWhitespace('items purchased.plan.consecutive'))) : void 0;
|
||||
|
||||
return {
|
||||
data: _.pick(user, splitWhitespace('items purchased.plan.consecutive')),
|
||||
message: i18n.t('hourglassPurchaseSet', req.language),
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,49 +1,44 @@
|
||||
import i18n from '../i18n';
|
||||
import content from '../content/index';
|
||||
import {
|
||||
BadRequest,
|
||||
NotAuthorized,
|
||||
NotFound,
|
||||
} from '../libs/errors';
|
||||
import _ from 'lodash';
|
||||
module.exports = function buyQuest (user, req = {}, analytics) {
|
||||
let key = _.get(req, 'params.key');
|
||||
if (!key) throw new BadRequest(i18n.t('missingKeyParam', req.language));
|
||||
|
||||
let item = content.quests[key];
|
||||
if (!item) throw new NotFound(i18n.t('questNotFound', req.language));
|
||||
|
||||
module.exports = function(user, req, cb, analytics) {
|
||||
var analyticsData, base, item, key, message, name;
|
||||
key = req.params.key;
|
||||
item = content.quests[key];
|
||||
if (!item) {
|
||||
return typeof cb === "function" ? cb({
|
||||
code: 404,
|
||||
message: "Quest '" + key + " not found (see https://github.com/HabitRPG/habitrpg/blob/develop/common/script/content/index.js)"
|
||||
}) : void 0;
|
||||
}
|
||||
if (!(item.category === 'gold' && item.goldValue)) {
|
||||
return typeof cb === "function" ? cb({
|
||||
code: 404,
|
||||
message: "Quest '" + key + " is not a Gold-purchasable quest (see https://github.com/HabitRPG/habitrpg/blob/develop/common/script/content/index.js)"
|
||||
}) : void 0;
|
||||
throw new NotAuthorized(i18n.t('questNotGoldPurchasable', {key}, req.language));
|
||||
}
|
||||
if (user.stats.gp < item.goldValue) {
|
||||
return typeof cb === "function" ? cb({
|
||||
code: 401,
|
||||
message: i18n.t('messageNotEnoughGold', req.language)
|
||||
}) : void 0;
|
||||
throw new NotAuthorized(i18n.t('messageNotEnoughGold', req.language));
|
||||
}
|
||||
message = i18n.t('messageBought', {
|
||||
itemText: item.text(req.language)
|
||||
}, req.language);
|
||||
if ((base = user.items.quests)[name = item.key] == null) {
|
||||
base[name] = 0;
|
||||
}
|
||||
user.items.quests[item.key] += 1;
|
||||
|
||||
user.items.quests[item.key] = user.items.quests[item.key] || 0;
|
||||
user.items.quests[item.key]++;
|
||||
user.stats.gp -= item.goldValue;
|
||||
analyticsData = {
|
||||
uuid: user._id,
|
||||
itemKey: item.key,
|
||||
itemType: 'Market',
|
||||
goldCost: item.goldValue,
|
||||
acquireMethod: 'Gold',
|
||||
category: 'behavior'
|
||||
};
|
||||
if (analytics != null) {
|
||||
analytics.track('acquire item', analyticsData);
|
||||
|
||||
if (analytics) {
|
||||
analytics.track('acquire item', {
|
||||
uuid: user._id,
|
||||
itemKey: item.key,
|
||||
itemType: 'Market',
|
||||
goldCost: item.goldValue,
|
||||
acquireMethod: 'Gold',
|
||||
category: 'behavior',
|
||||
});
|
||||
}
|
||||
return typeof cb === "function" ? cb({
|
||||
code: 200,
|
||||
message: message
|
||||
}, user.items.quests) : void 0;
|
||||
|
||||
return {
|
||||
data: user.items.quests,
|
||||
message: i18n.t('messageBought', {
|
||||
itemText: item.text(req.language),
|
||||
}, req.language),
|
||||
};
|
||||
};
|
||||
|
||||
@@ -2,30 +2,30 @@ import i18n from '../i18n';
|
||||
import content from '../content/index';
|
||||
import _ from 'lodash';
|
||||
import splitWhitespace from '../libs/splitWhitespace';
|
||||
import {
|
||||
BadRequest,
|
||||
NotAuthorized,
|
||||
NotFound,
|
||||
} from '../libs/errors';
|
||||
|
||||
module.exports = function buySpecialSpell (user, req = {}) {
|
||||
let key = _.get(req, 'params.key');
|
||||
if (!key) throw new BadRequest(i18n.t('missingKeyParam', req.language));
|
||||
|
||||
let item = content.special[key];
|
||||
if (!item) throw new NotFound(i18n.t('spellNotFound', {spellId: key}, req.language));
|
||||
|
||||
module.exports = function(user, req, cb) {
|
||||
var base, item, key, message;
|
||||
key = req.params.key;
|
||||
item = content.special[key];
|
||||
if (user.stats.gp < item.value) {
|
||||
return typeof cb === "function" ? cb({
|
||||
code: 401,
|
||||
message: i18n.t('messageNotEnoughGold', req.language)
|
||||
}) : void 0;
|
||||
throw new NotAuthorized(i18n.t('messageNotEnoughGold', req.language));
|
||||
}
|
||||
user.stats.gp -= item.value;
|
||||
if ((base = user.items.special)[key] == null) {
|
||||
base[key] = 0;
|
||||
}
|
||||
|
||||
user.items.special[key]++;
|
||||
if (typeof user.markModified === "function") {
|
||||
user.markModified('items.special');
|
||||
}
|
||||
message = i18n.t('messageBought', {
|
||||
itemText: item.text(req.language)
|
||||
}, req.language);
|
||||
return typeof cb === "function" ? cb({
|
||||
code: 200,
|
||||
message: message
|
||||
}, _.pick(user, splitWhitespace('items stats'))) : void 0;
|
||||
|
||||
return {
|
||||
data: _.pick(user, splitWhitespace('items stats')),
|
||||
message: i18n.t('messageBought', {
|
||||
itemText: item.text(req.language),
|
||||
}, req.language),
|
||||
};
|
||||
};
|
||||
|
||||
@@ -21,10 +21,6 @@ const COMMON_FILES = [
|
||||
'!./common/script/ops/addWebhook.js',
|
||||
'!./common/script/ops/allocateNow.js',
|
||||
'!./common/script/ops/blockUser.js',
|
||||
'!./common/script/ops/buy.js',
|
||||
'!./common/script/ops/buyMysterySet.js',
|
||||
'!./common/script/ops/buyQuest.js',
|
||||
'!./common/script/ops/buySpecialSpell.js',
|
||||
'!./common/script/ops/changeClass.js',
|
||||
'!./common/script/ops/clearCompleted.js',
|
||||
'!./common/script/ops/clearPMs.js',
|
||||
@@ -63,13 +59,9 @@ const COMMON_FILES = [
|
||||
'!./common/script/fns/dotGet.js',
|
||||
'!./common/script/fns/dotSet.js',
|
||||
'!./common/script/fns/getItem.js',
|
||||
'!./common/script/fns/handleTwoHanded.js',
|
||||
'!./common/script/fns/nullify.js',
|
||||
'!./common/script/fns/predictableRandom.js',
|
||||
'!./common/script/fns/preenUserHistory.js',
|
||||
'!./common/script/fns/randomDrop.js',
|
||||
'!./common/script/fns/randomVal.js',
|
||||
'!./common/script/fns/ultimateGear.js',
|
||||
'!./common/script/fns/updateStats.js',
|
||||
'!./common/script/libs/appliedTags.js',
|
||||
'!./common/script/libs/countExists.js',
|
||||
|
||||
@@ -263,15 +263,15 @@ export let schema = new Schema({
|
||||
spookDust: {type: Number, default: 0},
|
||||
shinySeed: {type: Number, default: 0},
|
||||
seafoam: {type: Number, default: 0},
|
||||
valentine: Number,
|
||||
valentine: {type: Number, default: 0},
|
||||
valentineReceived: Array, // array of strings, by sender name
|
||||
nye: Number,
|
||||
nye: {type: Number, default: 0},
|
||||
nyeReceived: Array,
|
||||
greeting: Number,
|
||||
greeting: {type: Number, default: 0},
|
||||
greetingReceived: Array,
|
||||
thankyou: Number,
|
||||
thankyou: {type: Number, default: 0},
|
||||
thankyouReceived: Array,
|
||||
birthday: Number,
|
||||
birthday: {type: Number, default: 0},
|
||||
birthdayReceived: Array,
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user