diff --git a/migrations/archive/2020/20201020_pet_color_achievements.js b/migrations/archive/2020/20201020_pet_color_achievements.js new file mode 100644 index 0000000000..d2eb4dac81 --- /dev/null +++ b/migrations/archive/2020/20201020_pet_color_achievements.js @@ -0,0 +1,82 @@ +/* eslint-disable no-console */ +const MIGRATION_NAME = '20201020_pet_color_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['Wolf-Golden'] > 0 + && pets['TigerCub-Skeleton'] > 0 + && pets['PandaCub-Skeleton'] > 0 + && pets['LionCub-Skeleton'] > 0 + && pets['Fox-Skeleton'] > 0 + && pets['FlyingPig-Skeleton'] > 0 + && pets['Dragon-Skeleton'] > 0 + && pets['Cactus-Skeleton'] > 0 + && pets['BearCub-Skeleton'] > 0) { + set['achievements.boneCollector'] = true; + } + } + + if (user && user.items && user.items.mounts) { + const mounts = user.items.mounts; + if (mounts['Wolf-Skeleton'] + && mounts['TigerCub-Skeleton'] + && mounts['PandaCub-Skeleton'] + && mounts['LionCub-Skeleton'] + && mounts['Fox-Skeleton'] + && mounts['FlyingPig-Skeleton'] + && mounts['Dragon-Skeleton'] + && mounts['Cactus-Skeleton'] + && mounts['BearCub-Skeleton'] ) { + set['achievements.skeletonCrew'] = true; + } + } + + if (count % progressCount === 0) console.warn(`${count} ${user._id}`); + + return await User.update({ _id: user._id }, { $set: set }).exec(); +} + +module.exports = async function processUsers () { + let query = { + migration: { $ne: MIGRATION_NAME }, + 'auth.timestamps.loggedin': { $gt: new Date('2020-10-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/package-lock.json b/package-lock.json index 25cbc46fab..7cec6fdcd5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "habitica", - "version": "4.165.3", + "version": "4.166.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 459086ccb7..90ced55a7b 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.165.3", + "version": "4.166.0", "main": "./website/server/index.js", "dependencies": { "@babel/core": "^7.12.3", diff --git a/website/client/src/assets/css/sprites/spritesmith-largeSprites-0.css b/website/client/src/assets/css/sprites/spritesmith-largeSprites-0.css index 9a9c9b2841..9e90b8e983 100644 --- a/website/client/src/assets/css/sprites/spritesmith-largeSprites-0.css +++ b/website/client/src/assets/css/sprites/spritesmith-largeSprites-0.css @@ -1,60 +1,66 @@ .promo_armoire_backgrounds_202010 { background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png'); - background-position: 0px -452px; + background-position: 0px -639px; width: 423px; height: 147px; } .promo_fall_customizations { background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png'); - background-position: 0px -244px; + background-position: -532px 0px; width: 336px; height: 207px; } .promo_fall_festival_2019 { background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png'); - background-position: -532px 0px; + background-position: 0px -449px; width: 360px; height: 189px; } .promo_fall_festival_2020 { background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png'); - background-position: -532px -190px; + background-position: -361px -449px; width: 360px; height: 174px; } .promo_mystery_202009 { background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png'); - background-position: -893px 0px; + background-position: -869px -296px; width: 282px; height: 147px; } .promo_mystery_202010 { background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png'); - background-position: -893px -148px; + background-position: -869px -444px; width: 282px; height: 147px; } .promo_sandy_sidekicks_bundle { background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png'); - background-position: -424px -600px; + background-position: -869px -148px; width: 420px; height: 147px; } +.promo_skeleton_achievements { + background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png'); + background-position: 0px -244px; + width: 366px; + height: 204px; +} .promo_spooky_sparkles { background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png'); - background-position: -424px -452px; + background-position: -424px -639px; width: 423px; height: 147px; } .promo_take_this { background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png'); - background-position: -1035px -426px; + background-position: -1152px -296px; width: 96px; height: 69px; } .promo_vampire_potions { background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png'); - background-position: 0px -600px; + background-position: -869px 0px; width: 423px; height: 147px; } @@ -66,13 +72,13 @@ } .scene_squall { background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png'); - background-position: -893px -426px; + background-position: -532px -208px; width: 141px; height: 169px; } .scene_strength { background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png'); - background-position: -893px -296px; + background-position: -869px -592px; width: 192px; height: 129px; } diff --git a/website/client/src/assets/css/sprites/spritesmith-main-0.css b/website/client/src/assets/css/sprites/spritesmith-main-0.css index 6b45fbd125..fc9df69bf4 100644 --- a/website/client/src/assets/css/sprites/spritesmith-main-0.css +++ b/website/client/src/assets/css/sprites/spritesmith-main-0.css @@ -1,12 +1,12 @@ .achievement-alien { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -1671px -1480px; + background-position: -1568px -1628px; width: 24px; height: 26px; } .achievement-alien2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -524px -1549px; + background-position: -622px -1549px; width: 48px; height: 52px; } @@ -24,7 +24,7 @@ } .achievement-alpha2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -573px -1549px; + background-position: -671px -1549px; width: 48px; height: 52px; } @@ -36,13 +36,13 @@ } .achievement-armor2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -622px -1549px; + background-position: -720px -1549px; width: 48px; height: 52px; } .achievement-backToBasics2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -1279px -1480px; + background-position: -1344px -1480px; width: 48px; height: 56px; } @@ -54,25 +54,31 @@ } .achievement-bewilder2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -671px -1549px; + background-position: -769px -1549px; width: 48px; height: 52px; } .achievement-birthday2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -720px -1549px; + background-position: -818px -1549px; width: 48px; height: 52px; } +.achievement-boneCollector2x { + background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); + background-position: -1393px -1480px; + width: 48px; + height: 56px; +} .achievement-boot2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -769px -1549px; + background-position: -867px -1549px; width: 48px; height: 52px; } .achievement-bow2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -818px -1549px; + background-position: -916px -1549px; width: 48px; height: 52px; } @@ -84,85 +90,85 @@ } .achievement-burnout2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -867px -1549px; + background-position: -965px -1549px; width: 48px; height: 52px; } .achievement-cactus2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -916px -1549px; + background-position: -1014px -1549px; width: 48px; height: 52px; } .achievement-cake2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -965px -1549px; + background-position: -1063px -1549px; width: 48px; height: 52px; } .achievement-cave2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -1014px -1549px; + background-position: -1112px -1549px; width: 48px; height: 52px; } .achievement-challenge2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -1063px -1549px; + background-position: -1161px -1549px; width: 48px; height: 52px; } .achievement-comment2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -1112px -1549px; + background-position: -1210px -1549px; width: 48px; height: 52px; } .achievement-completedTask2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -1328px -1480px; + background-position: -1442px -1480px; width: 48px; height: 56px; } .achievement-congrats2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -1161px -1549px; + background-position: -1259px -1549px; width: 48px; height: 52px; } .achievement-costumeContest2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -1210px -1549px; + background-position: -1308px -1549px; width: 48px; height: 52px; } .achievement-createdTask2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -1377px -1480px; + background-position: -1491px -1480px; width: 48px; height: 56px; } .achievement-dilatory2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -1259px -1549px; + background-position: -1357px -1549px; width: 48px; height: 52px; } .achievement-dustDevil2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -1426px -1480px; + background-position: -1540px -1480px; width: 48px; height: 56px; } .achievement-dysheartener2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -1308px -1549px; + background-position: -1406px -1549px; width: 48px; height: 52px; } .achievement-fedPet2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -1475px -1480px; + background-position: -1589px -1480px; width: 48px; height: 56px; } @@ -174,61 +180,61 @@ } .achievement-friends2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -1357px -1549px; + background-position: -1455px -1549px; width: 48px; height: 52px; } .achievement-getwell2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -1406px -1549px; + background-position: -1504px -1549px; width: 48px; height: 52px; } .achievement-goodAsGold2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -1524px -1480px; + background-position: -1638px -1480px; width: 48px; height: 56px; } .achievement-goodluck2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -1455px -1549px; + background-position: -1553px -1549px; width: 48px; height: 52px; } .achievement-greeting2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -1504px -1549px; + background-position: -1602px -1549px; width: 48px; height: 52px; } .achievement-guild2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -1553px -1549px; + background-position: -1651px -1549px; width: 48px; height: 52px; } .achievement-habitBirthday2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -1602px -1549px; + background-position: 0px -1628px; width: 48px; height: 52px; } .achievement-habiticaDay2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -1651px -1549px; + background-position: -49px -1628px; width: 48px; height: 52px; } .achievement-hatchedPet2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -1573px -1480px; + background-position: -426px -1549px; width: 48px; height: 56px; } .achievement-heart2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: 0px -1628px; + background-position: -98px -1628px; width: 48px; height: 52px; } @@ -240,13 +246,13 @@ } .achievement-karaoke-2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -49px -1628px; + background-position: -147px -1628px; width: 48px; height: 52px; } .achievement-karaoke { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -1671px -1507px; + background-position: -1593px -1628px; width: 24px; height: 26px; } @@ -258,7 +264,7 @@ } .achievement-lostMasterclasser2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -98px -1628px; + background-position: -196px -1628px; width: 48px; height: 52px; } @@ -270,37 +276,37 @@ } .achievement-monsterMagus2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -1622px -1480px; + background-position: -475px -1549px; width: 48px; height: 56px; } .achievement-ninja2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -147px -1628px; + background-position: -245px -1628px; width: 48px; height: 52px; } .achievement-npc2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -196px -1628px; + background-position: -294px -1628px; width: 48px; height: 52px; } .achievement-nye2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -245px -1628px; + background-position: -343px -1628px; width: 48px; height: 52px; } .achievement-partyOn2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -294px -1628px; + background-position: -392px -1628px; width: 48px; height: 52px; } .achievement-partyUp2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -343px -1628px; + background-position: -441px -1628px; width: 48px; height: 52px; } @@ -312,25 +318,25 @@ } .achievement-perfect2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -392px -1628px; + background-position: -490px -1628px; width: 48px; height: 52px; } .achievement-primedForPainting2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -426px -1549px; + background-position: -524px -1549px; width: 48px; height: 56px; } .achievement-purchasedEquipment2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -475px -1549px; + background-position: -573px -1549px; width: 48px; height: 56px; } .achievement-rat2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -441px -1628px; + background-position: -539px -1628px; width: 48px; height: 52px; } @@ -342,70 +348,76 @@ } .achievement-royally-loyal2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -490px -1628px; + background-position: -588px -1628px; width: 48px; height: 52px; } .achievement-seafoam2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -539px -1628px; + background-position: -637px -1628px; width: 48px; height: 52px; } .achievement-shield2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -588px -1628px; + background-position: -686px -1628px; width: 48px; height: 52px; } .achievement-shinySeed2x { - background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -637px -1628px; - width: 48px; - height: 52px; -} -.achievement-snowball2x { - background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -686px -1628px; - width: 48px; - height: 52px; -} -.achievement-spookySparkles2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); background-position: -735px -1628px; width: 48px; height: 52px; } -.achievement-stoikalm2x { +.achievement-skeletonCrew2x { + background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); + background-position: -1214px -1480px; + width: 64px; + height: 56px; +} +.achievement-snowball2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); background-position: -784px -1628px; width: 48px; height: 52px; } -.achievement-sun2x { +.achievement-spookySparkles2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); background-position: -833px -1628px; width: 48px; height: 52px; } -.achievement-sword2x { +.achievement-stoikalm2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); background-position: -882px -1628px; width: 48px; height: 52px; } -.achievement-thankyou2x { +.achievement-sun2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); background-position: -931px -1628px; width: 48px; height: 52px; } -.achievement-thermometer2x { +.achievement-sword2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); background-position: -980px -1628px; width: 48px; height: 52px; } +.achievement-thankyou2x { + background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); + background-position: -1029px -1628px; + width: 48px; + height: 52px; +} +.achievement-thermometer2x { + background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); + background-position: -1078px -1628px; + width: 48px; + height: 52px; +} .achievement-tickledPink2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); background-position: -702px -1480px; @@ -414,61 +426,61 @@ } .achievement-tree2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -1029px -1628px; + background-position: -1127px -1628px; width: 48px; height: 52px; } .achievement-triadbingo2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -1078px -1628px; + background-position: -1176px -1628px; width: 48px; height: 52px; } .achievement-ultimate-healer2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -1127px -1628px; + background-position: -1225px -1628px; width: 48px; height: 52px; } .achievement-ultimate-mage2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -1176px -1628px; + background-position: -1274px -1628px; width: 48px; height: 52px; } .achievement-ultimate-rogue2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -1225px -1628px; + background-position: -1323px -1628px; width: 48px; height: 52px; } .achievement-ultimate-warrior2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -1274px -1628px; + background-position: -1372px -1628px; width: 48px; height: 52px; } .achievement-undeadUndertaker2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -1214px -1480px; + background-position: -1279px -1480px; width: 64px; height: 56px; } .achievement-unearned2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -1323px -1628px; + background-position: -1421px -1628px; width: 48px; height: 52px; } .achievement-valentine2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -1372px -1628px; + background-position: -1470px -1628px; width: 48px; height: 52px; } .achievement-wolf2x { background-image: url('~@/assets/images/sprites/spritesmith-main-0.png'); - background-position: -1421px -1628px; + background-position: -1519px -1628px; width: 48px; height: 52px; } diff --git a/website/client/src/assets/images/sprites/spritesmith-largeSprites-0.png b/website/client/src/assets/images/sprites/spritesmith-largeSprites-0.png index ed78772562..a72dc4aa78 100644 Binary files a/website/client/src/assets/images/sprites/spritesmith-largeSprites-0.png and b/website/client/src/assets/images/sprites/spritesmith-largeSprites-0.png differ diff --git a/website/client/src/assets/images/sprites/spritesmith-main-0.png b/website/client/src/assets/images/sprites/spritesmith-main-0.png index adedf5e87b..f978c706be 100644 Binary files a/website/client/src/assets/images/sprites/spritesmith-main-0.png and b/website/client/src/assets/images/sprites/spritesmith-main-0.png differ diff --git a/website/client/src/components/notifications.vue b/website/client/src/components/notifications.vue index d6c8e4c563..cfc7b9097f 100644 --- a/website/client/src/components/notifications.vue +++ b/website/client/src/components/notifications.vue @@ -188,7 +188,7 @@ const NOTIFICATIONS = { label: $t => `${$t('achievement')}: ${$t('achievementBackToBasics')}`, modalId: 'generic-achievement', data: { - achievement: 'backToBasics', // defined manually until the server sends all the necessary data + achievement: 'backToBasics', }, }, ACHIEVEMENT_DUST_DEVIL: { @@ -196,7 +196,7 @@ const NOTIFICATIONS = { label: $t => `${$t('achievement')}: ${$t('achievementDustDevil')}`, modalId: 'generic-achievement', data: { - achievement: 'dustDevil', // defined manually until the server sends all the necessary data + achievement: 'dustDevil', }, }, ACHIEVEMENT_ARID_AUTHORITY: { @@ -204,7 +204,7 @@ const NOTIFICATIONS = { label: $t => `${$t('achievement')}: ${$t('achievementAridAuthority')}`, modalId: 'generic-achievement', data: { - achievement: 'aridAuthority', // defined manually until the server sends all the necessary data + achievement: 'aridAuthority', }, }, ACHIEVEMENT_PARTY_UP: { @@ -214,7 +214,7 @@ const NOTIFICATIONS = { data: { message: $t => $t('achievement'), modalText: $t => $t('achievementPartyUp'), - achievement: 'partyUp', // defined manually until the server sends all the necessary data + achievement: 'partyUp', }, }, ACHIEVEMENT_PARTY_ON: { @@ -224,7 +224,7 @@ const NOTIFICATIONS = { data: { message: $t => $t('achievement'), modalText: $t => $t('achievementPartyOn'), - achievement: 'partyOn', // defined manually until the server sends all the necessary data + achievement: 'partyOn', }, }, ACHIEVEMENT_BEAST_MASTER: { @@ -234,7 +234,7 @@ const NOTIFICATIONS = { data: { message: $t => $t('achievement'), modalText: $t => $t('beastAchievement'), - achievement: 'beastMaster', // defined manually until the server sends all the necessary data + achievement: 'beastMaster', }, }, ACHIEVEMENT_MOUNT_MASTER: { @@ -244,7 +244,7 @@ const NOTIFICATIONS = { data: { message: $t => $t('achievement'), modalText: $t => $t('mountAchievement'), - achievement: 'mountMaster', // defined manually until the server sends all the necessary data + achievement: 'mountMaster', }, }, ACHIEVEMENT_TRIAD_BINGO: { @@ -254,7 +254,7 @@ const NOTIFICATIONS = { data: { message: $t => $t('achievement'), modalText: $t => $t('triadBingoAchievement'), - achievement: 'triadBingo', // defined manually until the server sends all the necessary data + achievement: 'triadBingo', }, }, ACHIEVEMENT_MONSTER_MAGUS: { @@ -262,7 +262,7 @@ const NOTIFICATIONS = { label: $t => `${$t('achievement')}: ${$t('achievementMonsterMagus')}`, modalId: 'generic-achievement', data: { - achievement: 'monsterMagus', // defined manually until the server sends all the necessary data + achievement: 'monsterMagus', }, }, ACHIEVEMENT_UNDEAD_UNDERTAKER: { @@ -270,7 +270,7 @@ const NOTIFICATIONS = { label: $t => `${$t('achievement')}: ${$t('achievementUndeadUndertaker')}`, modalId: 'generic-achievement', data: { - achievement: 'undeadUndertaker', // defined manually until the server sends all the necessary data + achievement: 'undeadUndertaker', }, }, ACHIEVEMENT: { // data filled in handleUserNotifications @@ -287,7 +287,7 @@ const NOTIFICATIONS = { label: $t => `${$t('achievement')}: ${$t('achievementPrimedForPainting')}`, modalId: 'generic-achievement', data: { - achievement: 'primedForPainting', // defined manually until the server sends all the necessary data + achievement: 'primedForPainting', }, }, ACHIEVEMENT_PEARLY_PRO: { @@ -295,7 +295,7 @@ const NOTIFICATIONS = { label: $t => `${$t('achievement')}: ${$t('achievementPearlyPro')}`, modalId: 'generic-achievement', data: { - achievement: 'pearlyPro', // defined manually until the server sends all the necessary data + achievement: 'pearlyPro', }, }, ACHIEVEMENT_TICKLED_PINK: { @@ -303,7 +303,7 @@ const NOTIFICATIONS = { label: $t => `${$t('achievement')}: ${$t('achievementTickledPink')}`, modalId: 'generic-achievement', data: { - achievement: 'tickledPink', // defined manually until the server sends all the necessary data + achievement: 'tickledPink', }, }, ACHIEVEMENT_ROSY_OUTLOOK: { @@ -311,7 +311,7 @@ const NOTIFICATIONS = { label: $t => `${$t('achievement')}: ${$t('achievementRosyOutlook')}`, modalId: 'generic-achievement', data: { - achievement: 'rosyOutlook', // defined manually until the server sends all the necessary data + achievement: 'rosyOutlook', }, }, ACHIEVEMENT_BUG_BONANZA: { @@ -319,7 +319,7 @@ const NOTIFICATIONS = { label: $t => `${$t('achievement')}: ${$t('achievementBugBonanza')}`, modalId: 'generic-achievement', data: { - achievement: 'bugBonanza', // defined manually until the server sends all the necessary data + achievement: 'bugBonanza', }, }, ACHIEVEMENT_BARE_NECESSITIES: { @@ -327,7 +327,7 @@ const NOTIFICATIONS = { label: $t => `${$t('achievement')}: ${$t('achievementBareNecessities')}`, modalId: 'generic-achievement', data: { - achievement: 'bareNecessities', // defined manually until the server sends all the necessary data + achievement: 'bareNecessities', }, }, ACHIEVEMENT_FRESHWATER_FRIENDS: { @@ -335,7 +335,7 @@ const NOTIFICATIONS = { label: $t => `${$t('achievement')}: ${$t('achievementFreshwaterFriends')}`, modalId: 'generic-achievement', data: { - achievement: 'freshwaterFriends', // defined manually until the server sends all the necessary data + achievement: 'freshwaterFriends', }, }, ACHIEVEMENT_GOOD_AS_GOLD: { @@ -343,7 +343,7 @@ const NOTIFICATIONS = { label: $t => `${$t('achievement')}: ${$t('achievementGoodAsGold')}`, modalId: 'generic-achievement', data: { - achievement: 'goodAsGold', // defined manually until the server sends all the necessary data + achievement: 'goodAsGold', }, }, ACHIEVEMENT_ALL_THAT_GLITTERS: { @@ -351,7 +351,23 @@ const NOTIFICATIONS = { label: $t => `${$t('achievement')}: ${$t('achievementAllThatGlitters')}`, modalId: 'generic-achievement', data: { - achievement: 'allThatGlitters', // defined manually until the server sends all the necessary data + achievement: 'allThatGlitters', + }, + }, + ACHIEVEMENT_BONE_COLLECTOR: { + achievement: true, + label: $t => `${$t('achievement')}: ${$t('achievementBoneCollector')}`, + modalId: 'generic-achievement', + data: { + achievement: 'boneCollector', + }, + }, + ACHIEVEMENT_SKELETON_CREW: { + achievement: true, + label: $t => `${$t('achievement')}: ${$t('achievementSkeletonCrew')}`, + modalId: 'generic-achievement', + data: { + achievement: 'skeletonCrew', }, }, }; @@ -415,6 +431,7 @@ export default { 'ACHIEVEMENT_PEARLY_PRO', 'ACHIEVEMENT_TICKLED_PINK', 'ACHIEVEMENT_ROSY_OUTLOOK', 'ACHIEVEMENT', 'ONBOARDING_COMPLETE', 'FIRST_DROPS', 'ACHIEVEMENT_BUG_BONANZA', 'ACHIEVEMENT_BARE_NECESSITIES', 'ACHIEVEMENT_FRESHWATER_FRIENDS', 'ACHIEVEMENT_GOOD_AS_GOLD', 'ACHIEVEMENT_ALL_THAT_GLITTERS', + 'ACHIEVEMENT_BONE_COLLECTOR', 'ACHIEVEMENT_SKELETON_CREW', ].forEach(type => { handledNotifications[type] = true; }); @@ -831,6 +848,8 @@ export default { case 'ACHIEVEMENT_FRESHWATER_FRIENDS': case 'ACHIEVEMENT_GOOD_AS_GOLD': case 'ACHIEVEMENT_ALL_THAT_GLITTERS': + case 'ACHIEVEMENT_BONE_COLLECTOR': + case 'ACHIEVEMENT_SKELETON_CREW': case 'GENERIC_ACHIEVEMENT': this.showNotificationWithModal(notification); break; diff --git a/website/common/locales/en/achievements.json b/website/common/locales/en/achievements.json index 694d584e10..de700eb78d 100644 --- a/website/common/locales/en/achievements.json +++ b/website/common/locales/en/achievements.json @@ -90,5 +90,11 @@ "achievementGoodAsGoldModalText": "You collected all the Golden Pets!", "achievementAllThatGlitters": "All That Glitters", "achievementAllThatGlittersText": "Has tamed all Golden Mounts.", - "achievementAllThatGlittersModalText": "You tamed all the Golden Mounts!" + "achievementAllThatGlittersModalText": "You tamed all the Golden Mounts!", + "achievementBoneCollector": "Bone Collector", + "achievementBoneCollectorText": "Has collected all Skeleton pets.", + "achievementBoneCollectorModalText": "You collected all the Skeleton Pets!", + "achievementSkeletonCrew": "Skeleton Crew", + "achievementSkeletonCrewText": "Has tamed all Skeleton Mounts.", + "achievementSkeletonCrewModalText": "You tamed all the Skeleton Mounts!" } diff --git a/website/common/script/content/achievements.js b/website/common/script/content/achievements.js index 4f808103d4..4749f29486 100644 --- a/website/common/script/content/achievements.js +++ b/website/common/script/content/achievements.js @@ -212,6 +212,16 @@ const basicAchievs = { titleKey: 'achievementAllThatGlitters', textKey: 'achievementAllThatGlittersText', }, + boneCollector: { + icon: 'achievement-boneCollector', + titleKey: 'achievementBoneCollector', + textKey: 'achievementBoneCollectorText', + }, + skeletonCrew: { + icon: 'achievement-skeletonCrew', + titleKey: 'achievementSkeletonCrew', + textKey: 'achievementSkeletonCrewText', + }, }; Object.assign(achievementsData, basicAchievs); diff --git a/website/common/script/content/constants/animalColorAchievements.js b/website/common/script/content/constants/animalColorAchievements.js index a11a969754..1be56ef0d6 100644 --- a/website/common/script/content/constants/animalColorAchievements.js +++ b/website/common/script/content/constants/animalColorAchievements.js @@ -41,6 +41,13 @@ const ANIMAL_COLOR_ACHIEVEMENTS = [ mountAchievement: 'allThatGlitters', mountNotificationType: 'ACHIEVEMENT_ALL_THAT_GLITTERS', }, + { + color: 'Skeleton', + petAchievement: 'boneCollector', + petNotificationType: 'ACHIEVEMENT_BONE_COLLECTOR', + mountAchievement: 'skeletonCrew', + mountNotificationType: 'ACHIEVEMENT_SKELETON_CREW', + }, ]; export default ANIMAL_COLOR_ACHIEVEMENTS; diff --git a/website/common/script/libs/achievements.js b/website/common/script/libs/achievements.js index 89ae2fc270..dac7e98ade 100644 --- a/website/common/script/libs/achievements.js +++ b/website/common/script/libs/achievements.js @@ -204,6 +204,8 @@ function _getBasicAchievements (user, language) { _addSimple(result, user, { path: 'freshwaterFriends', language }); _addSimple(result, user, { path: 'goodAsGold', language }); _addSimple(result, user, { path: 'allThatGlitters', language }); + _addSimple(result, user, { path: 'boneCollector', language }); + _addSimple(result, user, { path: 'skeletonCrew', language }); _addSimpleWithMasterCount(result, user, { path: 'beastMaster', language }); _addSimpleWithMasterCount(result, user, { path: 'mountMaster', language }); diff --git a/website/raw_sprites/spritesmith/achievements/achievement-boneCollector2x.png b/website/raw_sprites/spritesmith/achievements/achievement-boneCollector2x.png new file mode 100644 index 0000000000..9ad45d0c36 Binary files /dev/null and b/website/raw_sprites/spritesmith/achievements/achievement-boneCollector2x.png differ diff --git a/website/raw_sprites/spritesmith/achievements/achievement-skeletonCrew2x.png b/website/raw_sprites/spritesmith/achievements/achievement-skeletonCrew2x.png new file mode 100644 index 0000000000..f610fd081c Binary files /dev/null and b/website/raw_sprites/spritesmith/achievements/achievement-skeletonCrew2x.png differ diff --git a/website/raw_sprites/spritesmith_large/promo_skeleton_achievements.png b/website/raw_sprites/spritesmith_large/promo_skeleton_achievements.png new file mode 100644 index 0000000000..4ce3010a90 Binary files /dev/null and b/website/raw_sprites/spritesmith_large/promo_skeleton_achievements.png differ diff --git a/website/server/models/user/schema.js b/website/server/models/user/schema.js index dc62630f59..c7f3c52952 100644 --- a/website/server/models/user/schema.js +++ b/website/server/models/user/schema.js @@ -136,6 +136,8 @@ export default new Schema({ freshwaterFriends: Boolean, goodAsGold: Boolean, allThatGlitters: Boolean, + boneCollector: Boolean, + skeletonCrew: Boolean, // Onboarding Guide createdTask: Boolean, completedTask: Boolean, diff --git a/website/server/models/userNotification.js b/website/server/models/userNotification.js index 3425a5c9d3..7da9f98fef 100644 --- a/website/server/models/userNotification.js +++ b/website/server/models/userNotification.js @@ -59,6 +59,8 @@ const NOTIFICATION_TYPES = [ 'ACHIEVEMENT_FRESHWATER_FRIENDS', 'ACHIEVEMENT_GOOD_AS_GOLD', 'ACHIEVEMENT_ALL_THAT_GLITTERS', + 'ACHIEVEMENT_BONE_COLLECTOR', + 'ACHIEVEMENT_SKELETON_CREW', 'ACHIEVEMENT', // generic achievement notification, details inside `notification.data` 'DROP_CAP_REACHED', ];