From df25e0574d9f452a33e9ba9cdd1da17b33fe0ecc Mon Sep 17 00:00:00 2001 From: SabreCat Date: Mon, 5 Dec 2022 16:36:42 -0600 Subject: [PATCH 01/12] fix(auth): enforce max pass length at update --- .../user/auth/PUT-user_update_password.test.js | 14 ++++++++++++++ website/server/controllers/api-v3/auth.js | 7 +++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/test/api/v3/integration/user/auth/PUT-user_update_password.test.js b/test/api/v3/integration/user/auth/PUT-user_update_password.test.js index 94fbd4f3e2..4ccfef0c5a 100644 --- a/test/api/v3/integration/user/auth/PUT-user_update_password.test.js +++ b/test/api/v3/integration/user/auth/PUT-user_update_password.test.js @@ -96,6 +96,20 @@ describe('PUT /user/auth/update-password', async () => { }); }); + it('returns an error when newPassword is too long', async () => { + const body = { + password, + newPassword: '12345678910111213141516171819202122232425262728293031323334353637383940', + confirmPassword: '12345678910111213141516171819202122232425262728293031323334353637383940', + }; + + await expect(user.put(ENDPOINT, body)).to.eventually.be.rejected.and.eql({ + code: 400, + error: 'BadRequest', + message: t('invalidReqParams'), + }); + }); + it('returns an error when confirmPassword is missing', async () => { const body = { password, diff --git a/website/server/controllers/api-v3/auth.js b/website/server/controllers/api-v3/auth.js index 7092066446..31cf12408e 100644 --- a/website/server/controllers/api-v3/auth.js +++ b/website/server/controllers/api-v3/auth.js @@ -289,8 +289,11 @@ api.updatePassword = { newPassword: { notEmpty: { errorMessage: res.t('missingNewPassword') }, isLength: { - options: { min: common.constants.MINIMUM_PASSWORD_LENGTH }, - errorMessage: res.t('minPasswordLength'), + options: { + min: common.constants.MINIMUM_PASSWORD_LENGTH, + max: common.constants.MAXIMUM_PASSWORD_LENGTH, + }, + errorMessage: res.t('passwordIssueLength'), }, }, confirmPassword: { From 573c9325650abeede35cc748dfc238b23840ff89 Mon Sep 17 00:00:00 2001 From: Natalie L <78037386+CuriousMagpie@users.noreply.github.com> Date: Tue, 13 Dec 2022 15:50:53 -0500 Subject: [PATCH 02/12] chore(content): add Polar Pro achievement (#14399) * chore(content): add Polar Pro achievement * chore(script): add migration script * fix(typo): rogue backticks * fix(capitalization): revert css blurp * fix(migration): no babby wuff Co-authored-by: Sabe Jones Co-authored-by: SabreCat --- habitica-images | 2 +- .../2022/20221213_pet_group_achievements.js | 108 ++++++++++++++++++ .../assets/css/sprites/spritesmith-main.css | 5 + website/common/locales/en/achievements.json | 5 +- website/common/script/content/achievements.js | 5 + .../constants/animalSetAchievements.js | 12 ++ website/common/script/libs/achievements.js | 1 + website/server/models/user/schema.js | 1 + 8 files changed, 137 insertions(+), 2 deletions(-) create mode 100644 migrations/archive/2022/20221213_pet_group_achievements.js 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, From a774d32b8adcbadbe6dcd35f2b511e31ee47e3ce Mon Sep 17 00:00:00 2001 From: SabreCat Date: Tue, 13 Dec 2022 14:51:42 -0600 Subject: [PATCH 03/12] chore(subproj): update habitica-images --- habitica-images | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/habitica-images b/habitica-images index f9c1439cd9..e8f76ad308 160000 --- a/habitica-images +++ b/habitica-images @@ -1 +1 @@ -Subproject commit f9c1439cd927486fa766982ad078e9feb323b9da +Subproject commit e8f76ad308e256fb65306cfe880cabdc98c818cd From 2d1fca402b646f0d2db3b420b5a3f9503cd3ddce Mon Sep 17 00:00:00 2001 From: SabreCat Date: Tue, 13 Dec 2022 14:51:53 -0600 Subject: [PATCH 04/12] 4.252.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 239cceb274..f6cd142c7e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "habitica", - "version": "4.251.0", + "version": "4.252.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 31d5f83242..ede5b90f2a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "habitica", "description": "A habit tracker app which treats your goals like a Role Playing Game.", - "version": "4.251.0", + "version": "4.252.0", "main": "./website/server/index.js", "dependencies": { "@babel/core": "^7.19.6", From 9c10cb3b883a850ddee22879bd4807e5d8080897 Mon Sep 17 00:00:00 2001 From: SabreCat Date: Wed, 14 Dec 2022 14:13:36 -0600 Subject: [PATCH 05/12] chore(event): enable G1G1 promo --- website/common/locales/en/limited.json | 2 +- website/common/script/content/constants/events.js | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/website/common/locales/en/limited.json b/website/common/locales/en/limited.json index 658227ca49..56561249e2 100644 --- a/website/common/locales/en/limited.json +++ b/website/common/locales/en/limited.json @@ -229,7 +229,7 @@ "howItWorks": "How it Works", "g1g1HowItWorks": "Type in the username of the account you’d like to gift to. From there, pick the sub length you’d like to gift and check out. Your account will automatically be rewarded with the same level of subscription you just gifted.", "limitations": "Limitations", - "g1g1Limitations": "This is a limited time event that starts on December 16th at 8:00 AM ET (13:00 UTC) and will end January 6th at 8:00 PM ET (1:00 UTC). This promotion only applies when you gift to another Habitican. If you or your gift recipient already have a subscription, the gifted subscription will add months of credit that will only be used after the current subscription is canceled or expires.", + "g1g1Limitations": "This is a limited time event that starts on December 14th at 8:00 AM ET (13:00 UTC) and will end January 5th at 11:59 PM ET (January 6th 04:59 UTC). This promotion only applies when you gift to another Habitican. If you or your gift recipient already have a subscription, the gifted subscription will add months of credit that will only be used after the current subscription is canceled or expires.", "noLongerAvailable": "This item is no longer available.", "gemSaleHow": "Between <%= eventStartMonth %> <%= eventStartOrdinal %> and <%= eventEndOrdinal %>, simply purchase any Gem bundle like usual and your account will be credited with the promotional amount of Gems. More Gems to spend, share, or save for any future releases!", "gemSaleLimitations": "This promotion only applies during the limited time event. This event starts on <%= eventStartMonth %> <%= eventStartOrdinal %> at 8:00 AM EDT (12:00 UTC) and will end <%= eventStartMonth %> <%= eventEndOrdinal %> at 8:00 PM EDT (00:00 UTC). The promo offer is only available when buying Gems for yourself." diff --git a/website/common/script/content/constants/events.js b/website/common/script/content/constants/events.js index f561d44bd5..2a8ff2cfc6 100644 --- a/website/common/script/content/constants/events.js +++ b/website/common/script/content/constants/events.js @@ -15,6 +15,11 @@ export const EVENTS = { season: 'normal', npcImageSuffix: '', }, + g1g12022: { + start: '2022-12-15T08:00-05:00', + end: '2023-01-08T23:59-05:00', + promo: 'g1g1', + }, harvestFeast2022: { start: '2022-11-22T08:00-05:00', end: '2022-11-27T20:00-05:00', From a9629bdc0ae13f4675e01cc2cad6dd31398cc29b Mon Sep 17 00:00:00 2001 From: SabreCat Date: Wed, 14 Dec 2022 14:13:42 -0600 Subject: [PATCH 06/12] 4.252.1 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index f6cd142c7e..1eee55488b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "habitica", - "version": "4.252.0", + "version": "4.252.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index ede5b90f2a..043cdf41b4 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "habitica", "description": "A habit tracker app which treats your goals like a Role Playing Game.", - "version": "4.252.0", + "version": "4.252.1", "main": "./website/server/index.js", "dependencies": { "@babel/core": "^7.19.6", From ee91780f2019f594fc89c4e4fa45c052fc15e07c Mon Sep 17 00:00:00 2001 From: SabreCat Date: Wed, 14 Dec 2022 14:41:33 -0600 Subject: [PATCH 07/12] fix(typo): tomorrow and tomorrow --- website/common/locales/en/limited.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/common/locales/en/limited.json b/website/common/locales/en/limited.json index 56561249e2..f5a7a3a072 100644 --- a/website/common/locales/en/limited.json +++ b/website/common/locales/en/limited.json @@ -229,7 +229,7 @@ "howItWorks": "How it Works", "g1g1HowItWorks": "Type in the username of the account you’d like to gift to. From there, pick the sub length you’d like to gift and check out. Your account will automatically be rewarded with the same level of subscription you just gifted.", "limitations": "Limitations", - "g1g1Limitations": "This is a limited time event that starts on December 14th at 8:00 AM ET (13:00 UTC) and will end January 5th at 11:59 PM ET (January 6th 04:59 UTC). This promotion only applies when you gift to another Habitican. If you or your gift recipient already have a subscription, the gifted subscription will add months of credit that will only be used after the current subscription is canceled or expires.", + "g1g1Limitations": "This is a limited time event that starts on December 15th at 8:00 AM ET (13:00 UTC) and will end January 5th at 11:59 PM ET (January 6th 04:59 UTC). This promotion only applies when you gift to another Habitican. If you or your gift recipient already have a subscription, the gifted subscription will add months of credit that will only be used after the current subscription is canceled or expires.", "noLongerAvailable": "This item is no longer available.", "gemSaleHow": "Between <%= eventStartMonth %> <%= eventStartOrdinal %> and <%= eventEndOrdinal %>, simply purchase any Gem bundle like usual and your account will be credited with the promotional amount of Gems. More Gems to spend, share, or save for any future releases!", "gemSaleLimitations": "This promotion only applies during the limited time event. This event starts on <%= eventStartMonth %> <%= eventStartOrdinal %> at 8:00 AM EDT (12:00 UTC) and will end <%= eventStartMonth %> <%= eventEndOrdinal %> at 8:00 PM EDT (00:00 UTC). The promo offer is only available when buying Gems for yourself." From 591279c1a81e57397840b212ddef18eae85600ce Mon Sep 17 00:00:00 2001 From: SabreCat Date: Thu, 15 Dec 2022 09:00:12 -0600 Subject: [PATCH 08/12] fix(dates): correct inconsistency --- website/common/locales/en/limited.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/common/locales/en/limited.json b/website/common/locales/en/limited.json index f5a7a3a072..1c9dbebdb8 100644 --- a/website/common/locales/en/limited.json +++ b/website/common/locales/en/limited.json @@ -229,7 +229,7 @@ "howItWorks": "How it Works", "g1g1HowItWorks": "Type in the username of the account you’d like to gift to. From there, pick the sub length you’d like to gift and check out. Your account will automatically be rewarded with the same level of subscription you just gifted.", "limitations": "Limitations", - "g1g1Limitations": "This is a limited time event that starts on December 15th at 8:00 AM ET (13:00 UTC) and will end January 5th at 11:59 PM ET (January 6th 04:59 UTC). This promotion only applies when you gift to another Habitican. If you or your gift recipient already have a subscription, the gifted subscription will add months of credit that will only be used after the current subscription is canceled or expires.", + "g1g1Limitations": "This is a limited time event that starts on December 15th at 8:00 AM ET (13:00 UTC) and will end January 8th at 11:59 PM ET (January 9th 04:59 UTC). This promotion only applies when you gift to another Habitican. If you or your gift recipient already have a subscription, the gifted subscription will add months of credit that will only be used after the current subscription is canceled or expires.", "noLongerAvailable": "This item is no longer available.", "gemSaleHow": "Between <%= eventStartMonth %> <%= eventStartOrdinal %> and <%= eventEndOrdinal %>, simply purchase any Gem bundle like usual and your account will be credited with the promotional amount of Gems. More Gems to spend, share, or save for any future releases!", "gemSaleLimitations": "This promotion only applies during the limited time event. This event starts on <%= eventStartMonth %> <%= eventStartOrdinal %> at 8:00 AM EDT (12:00 UTC) and will end <%= eventStartMonth %> <%= eventEndOrdinal %> at 8:00 PM EDT (00:00 UTC). The promo offer is only available when buying Gems for yourself." From 3893d38583ec6a2e20e483ce1f9665921aa1a172 Mon Sep 17 00:00:00 2001 From: SabreCat Date: Thu, 15 Dec 2022 14:04:45 -0600 Subject: [PATCH 09/12] 4.252.2 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index deb2c32f6f..06efc5575f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "habitica", - "version": "4.252.1", + "version": "4.252.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index bbd406d14f..c26709d46f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "habitica", "description": "A habit tracker app which treats your goals like a Role Playing Game.", - "version": "4.252.1", + "version": "4.252.2", "main": "./website/server/index.js", "dependencies": { "@babel/core": "^7.19.6", From fd9d738cc6cb6725d73914c1ae8c4bae6794d8ff Mon Sep 17 00:00:00 2001 From: Natalie L <78037386+CuriousMagpie@users.noreply.github.com> Date: Mon, 19 Dec 2022 16:53:52 -0500 Subject: [PATCH 10/12] chore(content): add winter wonderland items (#14407) * chore(content): add winter wonderland items * chore(typos): dates are hard * fix(tz): how far back we have fallen * fix(event): four extra hours for stragglers * fix(typo): singular snowball spell * fix(gear): remove stray incorrect event prop * merge release * Revert "merge release" This reverts commit 83e29d028866e1d2ab2c1c181e4c82eeb161b647. * feat(content): add EN text * fix(dates): 2022-2023 Winter * chore(content): add featured quest bundle * fix(event): delay Snowballs, add quests to Seasonal Shop Co-authored-by: Sabe Jones Co-authored-by: SabreCat --- .../assets/css/sprites/spritesmith-main.css | 170 ++++++++++++++++++ website/common/locales/en/gear.json | 32 ++++ website/common/locales/en/limited.json | 4 + .../common/script/content/appearance/sets.js | 4 +- website/common/script/content/bundles.js | 3 +- .../common/script/content/constants/events.js | 11 +- .../script/content/constants/seasonalSets.js | 5 + .../script/content/gear/sets/special/index.js | 106 ++++++++++- .../common/script/content/hatching-potions.js | 17 +- .../script/content/shop-featuredItems.js | 30 ++-- .../script/libs/shops-seasonal.config.js | 19 +- 11 files changed, 363 insertions(+), 38 deletions(-) diff --git a/website/client/src/assets/css/sprites/spritesmith-main.css b/website/client/src/assets/css/sprites/spritesmith-main.css index c57eb7c1f6..1f4657bda7 100644 --- a/website/client/src/assets/css/sprites/spritesmith-main.css +++ b/website/client/src/assets/css/sprites/spritesmith-main.css @@ -31280,6 +31280,26 @@ width: 117px; height: 120px; } +.broad_armor_special_winter2023Healer { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/broad_armor_special_winter2023Healer.png'); + width: 117px; + height: 120px; +} +.broad_armor_special_winter2023Mage { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/broad_armor_special_winter2023Mage.png'); + width: 114px; + height: 90px; +} +.broad_armor_special_winter2023Rogue { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/broad_armor_special_winter2023Rogue.png'); + width: 116px; + height: 119px; +} +.broad_armor_special_winter2023Warrior { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/broad_armor_special_winter2023Warrior.png'); + width: 114px; + height: 117px; +} .broad_armor_special_yeti { background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/broad_armor_special_yeti.png'); width: 90px; @@ -31505,6 +31525,26 @@ width: 117px; height: 120px; } +.head_special_winter2023Healer { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/head_special_winter2023Healer.png'); + width: 117px; + height: 120px; +} +.head_special_winter2023Mage { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/head_special_winter2023Mage.png'); + width: 114px; + height: 90px; +} +.head_special_winter2023Rogue { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/head_special_winter2023Rogue.png'); + width: 116px; + height: 119px; +} +.head_special_winter2023Warrior { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/head_special_winter2023Warrior.png'); + width: 114px; + height: 117px; +} .head_special_yeti { background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/head_special_yeti.png'); width: 90px; @@ -31640,6 +31680,21 @@ width: 117px; height: 120px; } +.shield_special_winter2023Healer { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shield_special_winter2023Healer.png'); + width: 117px; + height: 120px; +} +.shield_special_winter2023Rogue { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shield_special_winter2023Rogue.png'); + width: 116px; + height: 119px; +} +.shield_special_winter2023Warrior { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shield_special_winter2023Warrior.png'); + width: 114px; + height: 117px; +} .shield_special_yeti { background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shield_special_yeti.png'); width: 90px; @@ -31820,6 +31875,26 @@ width: 68px; height: 68px; } +.shop_armor_special_winter2023Healer { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_armor_special_winter2023Healer.png'); + width: 68px; + height: 68px; +} +.shop_armor_special_winter2023Mage { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_armor_special_winter2023Mage.png'); + width: 68px; + height: 68px; +} +.shop_armor_special_winter2023Rogue { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_armor_special_winter2023Rogue.png'); + width: 68px; + height: 68px; +} +.shop_armor_special_winter2023Warrior { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_armor_special_winter2023Warrior.png'); + width: 68px; + height: 68px; +} .shop_armor_special_yeti { background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_armor_special_yeti.png'); width: 68px; @@ -32045,6 +32120,26 @@ width: 68px; height: 68px; } +.shop_head_special_winter2023Healer { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_head_special_winter2023Healer.png'); + width: 68px; + height: 68px; +} +.shop_head_special_winter2023Mage { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_head_special_winter2023Mage.png'); + width: 68px; + height: 68px; +} +.shop_head_special_winter2023Rogue { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_head_special_winter2023Rogue.png'); + width: 68px; + height: 68px; +} +.shop_head_special_winter2023Warrior { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_head_special_winter2023Warrior.png'); + width: 68px; + height: 68px; +} .shop_head_special_yeti { background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_head_special_yeti.png'); width: 68px; @@ -32180,6 +32275,21 @@ width: 68px; height: 68px; } +.shop_shield_special_winter2023Healer { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_shield_special_winter2023Healer.png'); + width: 68px; + height: 68px; +} +.shop_shield_special_winter2023Rogue { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_shield_special_winter2023Rogue.png'); + width: 68px; + height: 68px; +} +.shop_shield_special_winter2023Warrior { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_shield_special_winter2023Warrior.png'); + width: 68px; + height: 68px; +} .shop_shield_special_yeti { background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_shield_special_yeti.png'); width: 68px; @@ -32360,6 +32470,26 @@ width: 68px; height: 68px; } +.shop_weapon_special_winter2023Healer { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_weapon_special_winter2023Healer.png'); + width: 68px; + height: 68px; +} +.shop_weapon_special_winter2023Mage { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_weapon_special_winter2023Mage.png'); + width: 68px; + height: 68px; +} +.shop_weapon_special_winter2023Rogue { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_weapon_special_winter2023Rogue.png'); + width: 68px; + height: 68px; +} +.shop_weapon_special_winter2023Warrior { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_weapon_special_winter2023Warrior.png'); + width: 68px; + height: 68px; +} .shop_weapon_special_yeti { background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_weapon_special_yeti.png'); width: 68px; @@ -32540,6 +32670,26 @@ width: 117px; height: 120px; } +.slim_armor_special_winter2023Healer { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/slim_armor_special_winter2023Healer.png'); + width: 117px; + height: 120px; +} +.slim_armor_special_winter2023Mage { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/slim_armor_special_winter2023Mage.png'); + width: 114px; + height: 90px; +} +.slim_armor_special_winter2023Rogue { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/slim_armor_special_winter2023Rogue.png'); + width: 116px; + height: 119px; +} +.slim_armor_special_winter2023Warrior { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/slim_armor_special_winter2023Warrior.png'); + width: 114px; + height: 117px; +} .slim_armor_special_yeti { background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/slim_armor_special_yeti.png'); width: 90px; @@ -32720,6 +32870,26 @@ width: 117px; height: 120px; } +.weapon_special_winter2023Healer { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/weapon_special_winter2023Healer.png'); + width: 117px; + height: 120px; +} +.weapon_special_winter2023Mage { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/weapon_special_winter2023Mage.png'); + width: 114px; + height: 90px; +} +.weapon_special_winter2023Rogue { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/weapon_special_winter2023Rogue.png'); + width: 116px; + height: 119px; +} +.weapon_special_winter2023Warrior { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/weapon_special_winter2023Warrior.png'); + width: 114px; + height: 117px; +} .weapon_special_yeti { background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/weapon_special_yeti.png'); width: 90px; diff --git a/website/common/locales/en/gear.json b/website/common/locales/en/gear.json index 766e6754ef..d78ac5111c 100644 --- a/website/common/locales/en/gear.json +++ b/website/common/locales/en/gear.json @@ -456,6 +456,15 @@ "weaponSpecialFall2022HealerText": "Right Peeker Eye", "weaponSpecialFall2022HealerNotes": "To claim victory, hold it forth and utter the words of command: 'Eye One!' Increases Intelligence by <%= int %>. Limited Edition 2022 Fall Gear.", + "weaponSpecialWinter2023RogueText": "Green Satin Sash", + "weaponSpecialWinter2023RogueNotes": "Legends tell of Rogues who snare their opponents' weapons, disarm them, then gift the item back just to be cute. Incrases Strength by <%= str %>. Limited Edition 2022-2023 Winter Gear.", + "weaponSpecialWinter2023WarriorText": "Tusk Spear", + "weaponSpecialWinter2023WarriorNotes": "The two prongs of this spear are shaped like walrus tusks but are twice as powerful. Jab at doubts and at silly poems until they back off! Increases Strength by <%= str %>. Limited Edition 2022-2023 Winter Gear.", + "weaponSpecialWinter2023MageText": "Foxfire", + "weaponSpecialWinter2023MageNotes": "Neither fox nor fire, but plenty festive! Increases Intelligence by <%= int %> and Perception by <%= per %>. Limited Edition 2022-2023 Winter Gear.", + "weaponSpecialWinter2023HealerText": "Throwing Wreath", + "weaponSpecialWinter2023HealerNotes": "Watch this festive, prickly wreath spin through the air toward your enemy or obstacles and return to you like a boomerang for another throw. Increases Intelligence by <%= int %>. Limited Edition 2022-2023 Winter Gear.", + "weaponMystery201411Text": "Pitchfork of Feasting", "weaponMystery201411Notes": "Stab your enemies or dig in to your favorite foods - this versatile pitchfork does it all! Confers no benefit. November 2014 Subscriber Item.", "weaponMystery201502Text": "Shimmery Winged Staff of Love and Also Truth", @@ -1109,6 +1118,15 @@ "armorSpecialFall2022HealerText": "Profusion of Peeker Pods", "armorSpecialFall2022HealerNotes": "How many peeps could a Peeker peep, if a Peeker could peep peeps? Increases Constitution by <%= con %>. Limited Edition 2022 Fall Gear.", + "armorSpecialWinter2023RogueText": "Ribbon Wrap", + "armorSpecialWinter2023RogueNotes": "Obtain items. Bundle them up in pretty paper. And give them to your local Rogue! The season demands it. Increases Perception by <%= per %>. Limited Edition 2022-2023 Winter Gear.", + "armorSpecialWinter2023WarriorText": "Walrus Suit", + "armorSpecialWinter2023WarriorNotes": "This tough walrus suit is perfect for a walk along a beach in the middle of the night. Increases Constitution by <%= con %>. Limited Edition 2022-2023 Winter Gear.", + "armorSpecialWinter2023MageText": "Fairy Light Gown", + "armorSpecialWinter2023MageNotes": "Just because you have lights on, that doesn't make you a tree! ...maybe some other year. Increases Intelligence by <%= int %>. Limited Edition 2022-2023 Winter Gear.", + "armorSpecialWinter2023HealerText": "Cardinal Suit", + "armorSpecialWinter2023HealerNotes": "This bright cardinal suit is perfect for flying high above your problems. Increases Constitution by <%= con %>. Limited Edition 2022-2023 Winter Gear.", + "armorMystery201402Text": "Messenger Robes", "armorMystery201402Notes": "Shimmering and strong, these robes have many pockets to carry letters. Confers no benefit. February 2014 Subscriber Item.", "armorMystery201403Text": "Forest Walker Armor", @@ -1835,6 +1853,15 @@ "headSpecialFall2022MageNotes": "Entrance and lure others close with this magical maiden mask. Increases Perception by <%= per %>. Limited Edition 2022 Fall Gear.", "headSpecialFall2022HealerText": "Peeker Mask", "headSpecialFall2022HealerNotes": "Beauty is in there. Somewhere! Increases Intelligence by <%= int %>. Limited Edition 2022 Fall Gear.", + + "headSpecialWinter2023RogueText": "Gift Bow", + "headSpecialWinter2023RogueNotes": "People's temptations to “unwrap” your hair will give you opportunities to practice your ducks and dodges. Increases Perception by <%= per %>. Limited Edition 2022-2023 Winter Gear.", + "headSpecialWinter2023WarriorText": "Walrus Helm", + "headSpecialWinter2023WarriorNotes": "This walrus helm is perfect for chatting with a friend or partaking in a clever meal. Increases Strength by <%= str %>. Limited Edition 2022-2023 Winter Gear.", + "headSpecialWinter2023MageText": "Fairy-Lit Tiara", + "headSpecialWinter2023MageNotes": "Were you hatched with a Starry Night potion? Because I've got stars in my eyes for you. Increases Perception by <%= per %>. Limited Edition 2022-2023 Winter Gear.", + "headSpecialWinter2023HealerText": "Cardinal Helm", + "headSpecialWinter2023HealerNotes": "This cardinal helm is perfect for whistling and singing to herald the winter season. Increases Intelligence by <%= int %>. Limited Edition 2022-2023 Winter Gear.", "headSpecialGaymerxText": "Rainbow Warrior Helm", "headSpecialGaymerxNotes": "In celebration of the GaymerX Conference, this special helmet is decorated with a radiant, colorful rainbow pattern! GaymerX is a game convention celebrating LGTBQ and gaming and is open to everyone.", @@ -2396,6 +2423,11 @@ "shieldSpecialFall2022HealerText": "Left Peeker Eye", "shieldSpecialFall2022HealerNotes": "Eye Two, look upon this costume and tremble. Increases Constitution by <%= con %>. Limited Edition 2022 Fall Gear.", + "shieldSpecialWinter2023WarriorText": "Oyster Shield", + "shieldSpecialWinter2023WarriorNotes": "The time has come, the Walrus said, to talk of many things: of oyster shells—and winter bells—of songs that someone sings—and where this shield’s pearl has gone—or what the new year brings! Increases Constitution by <%= con %>. Limited Edition 2022-2023 Winter Gear.", + "shieldSpecialWinter2023HealerText": "Cool Jams", + "shieldSpecialWinter2023HealerNotes": "Your song of frost and snow will soothe the spirits of all who hear. Increases Constitution by <%= con %>. Limited Edition 2022-2023 Winter Gear.", + "shieldMystery201601Text": "Resolution Slayer", "shieldMystery201601Notes": "This blade can be used to parry away all distractions. Confers no benefit. January 2016 Subscriber Item.", "shieldMystery201701Text": "Time-Freezer Shield", diff --git a/website/common/locales/en/limited.json b/website/common/locales/en/limited.json index 1c9dbebdb8..5e7e96b345 100644 --- a/website/common/locales/en/limited.json +++ b/website/common/locales/en/limited.json @@ -191,6 +191,10 @@ "fall2022OrcWarriorSet": "Orc (Warrior)", "fall2022HarpyMageSet": "Harpy (Mage)", "fall2022WatcherHealerSet": "Peeker (Healer)", + "winter2023WalrusWarriorSet": "Walrus (Warrior)", + "winter2023FairyLightsMageSet": "Fairy Lights (Mage)", + "winter2023CardinalHealerSet": "Cardinal (Healer)", + "spring2023RibbonRogueSet": "Ribbon (Rogue)", "eventAvailability": "Available for purchase until <%= date(locale) %>.", "eventAvailabilityReturning": "Available for purchase until <%= availableDate(locale) %>. This potion was last available in <%= previousDate(locale) %>.", "dateEndJanuary": "January 31", diff --git a/website/common/script/content/appearance/sets.js b/website/common/script/content/appearance/sets.js index 65152186c0..942b70f2ad 100644 --- a/website/common/script/content/appearance/sets.js +++ b/website/common/script/content/appearance/sets.js @@ -18,7 +18,7 @@ export default prefill({ setPrice: 5, availableFrom: '2022-10-04T08:00-04:00', availableUntil: EVENTS.fall2022.end, text: t('hauntedColors'), }, winteryHairColors: { - setPrice: 5, availableFrom: '2021-12-23T08:00-05:00', availableUntil: '2022-01-31T20:00-05:00', text: t('winteryColors'), + setPrice: 5, availableFrom: '2021-12-23T08:00-05:00', availableUntil: EVENTS.winter2023.end, text: t('winteryColors'), }, rainbowSkins: { setPrice: 5, text: t('rainbowSkins') }, animalSkins: { setPrice: 5, text: t('animalSkins') }, @@ -33,6 +33,6 @@ export default prefill({ setPrice: 5, availableFrom: '2022-07-05T08:00-05:00', availableUntil: EVENTS.summer2022.end, text: t('splashySkins'), }, winterySkins: { - setPrice: 5, availableFrom: '2021-12-23T08:00-05:00', availableUntil: '2022-01-31T20:00-05:00', text: t('winterySkins'), + setPrice: 5, availableFrom: '2023-01-17T08:00-05:00', availableUntil: EVENTS.winter2023.end, text: t('winterySkins'), }, }); diff --git a/website/common/script/content/bundles.js b/website/common/script/content/bundles.js index cb4e982fee..8214d474a6 100644 --- a/website/common/script/content/bundles.js +++ b/website/common/script/content/bundles.js @@ -85,8 +85,9 @@ const bundles = { 'evilsanta2', 'penguin', ], + event: EVENTS.winter2023, canBuy () { - return moment().isBetween('2022-01-11T08:00-05:00', '2022-01-31T20:00-05:00'); + return moment().isBetween(EVENTS.winter2023.start, EVENTS.winter2023.end); }, type: 'quests', value: 7, diff --git a/website/common/script/content/constants/events.js b/website/common/script/content/constants/events.js index 2a8ff2cfc6..c3e8522062 100644 --- a/website/common/script/content/constants/events.js +++ b/website/common/script/content/constants/events.js @@ -10,11 +10,18 @@ const gemsPromo = { export const EVENTS = { noEvent: { - start: '2022-11-27T20:00-05:00', - end: '2022-12-20T08:00-05:00', + start: '2023-01-31T20:00-05:00', + end: '2023-02-14T08:00-05:00', season: 'normal', npcImageSuffix: '', }, + winter2023: { + start: '2022-12-20T08:00-05:00', + end: '2023-01-31T23:59-05:00', + npcImageSuffix: '_winter', + season: 'winter', + gear: true, + }, g1g12022: { start: '2022-12-15T08:00-05:00', end: '2023-01-08T23:59-05:00', diff --git a/website/common/script/content/constants/seasonalSets.js b/website/common/script/content/constants/seasonalSets.js index 009ee62321..9af7043ce5 100644 --- a/website/common/script/content/constants/seasonalSets.js +++ b/website/common/script/content/constants/seasonalSets.js @@ -47,6 +47,11 @@ const SEASONAL_SETS = { 'winter2022StockingWarriorSet', 'winter2022PomegranateMageSet', 'winter2022IceCrystalHealerSet', + + 'winter2023RibbonRogueSet', + 'winter2023WalrusWarriorSet', + 'winter2023FairyLightsMageSet', + 'winter2023CardinalHealerSet', ], spring: [ // spring 2014 diff --git a/website/common/script/content/gear/sets/special/index.js b/website/common/script/content/gear/sets/special/index.js index 55f9c2d7a6..485e54ec83 100644 --- a/website/common/script/content/gear/sets/special/index.js +++ b/website/common/script/content/gear/sets/special/index.js @@ -718,27 +718,35 @@ const armor = { }, winter2022Rogue: { set: 'winter2022FireworksRogueSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'winter', }, winter2022Warrior: { set: 'winter2022StockingWarriorSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'winter', }, winter2022Mage: { set: 'winter2022PomegranateMageSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'winter', }, winter2022Healer: { set: 'winter2022IceCrystalHealerSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'winter', }, spring2022Rogue: { set: 'spring2022MagpieRogueSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'spring', }, spring2022Warrior: { set: 'spring2022RainstormWarriorSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'spring', }, spring2022Mage: { set: 'spring2022ForsythiaMageSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'spring', }, spring2022Healer: { set: 'spring2022PeridotHealerSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'spring', }, birthday2022: { text: t('armorSpecialBirthday2022Text'), @@ -748,27 +756,47 @@ const armor = { }, summer2022Rogue: { set: 'summer2022CrabRogueSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'summer', }, summer2022Warrior: { set: 'summer2022WaterspoutWarriorSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'summer', }, summer2022Mage: { set: 'summer2022MantaRayMageSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'summer', }, summer2022Healer: { set: 'summer2022AngelfishHealerSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'summer', }, fall2022Rogue: { set: 'fall2022KappaRogueSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'fall', }, fall2022Warrior: { set: 'fall2022OrcWarriorSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'fall', }, fall2022Mage: { set: 'fall2022HarpyMageSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'fall', }, fall2022Healer: { set: 'fall2022WatcherHealerSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'fall', + }, + winter2023Rogue: { + set: 'winter2023RibbonRogueSet', + }, + winter2023Warrior: { + set: 'winter2023WalrusWarriorSet', + }, + winter2023Mage: { + set: 'winter2023FairyLightsMageSet', + }, + winter2023Healer: { + set: 'winter2023CardinalHealerSet', }, }; @@ -1824,15 +1852,19 @@ const head = { }, winter2022Rogue: { set: 'winter2022FireworksRogueSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'winter', }, winter2022Warrior: { set: 'winter2022StockingWarriorSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'winter', }, winter2022Mage: { set: 'winter2022PomegranateMageSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'winter', }, winter2022Healer: { set: 'winter2022IceCrystalHealerSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'winter', }, nye2021: { text: t('headSpecialNye2021Text'), @@ -1842,39 +1874,63 @@ const head = { }, spring2022Rogue: { set: 'spring2022MagpieRogueSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'spring', }, spring2022Warrior: { set: 'spring2022RainstormWarriorSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'spring', }, spring2022Mage: { set: 'spring2022ForsythiaMageSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'spring', }, spring2022Healer: { set: 'spring2022PeridotHealerSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'spring', }, summer2022Rogue: { set: 'summer2022CrabRogueSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'summer', }, summer2022Warrior: { set: 'summer2022WaterspoutWarriorSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'summer', }, summer2022Mage: { set: 'summer2022MantaRayMageSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'summer', }, summer2022Healer: { set: 'summer2022AngelfishHealerSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'summer', }, fall2022Rogue: { set: 'fall2022KappaRogueSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'fall', }, fall2022Warrior: { set: 'fall2022OrcWarriorSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'fall', }, fall2022Mage: { set: 'fall2022HarpyMageSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'fall', }, fall2022Healer: { set: 'fall2022WatcherHealerSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'fall', + }, + winter2023Rogue: { + set: 'winter2023RibbonRogueSet', + }, + winter2023Warrior: { + set: 'winter2023WalrusWarriorSet', + }, + winter2023Mage: { + set: 'winter2023FairyLightsMageSet', + }, + winter2023Healer: { + set: 'winter2023CardinalHealerSet', }, }; @@ -2285,7 +2341,6 @@ const shield = { }, spring2015Rogue: { set: 'sneakySqueakerSet', - event: EVENTS.spring2021, canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'spring', }, spring2015Warrior: { @@ -2636,39 +2691,60 @@ const shield = { }, winter2022Rogue: { set: 'winter2022FireworksRogueSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'winter', }, winter2022Warrior: { set: 'winter2022StockingWarriorSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'winter', }, winter2022Healer: { set: 'winter2022IceCrystalHealerSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'winter', }, spring2022Rogue: { set: 'spring2022MagpieRogueSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'spring', }, spring2022Warrior: { set: 'spring2022RainstormWarriorSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'spring', }, spring2022Healer: { set: 'spring2022PeridotHealerSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'summer', }, summer2022Rogue: { set: 'summer2022CrabRogueSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'summer', }, summer2022Warrior: { set: 'summer2022WaterspoutWarriorSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'summer', }, summer2022Healer: { set: 'summer2022AngelfishHealerSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'summer', }, fall2022Rogue: { set: 'fall2022KappaRogueSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'fall', }, fall2022Warrior: { set: 'fall2022OrcWarriorSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'fall', }, fall2022Healer: { set: 'fall2022WatcherHealerSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'fall', + }, + winter2023Rogue: { + set: 'winter2023RibbonRogueSet', + }, + winter2023Warrior: { + set: 'winter2023WalrusWarriorSet', + }, + winter2023Healer: { + set: 'winter2023CardinalHealerSet', }, }; @@ -3348,51 +3424,79 @@ const weapon = { }, winter2022Rogue: { set: 'winter2022FireworksRogueSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'winter', }, winter2022Warrior: { set: 'winter2022StockingWarriorSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'winter', }, winter2022Mage: { set: 'winter2022PomegranateMageSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'winter', }, winter2022Healer: { set: 'winter2022IceCrystalHealerSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'winter', }, spring2022Rogue: { set: 'spring2022MagpieRogueSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'spring', }, spring2022Warrior: { set: 'spring2022RainstormWarriorSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'spring', }, spring2022Mage: { set: 'spring2022ForsythiaMageSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'spring', }, spring2022Healer: { set: 'spring2022PeridotHealerSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'spring', }, summer2022Rogue: { set: 'summer2022CrabRogueSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'summer', }, summer2022Warrior: { set: 'summer2022WaterspoutWarriorSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'summer', }, summer2022Mage: { set: 'summer2022MantaRayMageSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'summer', }, summer2022Healer: { set: 'summer2022AngelfishHealerSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'summer', }, fall2022Rogue: { set: 'fall2022KappaRogueSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'fall', }, fall2022Warrior: { set: 'fall2022OrcWarriorSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'fall', }, fall2022Mage: { set: 'fall2022HarpyMageSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'fall', }, fall2022Healer: { set: 'fall2022WatcherHealerSet', + canBuy: () => CURRENT_EVENT && CURRENT_EVENT.season === 'fall', + }, + winter2023Rogue: { + set: 'winter2023RibbonRogueSet', + }, + winter2023Warrior: { + set: 'winter2023WalrusWarriorSet', + }, + winter2023Mage: { + set: 'winter2023FairyLightsMageSet', + }, + winter2023Healer: { + set: 'winter2023CardinalHealerSet', }, }; diff --git a/website/common/script/content/hatching-potions.js b/website/common/script/content/hatching-potions.js index a2e40396c2..9ba437243d 100644 --- a/website/common/script/content/hatching-potions.js +++ b/website/common/script/content/hatching-potions.js @@ -176,11 +176,11 @@ const premium = { limited: true, _addlNotes: t('eventAvailabilityReturning', { availableDate: t('dateEndJanuary'), - previousDate: t('januaryYYYY', { year: 2020 }), + previousDate: t('januaryYYYY', { year: 2022 }), }), - event: EVENTS.winter2022, + event: EVENTS.winter2023, canBuy () { - return moment().isBetween(EVENTS.winter2022.start, EVENTS.winter2022.end); + return moment().isBetween(EVENTS.winter2023.start, EVENTS.winter2023.end); }, }, Peppermint: { @@ -200,12 +200,13 @@ const premium = { value: 2, text: t('hatchingPotionStarryNight'), limited: true, + event: EVENTS.winter2023, canBuy () { - return moment().isBetween('2019-12-19', '2020-02-02'); + return moment().isBetween(EVENTS.winter2023.start, EVENTS.winter2023.end); }, _addlNotes: t('eventAvailabilityReturning', { availableDate: t('dateEndJanuary'), - previousDate: t('decemberYYYY', { year: 2017 }), + previousDate: t('decemberYYYY', { year: 2019 }), }), }, Rainbow: { @@ -360,11 +361,11 @@ const premium = { limited: true, _addlNotes: t('eventAvailabilityReturning', { availableDate: t('dateEndJanuary'), - previousDate: t('decemberYYYY', { year: 2019 }), + previousDate: t('decemberYYYY', { year: 2020 }), }), - event: EVENTS.winter2021, + event: EVENTS.winter2023, canBuy () { - return moment().isBetween('2020-12-22T08:00-04:00', '2021-01-31T20:00-04:00'); + return moment().isBetween(EVENTS.winter2023.start, EVENTS.winter2023.end); }, }, Ruby: { diff --git a/website/common/script/content/shop-featuredItems.js b/website/common/script/content/shop-featuredItems.js index 031d7d3a9c..44ae32f7f7 100644 --- a/website/common/script/content/shop-featuredItems.js +++ b/website/common/script/content/shop-featuredItems.js @@ -5,7 +5,7 @@ import { EVENTS } from './constants'; // path: 'premiumHatchingPotions.Rainbow', const featuredItems = { market () { - if (moment().isBetween(EVENTS.bundle202211.start, EVENTS.bundle202211.end)) { + if (moment().isBetween(EVENTS.winter2023.start, EVENTS.winter2023.end)) { return [ { type: 'armoire', @@ -13,15 +13,15 @@ const featuredItems = { }, { type: 'premiumHatchingPotion', - path: 'premiumHatchingPotions.Frost', + path: 'premiumHatchingPotions.StarryNight', }, { type: 'premiumHatchingPotion', - path: 'premiumHatchingPotions.Ember', + path: 'premiumHatchingPotions.Holly', }, { type: 'premiumHatchingPotion', - path: 'premiumHatchingPotions.Thunderstorm', + path: 'premiumHatchingPotions.Aurora', }, ]; } @@ -32,51 +32,51 @@ const featuredItems = { }, { type: 'food', - path: 'food.Milk', + path: 'food.RottenMeat', }, { type: 'hatchingPotions', - path: 'hatchingPotions.White', + path: 'hatchingPotions.CottonCandyBlue', }, { type: 'eggs', - path: 'eggs.Fox', + path: 'eggs.FlyingPig', }, ]; }, quests () { - if (moment().isBetween(EVENTS.bundle202211.start, EVENTS.bundle202211.end)) { + if (moment().isBetween(EVENTS.winter2023.start, EVENTS.winter2023.end)) { return [ { type: 'bundles', - path: 'bundles.rockingReptiles', + path: 'bundles.winterQuests', }, { type: 'quests', - path: 'quests.peacock', + path: 'quests.whale', }, { type: 'quests', - path: 'quests.harpy', + path: 'quests.turtle', }, ]; } return [ { type: 'quests', - path: 'quests.axolotl', + path: 'quests.slime', }, { type: 'quests', - path: 'quests.stone', + path: 'quests.seaserpent', }, { type: 'quests', - path: 'quests.whale', + path: 'quests.unicorn', }, ]; }, - seasonal: 'spring2021Healer', + seasonal: 'winter2022Healer', timeTravelers: [ // TODO ], diff --git a/website/common/script/libs/shops-seasonal.config.js b/website/common/script/libs/shops-seasonal.config.js index 077a011288..fc6c64fde3 100644 --- a/website/common/script/libs/shops-seasonal.config.js +++ b/website/common/script/libs/shops-seasonal.config.js @@ -30,23 +30,24 @@ export default { pinnedSets: SHOP_OPEN ? { - healer: 'fall2022WatcherHealerSet', - rogue: 'fall2022KappaRogueSet', - warrior: 'fall2022OrcWarriorSet', - wizard: 'fall2022HarpyMageSet', + rogue: 'winter2023RibbonRogueSet', + warrior: 'winter2023WalrusWarriorSet', + wizard: 'winter2023FairyLightsMageSet', + healer: 'winter2023CardinalHealerSet', } : {}, - availableSpells: SHOP_OPEN && moment().isBetween('2022-10-04T08:00-05:00', CURRENT_EVENT.end) + availableSpells: SHOP_OPEN && moment().isBetween('2022-12-27T08:00-05:00', CURRENT_EVENT.end) ? [ - 'spookySparkles', + 'snowball', ] : [], - availableQuests: SHOP_OPEN && CURRENT_EVENT.season === 'spring' + availableQuests: SHOP_OPEN && CURRENT_EVENT.season === 'winter' ? [ - 'egg', + 'evilsanta', + 'evilsanta2', ] : [], - featuredSet: 'fall2021BrainEaterMageSet', + featuredSet: 'winter2022PomegranateMageSet', }; From 64bf4ee4b63288c6c7fd4aba72d19df43cf3f372 Mon Sep 17 00:00:00 2001 From: SabreCat Date: Mon, 19 Dec 2022 16:22:20 -0600 Subject: [PATCH 11/12] fix(tests): if singleton event, always provide empty string suffix --- website/server/libs/worldState.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/website/server/libs/worldState.js b/website/server/libs/worldState.js index 257ab1879f..68e7081bc9 100644 --- a/website/server/libs/worldState.js +++ b/website/server/libs/worldState.js @@ -27,6 +27,9 @@ export function getCurrentEvent () { }); if (!currEvtKey) return null; + if (!common.content.events[currEvtKey].npcImageSuffix) { + common.content.events[currEvtKey].npcImageSuffix = ''; + } return { event: currEvtKey, ...common.content.events[currEvtKey], From c6d36ad6b15dd36c15783219ad7c78a80fec887f Mon Sep 17 00:00:00 2001 From: SabreCat Date: Mon, 19 Dec 2022 16:22:28 -0600 Subject: [PATCH 12/12] 4.253.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 06efc5575f..cbdddb9d09 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "habitica", - "version": "4.252.2", + "version": "4.253.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index c26709d46f..0718e0200f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "habitica", "description": "A habit tracker app which treats your goals like a Role Playing Game.", - "version": "4.252.2", + "version": "4.253.0", "main": "./website/server/index.js", "dependencies": { "@babel/core": "^7.19.6",