diff --git a/habitica-images b/habitica-images index d66a5ea922..f9c1439cd9 160000 --- a/habitica-images +++ b/habitica-images @@ -1 +1 @@ -Subproject commit d66a5ea922d91815d4419b718ff38a80e11667f7 +Subproject commit f9c1439cd927486fa766982ad078e9feb323b9da diff --git a/migrations/archive/2022/20221213_pet_group_achievements.js b/migrations/archive/2022/20221213_pet_group_achievements.js new file mode 100644 index 0000000000..5bf2079b5e --- /dev/null +++ b/migrations/archive/2022/20221213_pet_group_achievements.js @@ -0,0 +1,108 @@ +/* eslint-disable no-console */ +const MIGRATION_NAME = '20221213_pet_group_achievements'; +import { model as User } from '../../../website/server/models/user'; + +const progressCount = 1000; +let count = 0; + +async function updateUser (user) { + count++; + + const set = { + migration: MIGRATION_NAME, + }; + + if (user && user.items && user.items.pets) { + const pets = user.items.pets; + if (pets['BearCub-Base'] + && pets['BearCub-CottonCandyBlue'] + && pets['BearCub-CottonCandyPink'] + && pets['BearCub-Desert'] + && pets['BearCub-Golden'] + && pets['BearCub-Red'] + && pets['BearCub-Shade'] + && pets['BearCub-Skeleton'] + && pets['BearCub-White'] + && pets['BearCub-Zombie'] + && pets['Fox-Base'] + && pets['Fox-CottonCandyBlue'] + && pets['Fox-CottonCandyPink'] + && pets['Fox-Desert'] + && pets['Fox-Golden'] + && pets['Fox-Red'] + && pets['Fox-Shade'] + && pets['Fox-Skeleton'] + && pets['Fox-White'] + && pets['Fox-Zombie'] + && pets['Penguin-Base'] + && pets['Penguin-CottonCandyBlue'] + && pets['Penguin-CottonCandyPink'] + && pets['Penguin-Desert'] + && pets['Penguin-Golden'] + && pets['Penguin-Red'] + && pets['Penguin-Shade'] + && pets['Penguin-Skeleton'] + && pets['Penguin-White'] + && pets['Penguin-Zombie'] + && pets['Whale-Base'] + && pets['Whale-CottonCandyBlue'] + && pets['Whale-CottonCandyPink'] + && pets['Whale-Desert'] + && pets['Whale-Golden'] + && pets['Whale-Red'] + && pets['Whale-Shade'] + && pets['Whale-Skeleton'] + && pets['Whale-White'] + && pets['Whale-Zombie'] + && pets['Wolf-Base'] + && pets['Wolf-CottonCandyBlue'] + && pets['Wolf-CottonCandyPink'] + && pets['Wolf-Desert'] + && pets['Wolf-Golden'] + && pets['Wolf-Red'] + && pets['Wolf-Shade'] + && pets['Wolf-Skeleton'] + && pets['Wolf-White'] + && pets['Wolf-Zombie'] { + set['achievements.polarPro'] = true; + } + } + + if (count % progressCount === 0) console.warn(`${count} ${user._id}`); + + return await User.update({ _id: user._id }, { $set: set }).exec(); +} + +export default async function processUsers () { + let query = { + // migration: { $ne: MIGRATION_NAME }, + 'auth.timestamps.loggedin': { $gt: new Date('2022-11-01') }, + }; + + const fields = { + _id: 1, + items: 1, + }; + + while (true) { // eslint-disable-line no-constant-condition + const users = await User // eslint-disable-line no-await-in-loop + .find(query) + .limit(250) + .sort({_id: 1}) + .select(fields) + .lean() + .exec(); + + if (users.length === 0) { + console.warn('All appropriate users found and modified.'); + console.warn(`\n${count} users processed\n`); + break; + } else { + query._id = { + $gt: users[users.length - 1]._id, + }; + } + + await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop + } +}; diff --git a/website/client/src/assets/css/sprites/spritesmith-main.css b/website/client/src/assets/css/sprites/spritesmith-main.css index 4302329360..c57eb7c1f6 100644 --- a/website/client/src/assets/css/sprites/spritesmith-main.css +++ b/website/client/src/assets/css/sprites/spritesmith-main.css @@ -293,6 +293,11 @@ width: 48px; height: 52px; } +.achievement-polarPro2x { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/achievement-polarPro2x.png'); + width: 68px; + height: 68px; +} .achievement-primedForPainting2x { background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/achievement-primedForPainting2x.png'); width: 48px; diff --git a/website/common/locales/en/achievements.json b/website/common/locales/en/achievements.json index b4b577280b..ad43c35688 100644 --- a/website/common/locales/en/achievements.json +++ b/website/common/locales/en/achievements.json @@ -141,5 +141,8 @@ "achievementWoodlandWizardModalText": "You collected all the forest pets!", "achievementBoneToPick": "Bone to Pick", "achievementBoneToPickText": "Has hatched all the Classic and Quest Skeleton Pets!", - "achievementBoneToPickModalText": "You collected all the Classic and Quest Skeleton Pets!" + "achievementBoneToPickModalText": "You collected all the Classic and Quest Skeleton Pets!", + "achievementPolarPro": "Polar Pro", + "achievementPolarProText": "Has hatched all Polar pets: Bear, Fox, Penguin, Whale, and Wolf!", + "achievementPolarProModalText": "You collected all the Polar Pets!" } diff --git a/website/common/script/content/achievements.js b/website/common/script/content/achievements.js index 12849bf637..f9451c33de 100644 --- a/website/common/script/content/achievements.js +++ b/website/common/script/content/achievements.js @@ -183,6 +183,11 @@ const animalSetAchievs = { titleKey: 'achievementDomesticated', textKey: 'achievementDomesticatedText', }, + polarPro: { + icon: 'achievement-polarPro', + titleKey: 'achievementPolarPro', + textKey: 'achievementPolarProText', + }, reptacularRumble: { icon: 'achievement-reptacularRumble', titleKey: 'achievementReptacularRumble', diff --git a/website/common/script/content/constants/animalSetAchievements.js b/website/common/script/content/constants/animalSetAchievements.js index 0c747a0826..51c07fabf3 100644 --- a/website/common/script/content/constants/animalSetAchievements.js +++ b/website/common/script/content/constants/animalSetAchievements.js @@ -41,6 +41,18 @@ const ANIMAL_SET_ACHIEVEMENTS = { achievementKey: 'domesticated', notificationType: 'ACHIEVEMENT_ANIMAL_SET', }, + polarPro: { + type: 'pet', + species: [ + 'BearCub', + 'Fox', + 'Penguin', + 'Whale', + 'Wolf', + ], + achievementKey: 'polarPro', + notificationType: 'ACHIEVEMENT_ANIMAL_SET', + }, reptacularRumble: { type: 'pet', species: [ diff --git a/website/common/script/libs/achievements.js b/website/common/script/libs/achievements.js index 52af6e2ce7..79aecd4c2f 100644 --- a/website/common/script/libs/achievements.js +++ b/website/common/script/libs/achievements.js @@ -220,6 +220,7 @@ function _getBasicAchievements (user, language) { _addSimple(result, user, { path: 'reptacularRumble', language }); _addSimple(result, user, { path: 'woodlandWizard', language }); _addSimple(result, user, { path: 'boneToPick', language }); + _addSimple(result, user, { path: 'polarPro', language }); _addSimpleWithMasterCount(result, user, { path: 'beastMaster', language }); _addSimpleWithMasterCount(result, user, { path: 'mountMaster', language }); diff --git a/website/server/models/user/schema.js b/website/server/models/user/schema.js index 4afe7a1ae8..0f47a975d9 100644 --- a/website/server/models/user/schema.js +++ b/website/server/models/user/schema.js @@ -152,6 +152,7 @@ export default new Schema({ reptacularRumble: Boolean, woodlandWizard: Boolean, boneToPick: Boolean, + polarPro: Boolean, // Onboarding Guide createdTask: Boolean, completedTask: Boolean,