mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-17 22:57:21 +01:00
Squashed commit of the following:
commit28193f86fbAuthor: Phillip Thelen <phillip@habitica.com> Date: Fri Jun 21 11:12:18 2024 +0200 Fix serving memoized content commit877fe48225Author: Phillip Thelen <phillip@habitica.com> Date: Thu Jun 20 12:23:24 2024 +0200 correctly memoize conent api commite0f6f79c5bAuthor: Phillip Thelen <phillip@habitica.com> Date: Thu Jun 20 10:11:27 2024 +0200 don’t build multiple times on heroku commitf62254d68eAuthor: Phillip Thelen <phillip@habitica.com> Date: Wed Jun 19 19:40:20 2024 +0200 fix client command commitd054e6fc16Author: Phillip Thelen <phillip@habitica.com> Date: Wed Jun 19 19:36:57 2024 +0200 correct build call commit7231f699c1Author: Phillip Thelen <phillip@habitica.com> Date: Wed Jun 19 19:32:32 2024 +0200 try setting up with heroku buildpack commit1dae0793fdAuthor: Phillip Thelen <phillip@habitica.com> Date: Wed Jun 19 18:50:32 2024 +0200 call gulp build:prod commitf18fbe86b6Author: Phillip Thelen <phillip@habitica.com> Date: Wed Jun 19 18:40:53 2024 +0200 build client commit61a61724caAuthor: Phillip Thelen <phillip@habitica.com> Date: Wed Jun 19 18:33:18 2024 +0200 testing commit93cf30eb18Author: Phillip Thelen <phillip@habitica.com> Date: Wed Jun 19 18:20:25 2024 +0200 integration fix commitcff08adcd0Author: Phillip Thelen <phillip@habitica.com> Date: Wed Jun 19 18:13:20 2024 +0200 specify dev docker file commit4da2ed4a1fAuthor: Phillip Thelen <phillip@habitica.com> Date: Wed Jun 19 18:10:07 2024 +0200 initialize stub commit11c5b26c59Author: Phillip Thelen <phillip@habitica.com> Date: Wed Jun 19 18:08:45 2024 +0200 test heroku file commitac85bb2e2dAuthor: Phillip Thelen <phillip@habitica.com> Date: Wed Jun 19 18:03:15 2024 +0200 fix stub reference commit74dfb2710fAuthor: Phillip Thelen <phillip@habitica.com> Date: Wed Jun 19 18:01:27 2024 +0200 test fixes commit8dbd3c3db1Author: Phillip Thelen <phillip@habitica.com> Date: Wed Jun 19 17:37:04 2024 +0200 fix canOwn test commit74b3b348ffAuthor: Phillip Thelen <phillip@habitica.com> Date: Wed Jun 19 17:32:31 2024 +0200 fix buy test commit3386d61fdeAuthor: Phillip Thelen <phillip@habitica.com> Date: Wed Jun 19 17:30:37 2024 +0200 fix debug tests commit19da14531cAuthor: Phillip Thelen <phillip@habitica.com> Date: Wed Jun 19 17:05:25 2024 +0200 add chameleon to featured quests commit254dd80f24Author: Phillip Thelen <phillip@habitica.com> Date: Wed Jun 19 17:05:14 2024 +0200 fix import commit0bc3f16b4bAuthor: Phillip Thelen <phillip@habitica.com> Date: Wed Jun 19 16:33:22 2024 +0200 add new content to new release file commit5184973bd5Author: Phillip Thelen <phillip@habitica.com> Date: Wed Jun 19 16:33:11 2024 +0200 fix release date tests commitb6accca5caAuthor: Phillip Thelen <phillip@habitica.com> Date: Wed Jun 19 16:33:06 2024 +0200 fix armoire tests commitfec68e6211Author: Phillip Thelen <phillip@habitica.com> Date: Wed Jun 19 16:02:03 2024 +0200 fix tests commitfc63c906ddAuthor: Phillip Thelen <phillip@habitica.com> Date: Mon Jun 10 14:44:21 2024 +0200 Improve test coverage commit3333f8f0f5Author: Phillip Thelen <phillip@habitica.com> Date: Mon Jun 10 14:24:59 2024 +0200 allow hatching potions to have a release date commit89a3ac3ddeAuthor: Phillip Thelen <phillip@habitica.com> Date: Mon Jun 10 14:11:38 2024 +0200 allow eggs to have a release date # Conflicts: # test/content/armoire.test.js commit16551ec83fMerge:f5f4974a732645bf6023Author: CuriousMagpie <eilatan@gmail.com> Date: Tue Jun 18 15:03:12 2024 -0400 Merge branch '2024-07-content-prebuild' into subs-private commit2645bf6023Author: CuriousMagpie <eilatan@gmail.com> Date: Tue Jun 18 15:02:47 2024 -0400 update habitica images commitf5f4974a73Author: CuriousMagpie <eilatan@gmail.com> Date: Tue Jun 18 14:58:13 2024 -0400 update habitica-images commit162e337d14Merge:f2506c323121a7d36b7bAuthor: CuriousMagpie <eilatan@gmail.com> Date: Tue Jun 18 13:46:03 2024 -0400 Merge branch '2024-07-content-prebuild' into subs-private commit21a7d36b7bAuthor: CuriousMagpie <eilatan@gmail.com> Date: Tue Jun 18 13:45:09 2024 -0400 update sprites commitf2506c3231Author: CuriousMagpie <eilatan@gmail.com> Date: Tue Jun 18 13:24:21 2024 -0400 updated sprites css commitd47641e25aAuthor: CuriousMagpie <eilatan@gmail.com> Date: Tue Jun 18 12:46:59 2024 -0400 typo fix commitfb8479ad1eAuthor: CuriousMagpie <eilatan@gmail.com> Date: Mon Jun 17 13:44:36 2024 -0400 finish July prebuild commit3810cf3ef3Author: CuriousMagpie <eilatan@gmail.com> Date: Fri Jun 14 10:42:47 2024 -0400 add chameleon quest commitd05da3722cAuthor: CuriousMagpie <eilatan@gmail.com> Date: Thu Jun 13 17:12:43 2024 -0400 add June background notes commitb8a3440ef2Author: CuriousMagpie <eilatan@gmail.com> Date: Thu Jun 13 16:40:04 2024 -0400 fix mystery item and background description commit44d63032d8Author: CuriousMagpie <eilatan@gmail.com> Date: Thu Jun 13 15:38:23 2024 -0400 add subscriber gear, enchanted armoire, and background commit9d7da91ec6Author: CuriousMagpie <eilatan@gmail.com> Date: Thu Jun 13 14:44:59 2024 -0400 add sprites
This commit is contained in:
@@ -623,6 +623,9 @@ const backgrounds = {
|
||||
backgrounds062024: {
|
||||
shell_gate: { },
|
||||
},
|
||||
backgrounds072024: {
|
||||
river_bottom: { },
|
||||
},
|
||||
eventBackgrounds: {
|
||||
birthday_bash: {
|
||||
price: 0,
|
||||
|
||||
21
website/common/script/content/constants/releaseDates.js
Normal file
21
website/common/script/content/constants/releaseDates.js
Normal file
@@ -0,0 +1,21 @@
|
||||
export const ARMOIRE_RELEASE_DATES = {
|
||||
somethingSpooky: { year: 2023, month: 10 },
|
||||
cookingImplementsTwo: { year: 2023, month: 11 },
|
||||
greenTrapper: { year: 2023, month: 12 },
|
||||
schoolUniform: { year: 2024, month: 1 },
|
||||
whiteLoungeWear: { year: 2024, month: 2 },
|
||||
hatterSet: { year: 2024, month: 3 },
|
||||
optimistSet: { year: 2024, month: 4 },
|
||||
pottersSet: { year: 2024, month: 5 },
|
||||
beachsideSet: { year: 2024, month: 6 },
|
||||
corsairSet: { year: 2024, month: 7 },
|
||||
};
|
||||
|
||||
export const EGGS_RELEASE_DATES = {
|
||||
Giraffe: { year: 2024, month: 6, day: 1 },
|
||||
Chameleon: { year: 2024, month: 7, day: 1 },
|
||||
};
|
||||
|
||||
export const HATCHING_POTIONS_RELEASE_DATES = {
|
||||
Koi: { year: 2024, month: 6, day: 1 },
|
||||
};
|
||||
@@ -377,6 +377,7 @@ export const MONTHLY_SCHEDULE = {
|
||||
'dilatory_derby',
|
||||
'armadillo',
|
||||
'guineapig',
|
||||
'chameleon',
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import assign from 'lodash/assign';
|
||||
import defaults from 'lodash/defaults';
|
||||
import each from 'lodash/each';
|
||||
import assign from 'lodash/assign';
|
||||
import t from './translation';
|
||||
import { filterReleased } from './is_released';
|
||||
import { EGGS_RELEASE_DATES } from './constants/releaseDates';
|
||||
import datedMemoize from '../fns/datedMemoize';
|
||||
|
||||
function applyEggDefaults (set, config) {
|
||||
each(set, (egg, key) => {
|
||||
@@ -396,6 +399,12 @@ const quests = {
|
||||
adjective: t('questEggGiraffeAdjective'),
|
||||
canBuy: hasQuestAchievementFunction('giraffe'),
|
||||
},
|
||||
Chameleon: {
|
||||
text: t('questEggChameleonText'),
|
||||
mountText: t('questEggChameleonMountText'),
|
||||
adjective: t('questEggChameleonAdjective'),
|
||||
canBuy: hasQuestAchievementFunction('chameleon'),
|
||||
},
|
||||
};
|
||||
|
||||
applyEggDefaults(drops, {
|
||||
@@ -410,10 +419,20 @@ applyEggDefaults(quests, {
|
||||
},
|
||||
});
|
||||
|
||||
const all = assign({}, drops, quests);
|
||||
function filterEggs (eggs) {
|
||||
return filterReleased(eggs, 'key', EGGS_RELEASE_DATES);
|
||||
}
|
||||
|
||||
export {
|
||||
drops,
|
||||
quests,
|
||||
all,
|
||||
const memoizedFilter = datedMemoize(filterEggs);
|
||||
|
||||
export default {
|
||||
get drops () {
|
||||
return memoizedFilter({ memoizeConfig: true, identifier: 'drops' }, drops);
|
||||
},
|
||||
get quests () {
|
||||
return memoizedFilter({ memoizeConfig: true, identifier: 'quests' }, quests);
|
||||
},
|
||||
get all () {
|
||||
return assign({}, this.drops, this.quests);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -2,12 +2,13 @@ import defaults from 'lodash/defaults';
|
||||
import find from 'lodash/find';
|
||||
import forEach from 'lodash/forEach';
|
||||
import moment from 'moment';
|
||||
import nconf from 'nconf';
|
||||
import upperFirst from 'lodash/upperFirst';
|
||||
import { ownsItem } from '../gear-helper';
|
||||
import { ATTRIBUTES } from '../../../constants';
|
||||
import t from '../../translation';
|
||||
import memoize from '../../../fns/datedMemoize';
|
||||
import { ARMOIRE_RELEASE_DATES as releaseDates } from '../../constants/releaseDates';
|
||||
import { buildReleaseDate } from '../../is_released';
|
||||
|
||||
const armor = {
|
||||
lunarArmor: {
|
||||
@@ -485,6 +486,10 @@ const armor = {
|
||||
con: 13,
|
||||
set: 'beachsideSet',
|
||||
},
|
||||
corsairsCoatAndCape: {
|
||||
con: 14,
|
||||
set: 'corsairSet',
|
||||
},
|
||||
};
|
||||
|
||||
const body = {
|
||||
@@ -994,6 +999,10 @@ const head = {
|
||||
int: 8,
|
||||
set: 'pottersSet',
|
||||
},
|
||||
corsairsBandana: {
|
||||
int: 7,
|
||||
set: 'corsairSet',
|
||||
},
|
||||
};
|
||||
|
||||
const shield = {
|
||||
@@ -1831,21 +1840,13 @@ const weapon = {
|
||||
per: 12,
|
||||
set: 'beachsideSet',
|
||||
},
|
||||
corsairsBlade: {
|
||||
str: 7,
|
||||
set: 'corsairSet',
|
||||
},
|
||||
};
|
||||
|
||||
const SWITCHOVER_TIME = nconf.get('CONTENT_SWITCHOVER_TIME_OFFSET') || 0;
|
||||
const releaseDay = 7;
|
||||
const releaseDates = {
|
||||
somethingSpooky: { year: 2023, month: 10 },
|
||||
cookingImplementsTwo: { year: 2023, month: 11 },
|
||||
greenTrapper: { year: 2023, month: 12 },
|
||||
schoolUniform: { year: 2024, month: 1 },
|
||||
whiteLoungeWear: { year: 2024, month: 2 },
|
||||
hatterSet: { year: 2024, month: 3 },
|
||||
optimistSet: { year: 2024, month: 4 },
|
||||
pottersSet: { year: 2024, month: 5 },
|
||||
beachsideSet: { year: 2024, month: 6 },
|
||||
};
|
||||
|
||||
forEach({
|
||||
armor,
|
||||
@@ -1890,12 +1891,12 @@ forEach({
|
||||
|
||||
function updateReleased (type) {
|
||||
const today = moment();
|
||||
const releaseDateEndPart = `${String(releaseDay).padStart(2, '0')}T${String(SWITCHOVER_TIME).padStart(2, '0')}:00-0500`;
|
||||
const returnType = {};
|
||||
forEach(type, (gearItem, gearKey) => {
|
||||
let released;
|
||||
if (releaseDates[gearItem.set]) {
|
||||
const releaseDateString = `${releaseDates[gearItem.set].year}-${String(releaseDates[gearItem.set].month).padStart(2, '0')}-${releaseDateEndPart}`;
|
||||
const components = releaseDates[gearItem.set];
|
||||
const releaseDateString = buildReleaseDate(components.year, components.month, releaseDay);
|
||||
released = today.isAfter(releaseDateString);
|
||||
} else {
|
||||
released = true;
|
||||
@@ -1931,4 +1932,16 @@ export default {
|
||||
get weapon () {
|
||||
return memoizedUpdatReleased({ identifier: 'weapon', memoizeConfig: true }, weapon);
|
||||
},
|
||||
// convenience method for tests mostly. Not used in the app
|
||||
get all () {
|
||||
const items = [];
|
||||
items.push(...Object.values(this.armor));
|
||||
items.push(...Object.values(this.body));
|
||||
items.push(...Object.values(this.eyewear));
|
||||
items.push(...Object.values(this.head));
|
||||
items.push(...Object.values(this.headAccessory));
|
||||
items.push(...Object.values(this.shield));
|
||||
items.push(...Object.values(this.weapon));
|
||||
return items;
|
||||
},
|
||||
};
|
||||
|
||||
@@ -66,6 +66,7 @@ const armor = {
|
||||
202310: { },
|
||||
202401: { },
|
||||
202406: { },
|
||||
202407: { },
|
||||
301404: { },
|
||||
301703: { },
|
||||
301704: { },
|
||||
@@ -226,6 +227,7 @@ const head = {
|
||||
202403: { },
|
||||
202404: { },
|
||||
202406: { },
|
||||
202407: { },
|
||||
301404: { },
|
||||
301405: { },
|
||||
301703: { },
|
||||
|
||||
@@ -2,6 +2,9 @@ import defaults from 'lodash/defaults';
|
||||
import each from 'lodash/each';
|
||||
import { assign } from 'lodash';
|
||||
import t from './translation';
|
||||
import datedMemoize from '../fns/datedMemoize';
|
||||
import { filterReleased } from './is_released';
|
||||
import { HATCHING_POTIONS_RELEASE_DATES } from './constants/releaseDates';
|
||||
|
||||
function hasQuestAchievementFunction (key) {
|
||||
return user => user.achievements.quests && user.achievements.quests[key] > 0;
|
||||
@@ -194,8 +197,23 @@ each(wacky, (pot, key) => {
|
||||
});
|
||||
});
|
||||
|
||||
const all = assign({}, drops, premium, wacky);
|
||||
function filterEggs (eggs) {
|
||||
return filterReleased(eggs, 'key', HATCHING_POTIONS_RELEASE_DATES);
|
||||
}
|
||||
|
||||
export {
|
||||
drops, premium, wacky, all,
|
||||
const memoizedFilter = datedMemoize(filterEggs);
|
||||
|
||||
export default {
|
||||
get drops () {
|
||||
return memoizedFilter({ memoizeConfig: true, identifier: 'drops' }, drops);
|
||||
},
|
||||
get premium () {
|
||||
return memoizedFilter({ memoizeConfig: true, identifier: 'premium' }, premium);
|
||||
},
|
||||
get wacky () {
|
||||
return memoizedFilter({ memoizeConfig: true, identifier: 'wacky' }, wacky);
|
||||
},
|
||||
get all () {
|
||||
return assign({}, this.drops, this.premium, this.wacky);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -18,9 +18,9 @@ import {
|
||||
|
||||
import achievements from './achievements';
|
||||
|
||||
import * as eggs from './eggs';
|
||||
import * as hatchingPotions from './hatching-potions';
|
||||
import * as stable from './stable';
|
||||
import eggs from './eggs';
|
||||
import hatchingPotions from './hatching-potions';
|
||||
import stable from './stable';
|
||||
import gear from './gear';
|
||||
import { quests, questsByLevel, userCanOwnQuestCategories } from './quests';
|
||||
|
||||
@@ -38,6 +38,7 @@ import { REPEATING_EVENTS, getRepeatingEvents } from './constants/events';
|
||||
import loginIncentives from './loginIncentives';
|
||||
|
||||
import officialPinnedItems from './officialPinnedItems';
|
||||
import memoize from '../fns/datedMemoize';
|
||||
|
||||
const api = {};
|
||||
|
||||
@@ -165,9 +166,18 @@ api.cardTypes = {
|
||||
|
||||
api.special = api.spells.special;
|
||||
|
||||
api.dropEggs = eggs.drops;
|
||||
api.questEggs = eggs.quests;
|
||||
api.eggs = eggs.all;
|
||||
Object.defineProperty(api, 'dropEggs', {
|
||||
get () { return eggs.drops; },
|
||||
enumerable: true,
|
||||
});
|
||||
Object.defineProperty(api, 'questEggs', {
|
||||
get () { return eggs.quests; },
|
||||
enumerable: true,
|
||||
});
|
||||
Object.defineProperty(api, 'eggs', {
|
||||
get () { return eggs.all; },
|
||||
enumerable: true,
|
||||
});
|
||||
|
||||
api.timeTravelStable = {
|
||||
pets: {
|
||||
@@ -186,298 +196,354 @@ api.timeTravelStable = {
|
||||
},
|
||||
};
|
||||
|
||||
api.dropHatchingPotions = hatchingPotions.drops;
|
||||
api.premiumHatchingPotions = hatchingPotions.premium;
|
||||
api.wackyHatchingPotions = hatchingPotions.wacky;
|
||||
api.hatchingPotions = hatchingPotions.all;
|
||||
|
||||
api.pets = stable.dropPets;
|
||||
api.premiumPets = stable.premiumPets;
|
||||
api.questPets = stable.questPets;
|
||||
api.specialPets = stable.specialPets;
|
||||
api.wackyPets = stable.wackyPets;
|
||||
api.petInfo = stable.petInfo;
|
||||
|
||||
api.mounts = stable.dropMounts;
|
||||
api.questMounts = stable.questMounts;
|
||||
api.premiumMounts = stable.premiumMounts;
|
||||
api.specialMounts = stable.specialMounts;
|
||||
api.mountInfo = stable.mountInfo;
|
||||
|
||||
api.food = {
|
||||
Meat: {
|
||||
text: t('foodMeat'),
|
||||
textA: t('foodMeatA'),
|
||||
textThe: t('foodMeatThe'),
|
||||
target: 'Base',
|
||||
},
|
||||
Milk: {
|
||||
text: t('foodMilk'),
|
||||
textA: t('foodMilkA'),
|
||||
textThe: t('foodMilkThe'),
|
||||
target: 'White',
|
||||
},
|
||||
Potatoe: {
|
||||
text: t('foodPotatoe'),
|
||||
textA: t('foodPotatoeA'),
|
||||
textThe: t('foodPotatoeThe'),
|
||||
target: 'Desert',
|
||||
},
|
||||
Strawberry: {
|
||||
text: t('foodStrawberry'),
|
||||
textA: t('foodStrawberryA'),
|
||||
textThe: t('foodStrawberryThe'),
|
||||
target: 'Red',
|
||||
},
|
||||
Chocolate: {
|
||||
text: t('foodChocolate'),
|
||||
textA: t('foodChocolateA'),
|
||||
textThe: t('foodChocolateThe'),
|
||||
target: 'Shade',
|
||||
},
|
||||
Fish: {
|
||||
text: t('foodFish'),
|
||||
textA: t('foodFishA'),
|
||||
textThe: t('foodFishThe'),
|
||||
target: 'Skeleton',
|
||||
},
|
||||
RottenMeat: {
|
||||
text: t('foodRottenMeat'),
|
||||
textA: t('foodRottenMeatA'),
|
||||
textThe: t('foodRottenMeatThe'),
|
||||
target: 'Zombie',
|
||||
},
|
||||
CottonCandyPink: {
|
||||
text: t('foodCottonCandyPink'),
|
||||
textA: t('foodCottonCandyPinkA'),
|
||||
textThe: t('foodCottonCandyPinkThe'),
|
||||
target: 'CottonCandyPink',
|
||||
},
|
||||
CottonCandyBlue: {
|
||||
text: t('foodCottonCandyBlue'),
|
||||
textA: t('foodCottonCandyBlueA'),
|
||||
textThe: t('foodCottonCandyBlueThe'),
|
||||
target: 'CottonCandyBlue',
|
||||
},
|
||||
Honey: {
|
||||
text: t('foodHoney'),
|
||||
textA: t('foodHoneyA'),
|
||||
textThe: t('foodHoneyThe'),
|
||||
target: 'Golden',
|
||||
},
|
||||
Saddle: {
|
||||
sellWarningNote: t('foodSaddleSellWarningNote'),
|
||||
text: t('foodSaddleText'),
|
||||
value: 5,
|
||||
notes: t('foodSaddleNotes'),
|
||||
canDrop: false,
|
||||
},
|
||||
/* eslint-disable camelcase */
|
||||
Cake_Skeleton: {
|
||||
text: t('foodCakeSkeleton'),
|
||||
textA: t('foodCakeSkeletonA'),
|
||||
textThe: t('foodCakeSkeletonThe'),
|
||||
target: 'Skeleton',
|
||||
},
|
||||
Cake_Base: {
|
||||
text: t('foodCakeBase'),
|
||||
textA: t('foodCakeBaseA'),
|
||||
textThe: t('foodCakeBaseThe'),
|
||||
target: 'Base',
|
||||
},
|
||||
Cake_CottonCandyBlue: {
|
||||
text: t('foodCakeCottonCandyBlue'),
|
||||
textA: t('foodCakeCottonCandyBlueA'),
|
||||
textThe: t('foodCakeCottonCandyBlueThe'),
|
||||
target: 'CottonCandyBlue',
|
||||
},
|
||||
Cake_CottonCandyPink: {
|
||||
text: t('foodCakeCottonCandyPink'),
|
||||
textA: t('foodCakeCottonCandyPinkA'),
|
||||
textThe: t('foodCakeCottonCandyPinkThe'),
|
||||
target: 'CottonCandyPink',
|
||||
},
|
||||
Cake_Shade: {
|
||||
text: t('foodCakeShade'),
|
||||
textA: t('foodCakeShadeA'),
|
||||
textThe: t('foodCakeShadeThe'),
|
||||
target: 'Shade',
|
||||
},
|
||||
Cake_White: {
|
||||
text: t('foodCakeWhite'),
|
||||
textA: t('foodCakeWhiteA'),
|
||||
textThe: t('foodCakeWhiteThe'),
|
||||
target: 'White',
|
||||
},
|
||||
Cake_Golden: {
|
||||
text: t('foodCakeGolden'),
|
||||
textA: t('foodCakeGoldenA'),
|
||||
textThe: t('foodCakeGoldenThe'),
|
||||
target: 'Golden',
|
||||
},
|
||||
Cake_Zombie: {
|
||||
text: t('foodCakeZombie'),
|
||||
textA: t('foodCakeZombieA'),
|
||||
textThe: t('foodCakeZombieThe'),
|
||||
target: 'Zombie',
|
||||
},
|
||||
Cake_Desert: {
|
||||
text: t('foodCakeDesert'),
|
||||
textA: t('foodCakeDesertA'),
|
||||
textThe: t('foodCakeDesertThe'),
|
||||
target: 'Desert',
|
||||
},
|
||||
Cake_Red: {
|
||||
text: t('foodCakeRed'),
|
||||
textA: t('foodCakeRedA'),
|
||||
textThe: t('foodCakeRedThe'),
|
||||
target: 'Red',
|
||||
},
|
||||
Candy_Skeleton: {
|
||||
text: t('foodCandySkeleton'),
|
||||
textA: t('foodCandySkeletonA'),
|
||||
textThe: t('foodCandySkeletonThe'),
|
||||
target: 'Skeleton',
|
||||
},
|
||||
Candy_Base: {
|
||||
text: t('foodCandyBase'),
|
||||
textA: t('foodCandyBaseA'),
|
||||
textThe: t('foodCandyBaseThe'),
|
||||
target: 'Base',
|
||||
},
|
||||
Candy_CottonCandyBlue: {
|
||||
text: t('foodCandyCottonCandyBlue'),
|
||||
textA: t('foodCandyCottonCandyBlueA'),
|
||||
textThe: t('foodCandyCottonCandyBlueThe'),
|
||||
target: 'CottonCandyBlue',
|
||||
},
|
||||
Candy_CottonCandyPink: {
|
||||
text: t('foodCandyCottonCandyPink'),
|
||||
textA: t('foodCandyCottonCandyPinkA'),
|
||||
textThe: t('foodCandyCottonCandyPinkThe'),
|
||||
target: 'CottonCandyPink',
|
||||
},
|
||||
Candy_Shade: {
|
||||
text: t('foodCandyShade'),
|
||||
textA: t('foodCandyShadeA'),
|
||||
textThe: t('foodCandyShadeThe'),
|
||||
target: 'Shade',
|
||||
},
|
||||
Candy_White: {
|
||||
text: t('foodCandyWhite'),
|
||||
textA: t('foodCandyWhiteA'),
|
||||
textThe: t('foodCandyWhiteThe'),
|
||||
target: 'White',
|
||||
},
|
||||
Candy_Golden: {
|
||||
text: t('foodCandyGolden'),
|
||||
textA: t('foodCandyGoldenA'),
|
||||
textThe: t('foodCandyGoldenThe'),
|
||||
target: 'Golden',
|
||||
},
|
||||
Candy_Zombie: {
|
||||
text: t('foodCandyZombie'),
|
||||
textA: t('foodCandyZombieA'),
|
||||
textThe: t('foodCandyZombieThe'),
|
||||
target: 'Zombie',
|
||||
},
|
||||
Candy_Desert: {
|
||||
text: t('foodCandyDesert'),
|
||||
textA: t('foodCandyDesertA'),
|
||||
textThe: t('foodCandyDesertThe'),
|
||||
target: 'Desert',
|
||||
},
|
||||
Candy_Red: {
|
||||
text: t('foodCandyRed'),
|
||||
textA: t('foodCandyRedA'),
|
||||
textThe: t('foodCandyRedThe'),
|
||||
target: 'Red',
|
||||
},
|
||||
Pie_Skeleton: {
|
||||
text: t('foodPieSkeleton'),
|
||||
textA: t('foodPieSkeletonA'),
|
||||
textThe: t('foodPieSkeletonThe'),
|
||||
target: 'Skeleton',
|
||||
},
|
||||
Pie_Base: {
|
||||
text: t('foodPieBase'),
|
||||
textA: t('foodPieBaseA'),
|
||||
textThe: t('foodPieBaseThe'),
|
||||
target: 'Base',
|
||||
},
|
||||
Pie_CottonCandyBlue: {
|
||||
text: t('foodPieCottonCandyBlue'),
|
||||
textA: t('foodPieCottonCandyBlueA'),
|
||||
textThe: t('foodPieCottonCandyBlueThe'),
|
||||
target: 'CottonCandyBlue',
|
||||
},
|
||||
Pie_CottonCandyPink: {
|
||||
text: t('foodPieCottonCandyPink'),
|
||||
textA: t('foodPieCottonCandyPinkA'),
|
||||
textThe: t('foodPieCottonCandyPinkThe'),
|
||||
target: 'CottonCandyPink',
|
||||
},
|
||||
Pie_Shade: {
|
||||
text: t('foodPieShade'),
|
||||
textA: t('foodPieShadeA'),
|
||||
textThe: t('foodPieShadeThe'),
|
||||
target: 'Shade',
|
||||
},
|
||||
Pie_White: {
|
||||
text: t('foodPieWhite'),
|
||||
textA: t('foodPieWhiteA'),
|
||||
textThe: t('foodPieWhiteThe'),
|
||||
target: 'White',
|
||||
},
|
||||
Pie_Golden: {
|
||||
text: t('foodPieGolden'),
|
||||
textA: t('foodPieGoldenA'),
|
||||
textThe: t('foodPieGoldenThe'),
|
||||
target: 'Golden',
|
||||
},
|
||||
Pie_Zombie: {
|
||||
text: t('foodPieZombie'),
|
||||
textA: t('foodPieZombieA'),
|
||||
textThe: t('foodPieZombieThe'),
|
||||
target: 'Zombie',
|
||||
},
|
||||
Pie_Desert: {
|
||||
text: t('foodPieDesert'),
|
||||
textA: t('foodPieDesertA'),
|
||||
textThe: t('foodPieDesertThe'),
|
||||
target: 'Desert',
|
||||
},
|
||||
Pie_Red: {
|
||||
text: t('foodPieRed'),
|
||||
textA: t('foodPieRedA'),
|
||||
textThe: t('foodPieRedThe'),
|
||||
target: 'Red',
|
||||
},
|
||||
/* eslint-enable camelcase */
|
||||
};
|
||||
|
||||
let FOOD_SEASON = 'Normal';
|
||||
getRepeatingEvents(moment()).forEach(event => {
|
||||
if (event.foodSeason) {
|
||||
FOOD_SEASON = event.foodSeason;
|
||||
}
|
||||
Object.defineProperty(api, 'dropHatchingPotions', {
|
||||
get () { return hatchingPotions.drops; },
|
||||
enumerable: true,
|
||||
});
|
||||
each(api.food, (food, key) => {
|
||||
let foodType = 'Normal';
|
||||
if (key.startsWith('Cake_')) {
|
||||
foodType = 'Cake';
|
||||
} else if (key.startsWith('Candy_')) {
|
||||
foodType = 'Candy';
|
||||
} else if (key.startsWith('Pie_')) {
|
||||
foodType = 'Pie';
|
||||
}
|
||||
defaults(food, {
|
||||
value: 1,
|
||||
key,
|
||||
notes: t('foodNotes'),
|
||||
canBuy: () => FOOD_SEASON === foodType,
|
||||
canDrop: FOOD_SEASON === foodType,
|
||||
Object.defineProperty(api, 'premiumHatchingPotions', {
|
||||
get () { return hatchingPotions.premium; },
|
||||
enumerable: true,
|
||||
});
|
||||
Object.defineProperty(api, 'wackyHatchingPotions', {
|
||||
get () { return hatchingPotions.wacky; },
|
||||
enumerable: true,
|
||||
});
|
||||
Object.defineProperty(api, 'hatchingPotions', {
|
||||
get () { return hatchingPotions.all; },
|
||||
enumerable: true,
|
||||
});
|
||||
|
||||
Object.defineProperty(api, 'dropPets', {
|
||||
get () { return stable.dropPets; },
|
||||
enumerable: true,
|
||||
});
|
||||
Object.defineProperty(api, 'premiumPets', {
|
||||
get () { return stable.premiumPets; },
|
||||
enumerable: true,
|
||||
});
|
||||
Object.defineProperty(api, 'questPets', {
|
||||
get () { return stable.questPets; },
|
||||
enumerable: true,
|
||||
});
|
||||
Object.defineProperty(api, 'specialPets', {
|
||||
get () { return stable.specialPets; },
|
||||
enumerable: true,
|
||||
});
|
||||
Object.defineProperty(api, 'wackyPets', {
|
||||
get () { return stable.wackyPets; },
|
||||
enumerable: true,
|
||||
});
|
||||
Object.defineProperty(api, 'petInfo', {
|
||||
get () { return stable.petInfo; },
|
||||
enumerable: true,
|
||||
});
|
||||
|
||||
Object.defineProperty(api, 'dropMounts', {
|
||||
get () { return stable.dropMounts; },
|
||||
enumerable: true,
|
||||
});
|
||||
Object.defineProperty(api, 'premiumMounts', {
|
||||
get () { return stable.premiumMounts; },
|
||||
enumerable: true,
|
||||
});
|
||||
Object.defineProperty(api, 'questMounts', {
|
||||
get () { return stable.questMounts; },
|
||||
enumerable: true,
|
||||
});
|
||||
Object.defineProperty(api, 'specialMounts', {
|
||||
get () { return stable.specialMounts; },
|
||||
enumerable: true,
|
||||
});
|
||||
Object.defineProperty(api, 'mountInfo', {
|
||||
get () { return stable.mountInfo; },
|
||||
enumerable: true,
|
||||
});
|
||||
|
||||
function buildFood () {
|
||||
const food = {
|
||||
Meat: {
|
||||
text: t('foodMeat'),
|
||||
textA: t('foodMeatA'),
|
||||
textThe: t('foodMeatThe'),
|
||||
target: 'Base',
|
||||
},
|
||||
Milk: {
|
||||
text: t('foodMilk'),
|
||||
textA: t('foodMilkA'),
|
||||
textThe: t('foodMilkThe'),
|
||||
target: 'White',
|
||||
},
|
||||
Potatoe: {
|
||||
text: t('foodPotatoe'),
|
||||
textA: t('foodPotatoeA'),
|
||||
textThe: t('foodPotatoeThe'),
|
||||
target: 'Desert',
|
||||
},
|
||||
Strawberry: {
|
||||
text: t('foodStrawberry'),
|
||||
textA: t('foodStrawberryA'),
|
||||
textThe: t('foodStrawberryThe'),
|
||||
target: 'Red',
|
||||
},
|
||||
Chocolate: {
|
||||
text: t('foodChocolate'),
|
||||
textA: t('foodChocolateA'),
|
||||
textThe: t('foodChocolateThe'),
|
||||
target: 'Shade',
|
||||
},
|
||||
Fish: {
|
||||
text: t('foodFish'),
|
||||
textA: t('foodFishA'),
|
||||
textThe: t('foodFishThe'),
|
||||
target: 'Skeleton',
|
||||
},
|
||||
RottenMeat: {
|
||||
text: t('foodRottenMeat'),
|
||||
textA: t('foodRottenMeatA'),
|
||||
textThe: t('foodRottenMeatThe'),
|
||||
target: 'Zombie',
|
||||
},
|
||||
CottonCandyPink: {
|
||||
text: t('foodCottonCandyPink'),
|
||||
textA: t('foodCottonCandyPinkA'),
|
||||
textThe: t('foodCottonCandyPinkThe'),
|
||||
target: 'CottonCandyPink',
|
||||
},
|
||||
CottonCandyBlue: {
|
||||
text: t('foodCottonCandyBlue'),
|
||||
textA: t('foodCottonCandyBlueA'),
|
||||
textThe: t('foodCottonCandyBlueThe'),
|
||||
target: 'CottonCandyBlue',
|
||||
},
|
||||
Honey: {
|
||||
text: t('foodHoney'),
|
||||
textA: t('foodHoneyA'),
|
||||
textThe: t('foodHoneyThe'),
|
||||
target: 'Golden',
|
||||
},
|
||||
Saddle: {
|
||||
sellWarningNote: t('foodSaddleSellWarningNote'),
|
||||
text: t('foodSaddleText'),
|
||||
value: 5,
|
||||
notes: t('foodSaddleNotes'),
|
||||
canBuy: () => true,
|
||||
canDrop: false,
|
||||
},
|
||||
/* eslint-disable camelcase */
|
||||
Cake_Skeleton: {
|
||||
text: t('foodCakeSkeleton'),
|
||||
textA: t('foodCakeSkeletonA'),
|
||||
textThe: t('foodCakeSkeletonThe'),
|
||||
target: 'Skeleton',
|
||||
},
|
||||
Cake_Base: {
|
||||
text: t('foodCakeBase'),
|
||||
textA: t('foodCakeBaseA'),
|
||||
textThe: t('foodCakeBaseThe'),
|
||||
target: 'Base',
|
||||
},
|
||||
Cake_CottonCandyBlue: {
|
||||
text: t('foodCakeCottonCandyBlue'),
|
||||
textA: t('foodCakeCottonCandyBlueA'),
|
||||
textThe: t('foodCakeCottonCandyBlueThe'),
|
||||
target: 'CottonCandyBlue',
|
||||
},
|
||||
Cake_CottonCandyPink: {
|
||||
text: t('foodCakeCottonCandyPink'),
|
||||
textA: t('foodCakeCottonCandyPinkA'),
|
||||
textThe: t('foodCakeCottonCandyPinkThe'),
|
||||
target: 'CottonCandyPink',
|
||||
},
|
||||
Cake_Shade: {
|
||||
text: t('foodCakeShade'),
|
||||
textA: t('foodCakeShadeA'),
|
||||
textThe: t('foodCakeShadeThe'),
|
||||
target: 'Shade',
|
||||
},
|
||||
Cake_White: {
|
||||
text: t('foodCakeWhite'),
|
||||
textA: t('foodCakeWhiteA'),
|
||||
textThe: t('foodCakeWhiteThe'),
|
||||
target: 'White',
|
||||
},
|
||||
Cake_Golden: {
|
||||
text: t('foodCakeGolden'),
|
||||
textA: t('foodCakeGoldenA'),
|
||||
textThe: t('foodCakeGoldenThe'),
|
||||
target: 'Golden',
|
||||
},
|
||||
Cake_Zombie: {
|
||||
text: t('foodCakeZombie'),
|
||||
textA: t('foodCakeZombieA'),
|
||||
textThe: t('foodCakeZombieThe'),
|
||||
target: 'Zombie',
|
||||
},
|
||||
Cake_Desert: {
|
||||
text: t('foodCakeDesert'),
|
||||
textA: t('foodCakeDesertA'),
|
||||
textThe: t('foodCakeDesertThe'),
|
||||
target: 'Desert',
|
||||
},
|
||||
Cake_Red: {
|
||||
text: t('foodCakeRed'),
|
||||
textA: t('foodCakeRedA'),
|
||||
textThe: t('foodCakeRedThe'),
|
||||
target: 'Red',
|
||||
},
|
||||
Candy_Skeleton: {
|
||||
text: t('foodCandySkeleton'),
|
||||
textA: t('foodCandySkeletonA'),
|
||||
textThe: t('foodCandySkeletonThe'),
|
||||
target: 'Skeleton',
|
||||
},
|
||||
Candy_Base: {
|
||||
text: t('foodCandyBase'),
|
||||
textA: t('foodCandyBaseA'),
|
||||
textThe: t('foodCandyBaseThe'),
|
||||
target: 'Base',
|
||||
},
|
||||
Candy_CottonCandyBlue: {
|
||||
text: t('foodCandyCottonCandyBlue'),
|
||||
textA: t('foodCandyCottonCandyBlueA'),
|
||||
textThe: t('foodCandyCottonCandyBlueThe'),
|
||||
target: 'CottonCandyBlue',
|
||||
},
|
||||
Candy_CottonCandyPink: {
|
||||
text: t('foodCandyCottonCandyPink'),
|
||||
textA: t('foodCandyCottonCandyPinkA'),
|
||||
textThe: t('foodCandyCottonCandyPinkThe'),
|
||||
target: 'CottonCandyPink',
|
||||
},
|
||||
Candy_Shade: {
|
||||
text: t('foodCandyShade'),
|
||||
textA: t('foodCandyShadeA'),
|
||||
textThe: t('foodCandyShadeThe'),
|
||||
target: 'Shade',
|
||||
},
|
||||
Candy_White: {
|
||||
text: t('foodCandyWhite'),
|
||||
textA: t('foodCandyWhiteA'),
|
||||
textThe: t('foodCandyWhiteThe'),
|
||||
target: 'White',
|
||||
},
|
||||
Candy_Golden: {
|
||||
text: t('foodCandyGolden'),
|
||||
textA: t('foodCandyGoldenA'),
|
||||
textThe: t('foodCandyGoldenThe'),
|
||||
target: 'Golden',
|
||||
},
|
||||
Candy_Zombie: {
|
||||
text: t('foodCandyZombie'),
|
||||
textA: t('foodCandyZombieA'),
|
||||
textThe: t('foodCandyZombieThe'),
|
||||
target: 'Zombie',
|
||||
},
|
||||
Candy_Desert: {
|
||||
text: t('foodCandyDesert'),
|
||||
textA: t('foodCandyDesertA'),
|
||||
textThe: t('foodCandyDesertThe'),
|
||||
target: 'Desert',
|
||||
},
|
||||
Candy_Red: {
|
||||
text: t('foodCandyRed'),
|
||||
textA: t('foodCandyRedA'),
|
||||
textThe: t('foodCandyRedThe'),
|
||||
target: 'Red',
|
||||
},
|
||||
Pie_Skeleton: {
|
||||
text: t('foodPieSkeleton'),
|
||||
textA: t('foodPieSkeletonA'),
|
||||
textThe: t('foodPieSkeletonThe'),
|
||||
target: 'Skeleton',
|
||||
},
|
||||
Pie_Base: {
|
||||
text: t('foodPieBase'),
|
||||
textA: t('foodPieBaseA'),
|
||||
textThe: t('foodPieBaseThe'),
|
||||
target: 'Base',
|
||||
},
|
||||
Pie_CottonCandyBlue: {
|
||||
text: t('foodPieCottonCandyBlue'),
|
||||
textA: t('foodPieCottonCandyBlueA'),
|
||||
textThe: t('foodPieCottonCandyBlueThe'),
|
||||
target: 'CottonCandyBlue',
|
||||
},
|
||||
Pie_CottonCandyPink: {
|
||||
text: t('foodPieCottonCandyPink'),
|
||||
textA: t('foodPieCottonCandyPinkA'),
|
||||
textThe: t('foodPieCottonCandyPinkThe'),
|
||||
target: 'CottonCandyPink',
|
||||
},
|
||||
Pie_Shade: {
|
||||
text: t('foodPieShade'),
|
||||
textA: t('foodPieShadeA'),
|
||||
textThe: t('foodPieShadeThe'),
|
||||
target: 'Shade',
|
||||
},
|
||||
Pie_White: {
|
||||
text: t('foodPieWhite'),
|
||||
textA: t('foodPieWhiteA'),
|
||||
textThe: t('foodPieWhiteThe'),
|
||||
target: 'White',
|
||||
},
|
||||
Pie_Golden: {
|
||||
text: t('foodPieGolden'),
|
||||
textA: t('foodPieGoldenA'),
|
||||
textThe: t('foodPieGoldenThe'),
|
||||
target: 'Golden',
|
||||
},
|
||||
Pie_Zombie: {
|
||||
text: t('foodPieZombie'),
|
||||
textA: t('foodPieZombieA'),
|
||||
textThe: t('foodPieZombieThe'),
|
||||
target: 'Zombie',
|
||||
},
|
||||
Pie_Desert: {
|
||||
text: t('foodPieDesert'),
|
||||
textA: t('foodPieDesertA'),
|
||||
textThe: t('foodPieDesertThe'),
|
||||
target: 'Desert',
|
||||
},
|
||||
Pie_Red: {
|
||||
text: t('foodPieRed'),
|
||||
textA: t('foodPieRedA'),
|
||||
textThe: t('foodPieRedThe'),
|
||||
target: 'Red',
|
||||
},
|
||||
/* eslint-enable camelcase */
|
||||
};
|
||||
|
||||
let FOOD_SEASON = 'Normal';
|
||||
getRepeatingEvents(moment()).forEach(event => {
|
||||
if (event.foodSeason) {
|
||||
FOOD_SEASON = event.foodSeason;
|
||||
}
|
||||
});
|
||||
each(food, (foodItem, key) => {
|
||||
let foodType = 'Normal';
|
||||
if (key.startsWith('Cake_')) {
|
||||
foodType = 'Cake';
|
||||
} else if (key.startsWith('Candy_')) {
|
||||
foodType = 'Candy';
|
||||
} else if (key.startsWith('Pie_')) {
|
||||
foodType = 'Pie';
|
||||
}
|
||||
defaults(foodItem, {
|
||||
value: 1,
|
||||
key,
|
||||
notes: t('foodNotes'),
|
||||
canBuy: () => FOOD_SEASON === foodType,
|
||||
canDrop: FOOD_SEASON === foodType,
|
||||
});
|
||||
});
|
||||
|
||||
return food;
|
||||
}
|
||||
|
||||
const memoizedBuildFood = memoize(buildFood);
|
||||
|
||||
Object.defineProperty(api, 'food', {
|
||||
get () { return memoizedBuildFood(); },
|
||||
});
|
||||
|
||||
api.appearances = appearances;
|
||||
|
||||
30
website/common/script/content/is_released.js
Normal file
30
website/common/script/content/is_released.js
Normal file
@@ -0,0 +1,30 @@
|
||||
import moment from 'moment';
|
||||
import filter from 'lodash/filter';
|
||||
import { pickBy } from 'lodash';
|
||||
import nconf from 'nconf';
|
||||
|
||||
const SWITCHOVER_TIME = nconf.get('CONTENT_SWITCHOVER_TIME_OFFSET') || 0;
|
||||
|
||||
const releaseDateEndPart = `T${String(SWITCHOVER_TIME).padStart(2, '0')}:00-0000`;
|
||||
|
||||
export function buildReleaseDate (year, month, day = 1) {
|
||||
return `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}${releaseDateEndPart}`;
|
||||
}
|
||||
|
||||
function isReleased (item, fieldName, releaseDateMap, releaseByDefault) {
|
||||
if (releaseDateMap[item[fieldName]]) {
|
||||
const release = releaseDateMap[item[fieldName]];
|
||||
if (release.day) {
|
||||
return moment().isAfter(moment(buildReleaseDate(release.year, release.month, release.day)));
|
||||
}
|
||||
return moment().isAfter(releaseDateMap[item[fieldName]]);
|
||||
}
|
||||
return releaseByDefault;
|
||||
}
|
||||
|
||||
export function filterReleased (items, fieldName, releaseDateMap, releaseByDefault = true) {
|
||||
if (typeof items === 'object') {
|
||||
return pickBy(items, item => isReleased(item, fieldName, releaseDateMap, releaseByDefault));
|
||||
}
|
||||
return filter(items, item => isReleased(item, fieldName, releaseDateMap, releaseByDefault));
|
||||
}
|
||||
@@ -232,6 +232,38 @@ const QUEST_PETS = {
|
||||
unlock: t('questButterflyUnlockText'),
|
||||
},
|
||||
},
|
||||
chameleon: {
|
||||
text: t('questChameleonText'),
|
||||
notes: t('questChameleonNotes'),
|
||||
completion: t('questChameleonCompletion'),
|
||||
value: 4,
|
||||
category: 'pet',
|
||||
boss: {
|
||||
name: t('questChameleonBoss'),
|
||||
hp: 400,
|
||||
str: 1.5,
|
||||
},
|
||||
drop: {
|
||||
items: [
|
||||
{
|
||||
type: 'eggs',
|
||||
key: 'Chameleon',
|
||||
text: t('questChameleonDropChameleonEgg'),
|
||||
}, {
|
||||
type: 'eggs',
|
||||
key: 'Chameleon',
|
||||
text: t('questChameleonDropChameleonEgg'),
|
||||
}, {
|
||||
type: 'eggs',
|
||||
key: 'Chameleon',
|
||||
text: t('questChameleonDropChameleonEgg'),
|
||||
},
|
||||
],
|
||||
gp: 35,
|
||||
exp: 250,
|
||||
unlock: t('questChameleonUnlockText'),
|
||||
},
|
||||
},
|
||||
cheetah: {
|
||||
text: t('questCheetahText'),
|
||||
notes: t('questCheetahNotes'),
|
||||
|
||||
@@ -20,6 +20,7 @@ const potentialFeaturedPetQuests = [
|
||||
'giraffe',
|
||||
|
||||
'guineapig',
|
||||
'chameleon',
|
||||
|
||||
'cheetah',
|
||||
|
||||
@@ -34,7 +35,6 @@ const potentialFeaturedPetQuests = [
|
||||
'sabretooth',
|
||||
];
|
||||
|
||||
// hatching potions and food names should be capitalized lest you break the market
|
||||
const featuredItems = {
|
||||
market () {
|
||||
const featured = [{
|
||||
|
||||
@@ -1,21 +1,12 @@
|
||||
import each from 'lodash/each';
|
||||
import moment from 'moment';
|
||||
import { EVENTS } from './constants/events';
|
||||
import {
|
||||
drops as dropEggs,
|
||||
quests as questEggs,
|
||||
} from './eggs';
|
||||
import {
|
||||
drops as dropPotions,
|
||||
premium as premiumPotions,
|
||||
wacky as wackyPotions,
|
||||
} from './hatching-potions';
|
||||
import allEggs from './eggs';
|
||||
import allPotions from './hatching-potions';
|
||||
import t from './translation';
|
||||
import memoize from '../fns/datedMemoize';
|
||||
|
||||
const petInfo = {};
|
||||
const mountInfo = {};
|
||||
|
||||
function constructSet (type, eggs, potions) {
|
||||
function constructSet (type, eggs, potions, petInfo, mountInfo, hasMounts = true) {
|
||||
const pets = {};
|
||||
const mounts = {};
|
||||
|
||||
@@ -37,52 +28,24 @@ function constructSet (type, eggs, potions) {
|
||||
potion: potion.text,
|
||||
egg: egg.text,
|
||||
}));
|
||||
mountInfo[key] = getAnimalData(t('mountName', {
|
||||
potion: potion.text,
|
||||
mount: egg.mountText,
|
||||
}));
|
||||
|
||||
pets[key] = true;
|
||||
mounts[key] = true;
|
||||
});
|
||||
});
|
||||
|
||||
return [pets, mounts];
|
||||
}
|
||||
|
||||
function constructPetOnlySet (type, eggs, potions) {
|
||||
const pets = {};
|
||||
|
||||
each(eggs, egg => {
|
||||
each(potions, potion => {
|
||||
const key = `${egg.key}-${potion.key}`;
|
||||
|
||||
function getAnimalData (text) {
|
||||
return {
|
||||
key,
|
||||
type,
|
||||
potion: potion.key,
|
||||
egg: egg.key,
|
||||
text,
|
||||
};
|
||||
if (hasMounts) {
|
||||
mountInfo[key] = getAnimalData(t('mountName', {
|
||||
potion: potion.text,
|
||||
mount: egg.mountText,
|
||||
}));
|
||||
mounts[key] = true;
|
||||
}
|
||||
|
||||
petInfo[key] = getAnimalData(t('petName', {
|
||||
potion: potion.text,
|
||||
egg: egg.text,
|
||||
}));
|
||||
pets[key] = true;
|
||||
});
|
||||
});
|
||||
|
||||
if (hasMounts) {
|
||||
return [pets, mounts];
|
||||
}
|
||||
return pets;
|
||||
}
|
||||
|
||||
const [dropPets, dropMounts] = constructSet('drop', dropEggs, dropPotions);
|
||||
const [premiumPets, premiumMounts] = constructSet('premium', dropEggs, premiumPotions);
|
||||
const [questPets, questMounts] = constructSet('quest', questEggs, dropPotions);
|
||||
const wackyPets = constructPetOnlySet('wacky', dropEggs, wackyPotions);
|
||||
|
||||
const canFindSpecial = {
|
||||
pets: {
|
||||
// Veteran Pet Ladder - awarded on major updates
|
||||
@@ -208,44 +171,88 @@ const specialMounts = {
|
||||
'JackOLantern-RoyalPurple': 'royalPurpleJackolantern',
|
||||
};
|
||||
|
||||
each(specialPets, (translationString, key) => {
|
||||
petInfo[key] = {
|
||||
key,
|
||||
type: 'special',
|
||||
text: t(translationString),
|
||||
canFind: canFindSpecial.pets[key],
|
||||
};
|
||||
});
|
||||
function buildInfo () {
|
||||
const petInfo = {};
|
||||
const mountInfo = {};
|
||||
|
||||
Object.assign(petInfo['Gryphatrice-Jubilant'], {
|
||||
canBuy () {
|
||||
return moment().isBetween(EVENTS.birthday10.start, EVENTS.birthday10.end);
|
||||
const [dropPets, dropMounts] = constructSet('drop', allEggs.drops, allPotions.drops, petInfo, mountInfo);
|
||||
const [premiumPets, premiumMounts] = constructSet('premium', allEggs.drops, allPotions.premium, petInfo, mountInfo);
|
||||
const [questPets, questMounts] = constructSet('quest', allEggs.quests, allPotions.drops, petInfo, mountInfo);
|
||||
const wackyPets = constructSet('wacky', allEggs.drops, allPotions.wacky, petInfo, mountInfo, false);
|
||||
|
||||
each(specialPets, (translationString, key) => {
|
||||
petInfo[key] = {
|
||||
key,
|
||||
type: 'special',
|
||||
text: t(translationString),
|
||||
canFind: canFindSpecial.pets[key],
|
||||
};
|
||||
});
|
||||
|
||||
Object.assign(petInfo['Gryphatrice-Jubilant'], {
|
||||
canBuy () {
|
||||
return moment().isBetween(EVENTS.birthday10.start, EVENTS.birthday10.end);
|
||||
},
|
||||
currency: 'gems',
|
||||
event: 'birthday10',
|
||||
value: 60,
|
||||
purchaseType: 'pets',
|
||||
});
|
||||
|
||||
each(specialMounts, (translationString, key) => {
|
||||
mountInfo[key] = {
|
||||
key,
|
||||
type: 'special',
|
||||
text: t(translationString),
|
||||
canFind: canFindSpecial.mounts[key],
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
dropPets,
|
||||
premiumPets,
|
||||
questPets,
|
||||
wackyPets,
|
||||
dropMounts,
|
||||
questMounts,
|
||||
premiumMounts,
|
||||
specialPets,
|
||||
specialMounts,
|
||||
petInfo,
|
||||
mountInfo,
|
||||
};
|
||||
}
|
||||
|
||||
const memoizedBuildInfo = memoize(buildInfo);
|
||||
|
||||
export default {
|
||||
get dropPets () {
|
||||
return memoizedBuildInfo().dropPets;
|
||||
},
|
||||
get premiumPets () {
|
||||
return memoizedBuildInfo().premiumPets;
|
||||
},
|
||||
get questPets () {
|
||||
return memoizedBuildInfo().questPets;
|
||||
},
|
||||
get wackyPets () {
|
||||
return memoizedBuildInfo().wackyPets;
|
||||
},
|
||||
get dropMounts () {
|
||||
return memoizedBuildInfo().dropMounts;
|
||||
},
|
||||
get questMounts () {
|
||||
return memoizedBuildInfo().questMounts;
|
||||
},
|
||||
get premiumMounts () {
|
||||
return memoizedBuildInfo().premiumMounts;
|
||||
},
|
||||
get petInfo () {
|
||||
return memoizedBuildInfo().petInfo;
|
||||
},
|
||||
get mountInfo () {
|
||||
return memoizedBuildInfo().mountInfo;
|
||||
},
|
||||
currency: 'gems',
|
||||
event: 'birthday10',
|
||||
value: 60,
|
||||
purchaseType: 'pets',
|
||||
});
|
||||
|
||||
each(specialMounts, (translationString, key) => {
|
||||
mountInfo[key] = {
|
||||
key,
|
||||
type: 'special',
|
||||
text: t(translationString),
|
||||
canFind: canFindSpecial.mounts[key],
|
||||
};
|
||||
});
|
||||
|
||||
export {
|
||||
dropPets,
|
||||
premiumPets,
|
||||
questPets,
|
||||
wackyPets,
|
||||
dropMounts,
|
||||
questMounts,
|
||||
premiumMounts,
|
||||
specialPets,
|
||||
specialMounts,
|
||||
petInfo,
|
||||
mountInfo,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user