mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-17 14:47:53 +01:00
Separated out buy functions into buyGear, buyArmoire, and buyPotion (#7065)
This commit is contained in:
committed by
Matteo Pagliazzi
parent
f44dbbbd71
commit
9e3d8ba4ac
@@ -113,6 +113,9 @@ import scoreTask from './ops/scoreTask';
|
||||
import sleep from './ops/sleep';
|
||||
import allocate from './ops/allocate';
|
||||
import buy from './ops/buy';
|
||||
import buyGear from './ops/buyGear';
|
||||
import buyPotion from './ops/buyPotion';
|
||||
import buyArmoire from './ops/buyArmoire';
|
||||
import buyMysterySet from './ops/buyMysterySet';
|
||||
import buyQuest from './ops/buyQuest';
|
||||
import buySpecialSpell from './ops/buySpecialSpell';
|
||||
@@ -150,6 +153,9 @@ api.ops = {
|
||||
sleep,
|
||||
allocate,
|
||||
buy,
|
||||
buyGear,
|
||||
buyPotion,
|
||||
buyArmoire,
|
||||
buyMysterySet,
|
||||
buySpecialSpell,
|
||||
buyQuest,
|
||||
@@ -266,6 +272,9 @@ api.wrap = function wrapUser (user, main = true) {
|
||||
releaseMounts: _.partial(importedOps.releaseMounts, user),
|
||||
releaseBoth: _.partial(importedOps.releaseBoth, user),
|
||||
buy: _.partial(importedOps.buy, user),
|
||||
buyPotion: _.partial(importedOps.buyPotion, user),
|
||||
buyArmoire: _.partial(importedOps.buyArmoire, user),
|
||||
buyGear: _.partial(importedOps.buyGear, user),
|
||||
buyQuest: _.partial(importedOps.buyQuest, user),
|
||||
buyMysterySet: _.partial(importedOps.buyMysterySet, user),
|
||||
hourglassPurchase: _.partial(importedOps.hourglassPurchase, user),
|
||||
|
||||
@@ -1,142 +1,24 @@
|
||||
import content from '../content/index';
|
||||
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';
|
||||
import buyPotion from './buyPotion';
|
||||
import buyArmoire from './buyArmoire';
|
||||
import buyGear from './buyGear';
|
||||
|
||||
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;
|
||||
let buyRes;
|
||||
if (key === 'potion') {
|
||||
item = content.potion;
|
||||
buyRes = buyPotion(user, req, analytics);
|
||||
} else if (key === 'armoire') {
|
||||
item = content.armoire;
|
||||
buyRes = buyArmoire(user, req, analytics);
|
||||
} else {
|
||||
item = content.gear.flat[key];
|
||||
}
|
||||
if (!item) throw new NotFound(i18n.t('itemNotFound', {key}, req.language));
|
||||
|
||||
if (user.stats.gp < item.value) {
|
||||
throw new NotAuthorized(i18n.t('messageNotEnoughGold', req.language));
|
||||
buyRes = buyGear(user, req, analytics);
|
||||
}
|
||||
|
||||
if (item.canOwn && !item.canOwn(user)) {
|
||||
throw new NotAuthorized(i18n.t('cannoyBuyItem', req.language));
|
||||
}
|
||||
|
||||
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 = 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 = 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),
|
||||
}, req.language);
|
||||
|
||||
if (count.remainingGearInSet(user.items.gear.owned, 'armoire') === 0) {
|
||||
user.flags.armoireEmpty = true;
|
||||
}
|
||||
|
||||
armoireResp = {
|
||||
type: 'gear',
|
||||
dropKey: drop.key,
|
||||
dropText: drop.text(req.language),
|
||||
};
|
||||
} else if ((!_.isEmpty(eligibleEquipment) && armoireResult < 0.8) || armoireResult < 0.5) { // eslint-disable-line no-extra-parens
|
||||
drop = randomVal(user, _.where(content.food, {
|
||||
canDrop: true,
|
||||
}));
|
||||
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>`,
|
||||
dropArticle: drop.article,
|
||||
dropText: drop.text(req.language),
|
||||
}, req.language);
|
||||
armoireResp = {
|
||||
type: 'food',
|
||||
dropKey: drop.key,
|
||||
dropArticle: drop.article,
|
||||
dropText: drop.text(req.language),
|
||||
};
|
||||
} else {
|
||||
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,
|
||||
};
|
||||
}
|
||||
} else {
|
||||
if (user.preferences.autoEquip) {
|
||||
user.items.gear.equipped[item.type] = item.key;
|
||||
message = handleTwoHanded(user, item, undefined, req);
|
||||
}
|
||||
user.items.gear.owned[item.key] = true;
|
||||
|
||||
if (item.last) ultimateGear(user);
|
||||
}
|
||||
|
||||
user.stats.gp -= item.value;
|
||||
|
||||
if (!message) {
|
||||
message = i18n.t('messageBought', {
|
||||
itemText: item.text(req.language),
|
||||
}, req.language);
|
||||
}
|
||||
|
||||
if (analytics) {
|
||||
analytics.track('acquire item', {
|
||||
uuid: user._id,
|
||||
itemKey: key,
|
||||
acquireMethod: 'Gold',
|
||||
goldCost: item.value,
|
||||
category: 'behavior',
|
||||
});
|
||||
}
|
||||
|
||||
let res = {
|
||||
data: _.pick(user, splitWhitespace('items achievements stats flags')),
|
||||
message,
|
||||
};
|
||||
|
||||
if (armoireResp) res.armoire = armoireResp;
|
||||
|
||||
if (req.v2 === true) {
|
||||
return res.data;
|
||||
} else {
|
||||
return res;
|
||||
}
|
||||
return buyRes;
|
||||
};
|
||||
|
||||
116
common/script/ops/buyArmoire.js
Normal file
116
common/script/ops/buyArmoire.js
Normal file
@@ -0,0 +1,116 @@
|
||||
import content from '../content/index';
|
||||
import i18n from '../i18n';
|
||||
import _ from 'lodash';
|
||||
import count from '../count';
|
||||
import splitWhitespace from '../libs/splitWhitespace';
|
||||
import {
|
||||
NotAuthorized,
|
||||
} from '../libs/errors';
|
||||
import predictableRandom from '../fns/predictableRandom';
|
||||
import randomVal from '../fns/randomVal';
|
||||
|
||||
module.exports = function buyArmoire (user, req = {}, analytics) {
|
||||
let item = content.armoire;
|
||||
|
||||
if (user.stats.gp < item.value) {
|
||||
throw new NotAuthorized(i18n.t('messageNotEnoughGold', req.language));
|
||||
}
|
||||
|
||||
if (item.canOwn && !item.canOwn(user)) {
|
||||
throw new NotAuthorized(i18n.t('cannotBuyItem', req.language));
|
||||
}
|
||||
|
||||
let armoireResp;
|
||||
let armoireResult;
|
||||
let eligibleEquipment;
|
||||
let drop;
|
||||
let message;
|
||||
|
||||
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 = randomVal(user, eligibleEquipment);
|
||||
|
||||
if (user.items.gear.owned[drop.key]) {
|
||||
throw new NotAuthorized(i18n.t('equipmentAlradyOwned', req.language));
|
||||
}
|
||||
|
||||
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),
|
||||
}, req.language);
|
||||
|
||||
if (count.remainingGearInSet(user.items.gear.owned, 'armoire') === 0) {
|
||||
user.flags.armoireEmpty = true;
|
||||
}
|
||||
|
||||
armoireResp = {
|
||||
type: 'gear',
|
||||
dropKey: drop.key,
|
||||
dropText: drop.text(req.language),
|
||||
};
|
||||
} else if ((!_.isEmpty(eligibleEquipment) && armoireResult < 0.8) || armoireResult < 0.5) { // eslint-disable-line no-extra-parens
|
||||
drop = randomVal(user, _.where(content.food, {
|
||||
canDrop: true,
|
||||
}));
|
||||
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>`,
|
||||
dropArticle: drop.article,
|
||||
dropText: drop.text(req.language),
|
||||
}, req.language);
|
||||
armoireResp = {
|
||||
type: 'food',
|
||||
dropKey: drop.key,
|
||||
dropArticle: drop.article,
|
||||
dropText: drop.text(req.language),
|
||||
};
|
||||
} else {
|
||||
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,
|
||||
};
|
||||
}
|
||||
|
||||
user.stats.gp -= item.value;
|
||||
|
||||
if (!message) {
|
||||
message = i18n.t('messageBought', {
|
||||
itemText: item.text(req.language),
|
||||
}, req.language);
|
||||
}
|
||||
|
||||
if (analytics) {
|
||||
analytics.track('acquire item', {
|
||||
uuid: user._id,
|
||||
itemKey: 'Armoire',
|
||||
acquireMethod: 'Gold',
|
||||
goldCost: item.value,
|
||||
category: 'behavior',
|
||||
});
|
||||
}
|
||||
|
||||
let res = {
|
||||
data: _.pick(user, splitWhitespace('items flags')),
|
||||
message,
|
||||
};
|
||||
|
||||
if (armoireResp) res.armoire = armoireResp;
|
||||
|
||||
if (req.v2 === true) {
|
||||
return res.data;
|
||||
} else {
|
||||
return res;
|
||||
}
|
||||
};
|
||||
72
common/script/ops/buyGear.js
Normal file
72
common/script/ops/buyGear.js
Normal file
@@ -0,0 +1,72 @@
|
||||
import content from '../content/index';
|
||||
import i18n from '../i18n';
|
||||
import _ from 'lodash';
|
||||
import splitWhitespace from '../libs/splitWhitespace';
|
||||
import {
|
||||
BadRequest,
|
||||
NotAuthorized,
|
||||
NotFound,
|
||||
} from '../libs/errors';
|
||||
import handleTwoHanded from '../fns/handleTwoHanded';
|
||||
import ultimateGear from '../fns/ultimateGear';
|
||||
|
||||
module.exports = function buyGear (user, req = {}, analytics) {
|
||||
let key = _.get(req, 'params.key');
|
||||
if (!key) throw new BadRequest(i18n.t('missingKeyParam', req.language));
|
||||
|
||||
let item = content.gear.flat[key];
|
||||
|
||||
if (!item) throw new NotFound(i18n.t('itemNotFound', {key}, req.language));
|
||||
|
||||
if (user.stats.gp < item.value) {
|
||||
throw new NotAuthorized(i18n.t('messageNotEnoughGold', req.language));
|
||||
}
|
||||
|
||||
if (item.canOwn && !item.canOwn(user)) {
|
||||
throw new NotAuthorized(i18n.t('cannotBuyItem', req.language));
|
||||
}
|
||||
|
||||
let message;
|
||||
|
||||
if (user.items.gear.owned[item.key]) {
|
||||
throw new NotAuthorized(i18n.t('equipmentAlreadyOwned', req.language));
|
||||
}
|
||||
|
||||
if (user.preferences.autoEquip) {
|
||||
user.items.gear.equipped[item.type] = item.key;
|
||||
message = handleTwoHanded(user, item, undefined, req);
|
||||
}
|
||||
|
||||
user.items.gear.owned[item.key] = true;
|
||||
|
||||
if (item.last) ultimateGear(user);
|
||||
|
||||
user.stats.gp -= item.value;
|
||||
|
||||
if (!message) {
|
||||
message = i18n.t('messageBought', {
|
||||
itemText: item.text(req.language),
|
||||
}, req.language);
|
||||
}
|
||||
|
||||
if (analytics) {
|
||||
analytics.track('acquire item', {
|
||||
uuid: user._id,
|
||||
itemKey: key,
|
||||
acquireMethod: 'Gold',
|
||||
goldCost: item.value,
|
||||
category: 'behavior',
|
||||
});
|
||||
}
|
||||
|
||||
let res = {
|
||||
data: _.pick(user, splitWhitespace('items achievements stats flags')),
|
||||
message,
|
||||
};
|
||||
|
||||
if (req.v2 === true) {
|
||||
return res.data;
|
||||
} else {
|
||||
return res;
|
||||
}
|
||||
};
|
||||
52
common/script/ops/buyPotion.js
Normal file
52
common/script/ops/buyPotion.js
Normal file
@@ -0,0 +1,52 @@
|
||||
import content from '../content/index';
|
||||
import i18n from '../i18n';
|
||||
import _ from 'lodash';
|
||||
import splitWhitespace from '../libs/splitWhitespace';
|
||||
import {
|
||||
NotAuthorized,
|
||||
} from '../libs/errors';
|
||||
|
||||
module.exports = function buyPotion (user, req = {}, analytics) {
|
||||
let item = content.potion;
|
||||
|
||||
if (user.stats.gp < item.value) {
|
||||
throw new NotAuthorized(i18n.t('messageNotEnoughGold', req.language));
|
||||
}
|
||||
|
||||
if (item.canOwn && !item.canOwn(user)) {
|
||||
throw new NotAuthorized(i18n.t('cannotBuyItem', req.language));
|
||||
}
|
||||
|
||||
user.stats.hp += 15;
|
||||
if (user.stats.hp > 50) {
|
||||
user.stats.hp = 50;
|
||||
}
|
||||
|
||||
user.stats.gp -= item.value;
|
||||
|
||||
let message = i18n.t('messageBought', {
|
||||
itemText: item.text(req.language),
|
||||
}, req.language);
|
||||
|
||||
|
||||
if (analytics) {
|
||||
analytics.track('acquire item', {
|
||||
uuid: user._id,
|
||||
itemKey: 'Potion',
|
||||
acquireMethod: 'Gold',
|
||||
goldCost: item.value,
|
||||
category: 'behavior',
|
||||
});
|
||||
}
|
||||
|
||||
let res = {
|
||||
data: _.pick(user, splitWhitespace('stats')),
|
||||
message,
|
||||
};
|
||||
|
||||
if (req.v2 === true) {
|
||||
return res.data;
|
||||
} else {
|
||||
return res;
|
||||
}
|
||||
};
|
||||
@@ -30,6 +30,9 @@ import releasePets from './releasePets';
|
||||
import releaseMounts from './releaseMounts';
|
||||
import releaseBoth from './releaseBoth';
|
||||
import buy from './buy';
|
||||
import buyGear from './buyGear';
|
||||
import buyPotion from './buyPotion';
|
||||
import buyArmoire from './buyArmoire';
|
||||
import buyQuest from './buyQuest';
|
||||
import buyMysterySet from './buyMysterySet';
|
||||
import hourglassPurchase from './hourglassPurchase';
|
||||
@@ -77,6 +80,9 @@ module.exports = {
|
||||
releaseMounts,
|
||||
releaseBoth,
|
||||
buy,
|
||||
buyGear,
|
||||
buyPotion,
|
||||
buyArmoire,
|
||||
buyQuest,
|
||||
buyMysterySet,
|
||||
hourglassPurchase,
|
||||
|
||||
Reference in New Issue
Block a user