mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-17 14:47:53 +01:00
Merge branch 'develop' into release
This commit is contained in:
@@ -598,10 +598,20 @@ let backgrounds = {
|
||||
};
|
||||
/* eslint-enable quote-props */
|
||||
|
||||
forOwn(backgrounds, function prefillBackgroundSet (value) {
|
||||
forOwn(value, function prefillBackground (bgObject) {
|
||||
bgObject.price = 7;
|
||||
let flat = {};
|
||||
|
||||
forOwn(backgrounds, function prefillBackgroundSet (backgroundsInSet, set) {
|
||||
forOwn(backgroundsInSet, function prefillBackground (background, bgKey) {
|
||||
background.key = bgKey;
|
||||
background.set = set;
|
||||
background.price = 7;
|
||||
|
||||
flat[bgKey] = background;
|
||||
});
|
||||
});
|
||||
|
||||
module.exports = backgrounds;
|
||||
module.exports = {
|
||||
tree: backgrounds,
|
||||
flat,
|
||||
};
|
||||
|
||||
|
||||
@@ -32,6 +32,34 @@ export const EVENTS = {
|
||||
fall2017: { start: '2017-09-21', end: '2017-11-02' },
|
||||
};
|
||||
|
||||
export const SEASONAL_SETS = {
|
||||
fall: [
|
||||
// fall 2014
|
||||
'vampireSmiterSet',
|
||||
'monsterOfScienceSet',
|
||||
'witchyWizardSet',
|
||||
'mummyMedicSet',
|
||||
|
||||
// fall 2015
|
||||
'battleRogueSet',
|
||||
'scarecrowWarriorSet',
|
||||
'stitchWitchSet',
|
||||
'potionerSet',
|
||||
|
||||
// fall 2016
|
||||
'fall2016BlackWidowSet',
|
||||
'fall2016SwampThingSet',
|
||||
'fall2016WickedSorcererSet',
|
||||
'fall2016GorgonHealerSet',
|
||||
|
||||
// fall 2017
|
||||
'fall2017TrickOrTreatSet',
|
||||
'fall2017HabitoweenSet',
|
||||
'fall2017MasqueradeSet',
|
||||
'fall2017HauntedHouseSet',
|
||||
],
|
||||
};
|
||||
|
||||
export const GEAR_TYPES = [
|
||||
'weapon',
|
||||
'armor',
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -25,7 +24,7 @@ import {
|
||||
} from './quests';
|
||||
|
||||
import appearances from './appearance';
|
||||
import backgrounds from './appearance/backgrounds.js';
|
||||
import backgrounds from './appearance/backgrounds';
|
||||
import spells from './spells';
|
||||
import subscriptionBlocks from './subscriptionBlocks';
|
||||
import faq from './faq';
|
||||
@@ -33,6 +32,8 @@ import timeTravelers from './time-travelers';
|
||||
|
||||
import loginIncentives from './loginIncentives';
|
||||
|
||||
import officialPinnedItems from './officialPinnedItems';
|
||||
|
||||
api.achievements = achievements;
|
||||
|
||||
api.quests = quests;
|
||||
@@ -45,9 +46,13 @@ api.gear = gear;
|
||||
api.spells = spells;
|
||||
api.subscriptionBlocks = subscriptionBlocks;
|
||||
|
||||
api.audioThemes = ['danielTheBard', 'gokulTheme', 'luneFoxTheme', 'wattsTheme', 'rosstavoTheme', 'dewinTheme', 'airuTheme', 'beatscribeNesTheme', 'arashiTheme'];
|
||||
|
||||
api.mystery = timeTravelers.mystery;
|
||||
api.timeTravelerStore = timeTravelers.timeTravelerStore;
|
||||
|
||||
api.officialPinnedItems = officialPinnedItems;
|
||||
|
||||
/*
|
||||
---------------------------------------------------------------
|
||||
Discounted Item Bundles
|
||||
@@ -68,6 +73,7 @@ api.bundles = {
|
||||
return moment().isBetween('2017-05-16', '2017-05-31');
|
||||
},
|
||||
type: 'quests',
|
||||
class: 'quest_bundle_featheredFriends',
|
||||
value: 7,
|
||||
},
|
||||
splashyPals: {
|
||||
@@ -83,6 +89,7 @@ api.bundles = {
|
||||
return moment().isBetween('2017-07-11', '2017-08-02');
|
||||
},
|
||||
type: 'quests',
|
||||
class: 'quest_bundle_splashyPals',
|
||||
value: 7,
|
||||
},
|
||||
farmFriends: {
|
||||
@@ -127,8 +134,8 @@ api.armoire = {
|
||||
},
|
||||
value: 100,
|
||||
key: 'armoire',
|
||||
canOwn (u) {
|
||||
return includes(u.achievements.ultimateGearSets, true);
|
||||
canOwn () {
|
||||
return true;
|
||||
},
|
||||
};
|
||||
|
||||
@@ -533,7 +540,8 @@ each(api.food, (food, key) => {
|
||||
|
||||
api.appearances = appearances;
|
||||
|
||||
api.backgrounds = backgrounds;
|
||||
api.backgrounds = backgrounds.tree;
|
||||
api.backgroundsFlat = backgrounds.flat;
|
||||
|
||||
api.userDefaults = {
|
||||
habits: [
|
||||
|
||||
@@ -204,6 +204,7 @@ let mysterySets = {
|
||||
each(mysterySets, (value, key) => {
|
||||
value.key = key;
|
||||
value.text = t(`mysterySet${key}`);
|
||||
value.class = `shop_set_mystery_${key}`;
|
||||
});
|
||||
|
||||
module.exports = mysterySets;
|
||||
|
||||
4
website/common/script/content/officialPinnedItems.js
Normal file
4
website/common/script/content/officialPinnedItems.js
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
// { path: '', type: '', canShow?: (user) => boolean }
|
||||
|
||||
export default [];
|
||||
@@ -1054,6 +1054,7 @@ let quests = {
|
||||
basilist: {
|
||||
text: t('questBasilistText'),
|
||||
notes: t('questBasilistNotes'),
|
||||
group: 'questGroupEarnable',
|
||||
completion: t('questBasilistCompletion'),
|
||||
value: 4,
|
||||
category: 'unlockable',
|
||||
@@ -2224,6 +2225,7 @@ let quests = {
|
||||
dustbunnies: {
|
||||
text: t('questDustBunniesText'),
|
||||
notes: t('questDustBunniesNotes'),
|
||||
group: 'questGroupEarnable',
|
||||
completion: t('questDustBunniesCompletion'),
|
||||
value: 4,
|
||||
category: 'unlockable',
|
||||
|
||||
@@ -1,19 +1,44 @@
|
||||
const featuredItems = {
|
||||
market: [
|
||||
'head_armoire_vikingHelm',
|
||||
'weapon_special_1',
|
||||
'shield_special_0',
|
||||
'armor_warrior_5',
|
||||
],
|
||||
quests: [
|
||||
'dilatoryDistress1',
|
||||
'dilatoryDistress2',
|
||||
'dilatoryDistress3',
|
||||
],
|
||||
seasonal: 'summerMage',
|
||||
timeTravelers: [
|
||||
market: [
|
||||
{
|
||||
type: 'armoire',
|
||||
path: 'armoire',
|
||||
},
|
||||
{
|
||||
type: 'hatchingPotions',
|
||||
path: 'hatchingPotions.Golden',
|
||||
},
|
||||
{
|
||||
type: 'food',
|
||||
path: 'food.Saddle',
|
||||
},
|
||||
{
|
||||
type: 'card',
|
||||
path: 'cardTypes.greeting',
|
||||
},
|
||||
],
|
||||
quests: [
|
||||
{
|
||||
type: 'quests',
|
||||
path: 'quests.gryphon',
|
||||
},
|
||||
{
|
||||
type: 'quests',
|
||||
path: 'quests.dilatoryDistress1',
|
||||
},
|
||||
{
|
||||
type: 'quests',
|
||||
path: 'quests.nudibranch',
|
||||
},
|
||||
{
|
||||
type: 'quests',
|
||||
path: 'quests.taskwoodsTerror1',
|
||||
},
|
||||
],
|
||||
seasonal: 'summerMage',
|
||||
timeTravelers: [
|
||||
// TODO
|
||||
],
|
||||
],
|
||||
};
|
||||
|
||||
export default featuredItems;
|
||||
|
||||
@@ -2,6 +2,8 @@ import t from './translation';
|
||||
import each from 'lodash/each';
|
||||
import { NotAuthorized } from '../libs/errors';
|
||||
import statsComputed from '../libs/statsComputed';
|
||||
import crit from '../fns/crit';
|
||||
import updateStats from '../fns/updateStats';
|
||||
|
||||
/*
|
||||
---------------------------------------------------------------
|
||||
@@ -15,7 +17,7 @@ import statsComputed from '../libs/statsComputed';
|
||||
|
||||
* {cast}: the function that's run to perform the ability's action. This is pretty slick - because this is exported to the
|
||||
web, this function can be performed on the client and on the server. `user` param is self (needed for determining your
|
||||
own stats for effectiveness of cast), and `target` param is one of [task, party, user]. In the case of `self` spells,
|
||||
own stats for effectiveness of cast), and `target` param is one of [task, party, user]. In the case of `self` skills,
|
||||
you act on `user` instead of `target`. You can trust these are the correct objects, as long as the `target` attr of the
|
||||
spell is correct. Take a look at habitrpg/website/server/models/user.js and habitrpg/website/server/models/task.js for what attributes are
|
||||
available on each model. Note `task.value` is its "redness". If party is passed in, it's an array of users,
|
||||
@@ -29,8 +31,8 @@ function diminishingReturns (bonus, max, halfway) {
|
||||
return max * (bonus / (bonus + halfway));
|
||||
}
|
||||
|
||||
function calculateBonus (value, stat, crit = 1, statScale = 0.5) {
|
||||
return (value < 0 ? 1 : value + 1) + stat * statScale * crit;
|
||||
function calculateBonus (value, stat, critVal = 1, statScale = 0.5) {
|
||||
return (value < 0 ? 1 : value + 1) + stat * statScale * critVal;
|
||||
}
|
||||
|
||||
let spells = {};
|
||||
@@ -43,12 +45,12 @@ spells.wizard = {
|
||||
target: 'task',
|
||||
notes: t('spellWizardFireballNotes'),
|
||||
cast (user, target, req) {
|
||||
let bonus = statsComputed(user).int * user.fns.crit('per');
|
||||
let bonus = statsComputed(user).int * crit.crit(user, 'per');
|
||||
bonus *= Math.ceil((target.value < 0 ? 1 : target.value + 1) * 0.075);
|
||||
user.stats.exp += diminishingReturns(bonus, 75);
|
||||
if (!user.party.quest.progress.up) user.party.quest.progress.up = 0;
|
||||
user.party.quest.progress.up += Math.ceil(statsComputed(user).int * 0.1);
|
||||
user.fns.updateStats(user.stats, req);
|
||||
updateStats(user, user.stats, req);
|
||||
},
|
||||
},
|
||||
mpheal: { // Ethereal Surge
|
||||
@@ -100,7 +102,7 @@ spells.warrior = {
|
||||
target: 'task',
|
||||
notes: t('spellWarriorSmashNotes'),
|
||||
cast (user, target) {
|
||||
let bonus = statsComputed(user).str * user.fns.crit('con');
|
||||
let bonus = statsComputed(user).str * crit.crit(user, 'con');
|
||||
target.value += diminishingReturns(bonus, 2.5, 35);
|
||||
if (!user.party.quest.progress.up) user.party.quest.progress.up = 0;
|
||||
user.party.quest.progress.up += diminishingReturns(bonus, 55, 70);
|
||||
@@ -167,11 +169,11 @@ spells.rogue = {
|
||||
target: 'task',
|
||||
notes: t('spellRogueBackStabNotes'),
|
||||
cast (user, target, req) {
|
||||
let _crit = user.fns.crit('str', 0.3);
|
||||
let _crit = crit.crit(user, 'str', 0.3);
|
||||
let bonus = calculateBonus(target.value, statsComputed(user).str, _crit);
|
||||
user.stats.exp += diminishingReturns(bonus, 75, 50);
|
||||
user.stats.gp += diminishingReturns(bonus, 18, 75);
|
||||
user.fns.updateStats(user.stats, req);
|
||||
updateStats(user, user.stats, req);
|
||||
},
|
||||
},
|
||||
toolsOfTrade: { // Tools of the Trade
|
||||
|
||||
@@ -69,6 +69,7 @@ let specialPets = {
|
||||
'JackOLantern-Ghost': 'ghostJackolantern',
|
||||
'Jackalope-RoyalPurple': 'royalPurpleJackalope',
|
||||
'Orca-Base': 'orca',
|
||||
'Bear-Veteran': 'veteranBear',
|
||||
};
|
||||
|
||||
let specialMounts = {
|
||||
|
||||
Reference in New Issue
Block a user