From b1678e176990907ccb10ba3c676d12c5d1f72265 Mon Sep 17 00:00:00 2001 From: Sabe Jones Date: Tue, 18 Apr 2017 17:38:53 -0500 Subject: [PATCH] feat(subs): Jackalope Pets (#8684) --- migrations/20170418_subscriber_jackalopes.js | 88 +++++++++++++++ test/api/v3/unit/libs/payments.test.js | 20 ++++ .../stable/pets/Pet-Jackalope-RoyalPurple.png | Bin 0 -> 949 bytes .../spritesmith_large/promo/promo_bees.png | Bin 0 -> 17563 bytes website/common/locales/en/subscriber.json | 4 +- website/common/script/content/index.js | 2 + website/common/script/content/stable.js | 1 + website/common/script/libs/shops.js | 2 +- website/server/libs/payments.js | 1 + website/views/options/settings/index.jade | 104 +++++++++--------- website/views/shared/new-stuff.jade | 42 +++++-- 11 files changed, 201 insertions(+), 63 deletions(-) create mode 100644 migrations/20170418_subscriber_jackalopes.js create mode 100644 website/assets/sprites/spritesmith/stable/pets/Pet-Jackalope-RoyalPurple.png create mode 100644 website/assets/sprites/spritesmith_large/promo/promo_bees.png diff --git a/migrations/20170418_subscriber_jackalopes.js b/migrations/20170418_subscriber_jackalopes.js new file mode 100644 index 0000000000..d32867de98 --- /dev/null +++ b/migrations/20170418_subscriber_jackalopes.js @@ -0,0 +1,88 @@ +var migrationName = '20170418_subscriber_jackalopes.js'; +var authorName = 'Sabe'; // in case script author needs to know when their ... +var authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; //... own data is done + +/* + * Award Royal Purple Jackalope pet to all current subscribers + */ + +var monk = require('monk'); +var connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE +var dbUsers = monk(connectionString).get('users', { castIds: false }); +var now = new Date(); + +function processUsers(lastId) { + // specify a query to limit the affected users (empty for all users): + var query = { + 'purchased.plan.customerId': {$type: 2}, + $or: [ + {'purchased.plan.dateTerminated': null}, + {'purchased.plan.dateTerminated': {$exists: false}}, + {'purchased.plan.dateTerminated': {$gt: now}}, + ] + }; + + if (lastId) { + query._id = { + $gt: lastId + } + } + + dbUsers.find(query, { + sort: {_id: 1}, + limit: 250, + fields: [] // specify fields we are interested in to limit retrieved data (empty if we're not reading data): + }) + .then(updateUsers) + .catch(function (err) { + console.log(err); + return exiting(1, 'ERROR! ' + err); + }); +} + +var progressCount = 1000; +var count = 0; + +function updateUsers (users) { + if (!users || users.length === 0) { + console.warn('All appropriate users found and modified.'); + displayData(); + return; + } + + var userPromises = users.map(updateUser); + var lastUser = users[users.length - 1]; + + return Promise.all(userPromises) + .then(function () { + processUsers(lastUser._id); + }); +} + +function updateUser (user) { + count++; + + var set = {'items.pets.Jackalope-RoyalPurple': 5}; + + dbUsers.update({_id: user._id}, {$set:set}); + + if (count % progressCount == 0) console.warn(count + ' ' + user._id); + if (user._id == authorUuid) console.warn(authorName + ' processed'); +} + +function displayData() { + console.warn('\n' + count + ' users processed\n'); + return exiting(0); +} + +function exiting(code, msg) { + code = code || 0; // 0 = success + if (code && !msg) { msg = 'ERROR!'; } + if (msg) { + if (code) { console.error(msg); } + else { console.log( msg); } + } + process.exit(code); +} + +module.exports = processUsers; diff --git a/test/api/v3/unit/libs/payments.test.js b/test/api/v3/unit/libs/payments.test.js index 56057f8c23..bed489f490 100644 --- a/test/api/v3/unit/libs/payments.test.js +++ b/test/api/v3/unit/libs/payments.test.js @@ -83,6 +83,12 @@ describe('payments/index', () => { }; }); + it('awards the Royal Purple Jackalope pet', async () => { + await api.createSubscription(data); + + expect(recipient.items.pets['Jackalope-RoyalPurple']).to.eql(5); + }); + it('adds extra months to an existing subscription', async () => { recipient.purchased.plan = plan; @@ -241,6 +247,12 @@ describe('payments/index', () => { expect(user.purchased.plan.dateCreated).to.exist; }); + it('awards the Royal Purple Jackalope pet', async () => { + await api.createSubscription(data); + + expect(user.items.pets['Jackalope-RoyalPurple']).to.eql(5); + }); + it('sets extraMonths if plan has dateTerminated date', async () => { user.purchased.plan = plan; user.purchased.plan.dateTerminated = moment(new Date()).add(2, 'months'); @@ -633,5 +645,13 @@ describe('payments/index', () => { expect(updatedUser.purchased.plan.lastBillingDate).to.not.exist; expect(updatedUser.purchased.plan.dateCreated).to.exist; }); + + it('awards the Royal Purple Jackalope pet', async () => { + await api.addSubToGroupUser(user, group); + + let updatedUser = await User.findById(user._id).exec(); + + expect(updatedUser.items.pets['Jackalope-RoyalPurple']).to.eql(5); + }); }); }); diff --git a/website/assets/sprites/spritesmith/stable/pets/Pet-Jackalope-RoyalPurple.png b/website/assets/sprites/spritesmith/stable/pets/Pet-Jackalope-RoyalPurple.png new file mode 100644 index 0000000000000000000000000000000000000000..d9e597a627451579c57f51e90b821145060abc2d GIT binary patch literal 949 zcmV;m14{gfP)=Kg-C&tc~6IDEhTX5M?M z6aWAK0000000000000000002YA41a^oSJA(=?mpF_+G0htaSguUv8i6I@Wb=(_sO5 z#3IfK!mb0xzecqtdrKRfG^{P|*X?ZsCBAxkjXmFI#(I4v$+^in=dO%}$V7BTXQh-< ziSC$=AM_cOq%xbUh`D{FIo3vT2*>j-|*%bVlbt zsBbcHf812hoFx(8vD*)xFh4lz-1xXv$FJ_SSo_F1$hpZmlZoie+1bjTEy`N;Iv+-T zD|`77(;j5A-F4fvuP?J-zhZaH+AenyWFk7FbK06;J!98UZpee^{PuIy`n4b{?@Vh; zCbEcGsIzMYmugF-!vCuBl8G!LI$JAj*|xZDUzXh9be-jki*$Upw{TW}2QraG%wnCr z6qek2S*_!{7e=go4xcX2abx6@wa;8on@nU8=LX>*O1i%C;l+VN`-RS?Jvr<@wzw)+ z#{=!-WFk7l->b7!_~Vae-M((Ac_l-tE&F>>P-H6Xsmg@4PyF&KYkT#{FV^4hibbiyb zNVo5-$kTCEzIn^*`_DnE!merup)WBKA`{UW0_*IhcIC$B);{uXvsAm|-3}dl-3q(; zWJt#oW4+d$fNT%)oSIBT=j_J$CC@3%rGZKNgFUz-O; zvYHPoGj?+5j*b_uuJKh^_9qk38D_LPyS@r?Jldw?E3sPZ+5B0jDfulmAH?WFG7+62 zy|c5|Ia=cNmX|y`PpQ-aZi|)YbXhm>vifs&MrTO7I=en=mYR3;xT#GhqBG3eW?QP= z-BX?RzXfpJsFR843>n#MPlq6Xf+086?V~0C-Nu_tWD&DO=OAZr*Nr`AXLJStnAiLU XEteTsTP34700000NkvXXu0mjf<2u8e literal 0 HcmV?d00001 diff --git a/website/assets/sprites/spritesmith_large/promo/promo_bees.png b/website/assets/sprites/spritesmith_large/promo/promo_bees.png new file mode 100644 index 0000000000000000000000000000000000000000..56b987f70cde9f620b786539a98b69d33b2f9fdc GIT binary patch literal 17563 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 literal 0 HcmV?d00001 diff --git a/website/common/locales/en/subscriber.json b/website/common/locales/en/subscriber.json index 3c10bc8ee9..96202fbf8f 100644 --- a/website/common/locales/en/subscriber.json +++ b/website/common/locales/en/subscriber.json @@ -8,12 +8,14 @@ "reachedGoldToGemCap": "You've reached the Gold=>Gem conversion cap <%= convCap %> for this month. We have this to prevent abuse / farming. The cap resets within the first three days of each month.", "retainHistory": "Retain additional history entries", "retainHistoryText": "Makes completed To-Dos and task history available for longer.", - "doubleDrops": "Daily drop-caps doubled", + "doubleDrops": "Daily drop caps doubled", "doubleDropsText": "Complete your stable faster!", "mysteryItem": "Exclusive monthly items", "mysteryItemText": "Each month you will receive a unique cosmetic item for your avatar! Plus, for every three months of consecutive subscription, the Mysterious Time Travelers will grant you access to historic (and futuristic!) cosmetic items.", "supportDevs": "Supports the developers", "supportDevsText": "Your subscription helps keep Habitica thriving and helps fund the development of new features. Thank you for your generosity!", + "exclusiveJackalopePet": "Exclusive pet", + "exclusiveJackalopePetText": "Get the Royal Purple Jackalope pet, available only to subscribers!", "giftSubscription": "Want to gift a subscription to someone?", "giftSubscriptionText1": "Open their profile! You can do this by clicking on their avatar in your party header or by clicking on their name in chat.", "giftSubscriptionText2": "Click on the gift icon in the bottom left of their profile.", diff --git a/website/common/script/content/index.js b/website/common/script/content/index.js index a031c96490..df3ba873dc 100644 --- a/website/common/script/content/index.js +++ b/website/common/script/content/index.js @@ -125,11 +125,13 @@ api.timeTravelStable = { 'Mammoth-Base': t('mammoth'), 'MantisShrimp-Base': t('mantisShrimp'), 'Phoenix-Base': t('phoenix'), + 'MagicalBee-Base': t('magicalBee'), }, mounts: { 'Mammoth-Base': t('mammoth'), 'MantisShrimp-Base': t('mantisShrimp'), 'Phoenix-Base': t('phoenix'), + 'MagicalBee-Base': t('magicalBee'), }, }; diff --git a/website/common/script/content/stable.js b/website/common/script/content/stable.js index 942a9aaa00..80d89f5a0e 100644 --- a/website/common/script/content/stable.js +++ b/website/common/script/content/stable.js @@ -67,6 +67,7 @@ let specialPets = { 'Lion-Veteran': 'veteranLion', 'Gryphon-RoyalPurple': 'royalPurpleGryphon', 'JackOLantern-Ghost': 'ghostJackolantern', + 'Jackalope-RoyalPurple': 'royalPurpleJackalope', }; let specialMounts = { diff --git a/website/common/script/libs/shops.js b/website/common/script/libs/shops.js index 871cde74a0..3deaac1c63 100644 --- a/website/common/script/libs/shops.js +++ b/website/common/script/libs/shops.js @@ -149,7 +149,7 @@ shops.getQuestShopCategories = function getQuestShopCategories (user, language) shops.getTimeTravelersCategories = function getTimeTravelersCategories (user, language) { let categories = []; - let stable = {pets: 'Pet-', mounts: 'Mount_Head_'}; + let stable = {pets: 'Pet-', mounts: 'Mount_Icon_'}; for (let type in stable) { if (stable.hasOwnProperty(type)) { let category = { diff --git a/website/server/libs/payments.js b/website/server/libs/payments.js index 0eb94790a0..8cb600da48 100644 --- a/website/server/libs/payments.js +++ b/website/server/libs/payments.js @@ -289,6 +289,7 @@ api.createSubscription = async function createSubscription (data) { } if (recipient !== group) { + recipient.items.pets['Jackalope-RoyalPurple'] = 5; revealMysteryItems(recipient); } diff --git a/website/views/options/settings/index.jade b/website/views/options/settings/index.jade index 39a081b113..bf95f370f2 100644 --- a/website/views/options/settings/index.jade +++ b/website/views/options/settings/index.jade @@ -1,51 +1,53 @@ -mixin subPerks() - ul - li - span.hint(popover=env.t('buyGemsGoldText', {gemCost: "{{Shared.planGemLimits.convRate}}", gemLimit: "{{Shared.planGemLimits.convCap}}"}),popover-trigger='mouseenter',popover-placement='right') #{env.t('buyGemsGold')}  - span.badge.badge-success(ng-show='_subscription.key!="basic_earned"')=env.t('buyGemsGoldCap', {amount: '{{gemGoldCap(_subscription) | min }}'}) - li - span.hint(popover=env.t('retainHistoryText'),popover-trigger='mouseenter',popover-placement='right')=env.t('retainHistory') - li - span.hint(popover=env.t('doubleDropsText'),popover-trigger='mouseenter',popover-placement='right')=env.t('doubleDrops') - li - span.hint(popover=env.t('mysteryItemText'),popover-trigger='mouseenter',popover-placement='right') #{env.t('mysteryItem')}  - div(ng-show='_subscription.key!="basic_earned"') - .badge.badge-success=env.t('mysticHourglass', {amount: '+{{numberOfMysticHourglasses(_subscription)}}'}) - .small.muted=env.t('mysticHourglassText') - li - span.hint(popover=env.t('supportDevsText'),popover-trigger='mouseenter',popover-placement='right')=env.t('supportDevs') - -script(id='partials/options.settings.html', type="text/ng-template") - ul.options-menu - li(ng-class="{ active: $state.includes('options.settings.settings') }") - a(ui-sref='options.settings.settings') - =env.t('site') - li(ng-class="{ active: $state.includes('options.settings.api') }") - a(ui-sref='options.settings.api') - =env.t('API') - li(ng-class="{ active: $state.includes('options.settings.export') }") - a(ui-sref='options.settings.export') - =env.t('dataExport') - li(ng-class="{ active: $state.includes('options.settings.promo') }") - a(ui-sref='options.settings.promo') - =env.t('promoCode') - li(ng-class="{ active: $state.includes('options.settings.subscription') }") - a(ui-sref='options.settings.subscription')=env.t('subscription') - li(ng-class="{ active: $state.includes('options.settings.notifications') }") - a(ui-sref='options.settings.notifications')=env.t('notifications') - - .tab-content - .tab-pane.active - div(ui-view) - -include ./settings -include ./promo -include ./api -include ./export -include ./notification -include ./subscription - -script(id='partials/feature-matrix-check.html',type='text/ng-template') - span.task-checker.action-yesno - input.focusable(type='checkbox', checked) - label +mixin subPerks() + ul + li + span.hint(popover=env.t('buyGemsGoldText', {gemCost: "{{Shared.planGemLimits.convRate}}", gemLimit: "{{Shared.planGemLimits.convCap}}"}),popover-trigger='mouseenter',popover-placement='right') #{env.t('buyGemsGold')}  + span.badge.badge-success(ng-show='_subscription.key!="basic_earned"')=env.t('buyGemsGoldCap', {amount: '{{gemGoldCap(_subscription) | min }}'}) + li + span.hint(popover=env.t('retainHistoryText'),popover-trigger='mouseenter',popover-placement='right')=env.t('retainHistory') + li + span.hint(popover=env.t('doubleDropsText'),popover-trigger='mouseenter',popover-placement='right')=env.t('doubleDrops') + li + span.hint(popover=env.t('mysteryItemText'),popover-trigger='mouseenter',popover-placement='right') #{env.t('mysteryItem')}  + div(ng-show='_subscription.key!="basic_earned"') + .badge.badge-success=env.t('mysticHourglass', {amount: '+{{numberOfMysticHourglasses(_subscription)}}'}) + .small.muted=env.t('mysticHourglassText') + li + span.hint(popover=env.t('exclusiveJackalopePetText'),popover-trigger='mouseenter',popover-placement='right')=env.t('exclusiveJackalopePet') + li + span.hint(popover=env.t('supportDevsText'),popover-trigger='mouseenter',popover-placement='right')=env.t('supportDevs') + +script(id='partials/options.settings.html', type="text/ng-template") + ul.options-menu + li(ng-class="{ active: $state.includes('options.settings.settings') }") + a(ui-sref='options.settings.settings') + =env.t('site') + li(ng-class="{ active: $state.includes('options.settings.api') }") + a(ui-sref='options.settings.api') + =env.t('API') + li(ng-class="{ active: $state.includes('options.settings.export') }") + a(ui-sref='options.settings.export') + =env.t('dataExport') + li(ng-class="{ active: $state.includes('options.settings.promo') }") + a(ui-sref='options.settings.promo') + =env.t('promoCode') + li(ng-class="{ active: $state.includes('options.settings.subscription') }") + a(ui-sref='options.settings.subscription')=env.t('subscription') + li(ng-class="{ active: $state.includes('options.settings.notifications') }") + a(ui-sref='options.settings.notifications')=env.t('notifications') + + .tab-content + .tab-pane.active + div(ui-view) + +include ./settings +include ./promo +include ./api +include ./export +include ./notification +include ./subscription + +script(id='partials/feature-matrix-check.html',type='text/ng-template') + span.task-checker.action-yesno + input.focusable(type='checkbox', checked) + label diff --git a/website/views/shared/new-stuff.jade b/website/views/shared/new-stuff.jade index a871c9e024..98f8ecc337 100644 --- a/website/views/shared/new-stuff.jade +++ b/website/views/shared/new-stuff.jade @@ -1,24 +1,46 @@ -h2 4/13/2017 - BUTTERFLY PET QUEST AND SAMPLE DAILIES WIKI SPOTLIGHT +h2 4/18/2017 - ANDROID UPDATE, NEW JACKALOPE PET FOR SUBSCRIBERS, AND MAGICAL BEES IN THE TIME TRAVEL SHOP hr tr td - .quest_butterfly.pull-right - h3 New Pet Quest: Bye, Bye, Butterfry! - p A trip to the Taskan countryside's butterfly garden gets deeply dangerous when some neglected Dailies attract a Flaming Butterfry! Get the latest pet quest, "Bye, Bye Butterfry" in the Quest Shop, and earn some cute caterpillar pets by completing your real-life tasks. - p.small.muted Written by AnnDeLune - p.small.muted Art by Leephon, Megan, Eevachu, Beffymaroo, UncommonCriminal, Anna Glassman, and Lilith of Alfheim + .promo_bees.pull-right + h3 Android Update + p There's an exciting new update to our Android app! Task navigation has been redesigned, and there are more options for filtering your tasks. We've also added a snazzy new login screen and an improved tutorial for new users! + br + p Be sure to download the update now for a better Habitica experience! If you like the improvements that we’ve been making to our app, please consider reviewing this new version. It really helps us out! + p.small.muted by viirus, Sara Olson, and beffymaroo tr td - .scene_dailies.pull-left.slight-right-margin - h3 Featured Wiki Article: Sample Dailies - p This month's featured Wiki article is about Sample Dailies! We hope that it will help you as work on adding or revamping your daily tasks. Be sure to check it out, and let us know what you think by reaching out on Twitter, Tumblr, and Facebook. - p.small.muted by Beffymaroo and the Wiki Wizards + .Pet-Jackalope-RoyalPurple.pull-left.slight-right-margin + h3 New Exclusive Jackalope Pet for Subscribers + p As a thank-you for your support, all subscribers and group plan members have received Royal Purple Jackalope pets! New subscribers will receive this pet when they sign up, so check out the info on our Subscriptions page to learn more about all the great benefits of subscribing to Habitica including your very own Jackalope pet! + p.small.muted by Beffymaroo and SabreCat + tr + td + h3 Bees Available from the Time Travelers + p Magical Bee Pets and Mounts are now available from the Time Travelers! If you missed out on these happy, buzzing companions from last year, be sure to adopt them now. + br + p If bees are something you'd prefer not to see in Habitica due to a phobia, check out the Phobia Protection Extension which will hide any pets, mounts, backgrounds, quest bosses, or equipment featuring bees (as well as snakes, spiders, and rats). We hope that it helps make everyone's Habitica experience fun! + p.small.muted by Lemoness and SabreCat if menuItem !== 'oldNews' hr a(href='/static/old-news', target='_blank') Read older news mixin oldNews + h2 4/13/2017 - BUTTERFLY PET QUEST AND SAMPLE DAILIES WIKI SPOTLIGHT + tr + td + .quest_butterfly.pull-right + h3 New Pet Quest: Bye, Bye, Butterfry! + p A trip to the Taskan countryside's butterfly garden gets deeply dangerous when some neglected Dailies attract a Flaming Butterfry! Get the latest pet quest, "Bye, Bye Butterfry" in the Quest Shop, and earn some cute caterpillar pets by completing your real-life tasks. + p.small.muted Written by AnnDeLune + p.small.muted Art by Leephon, Megan, Eevachu, Beffymaroo, UncommonCriminal, Anna Glassman, and Lilith of Alfheim + tr + td + .scene_dailies.pull-left.slight-right-margin + h3 Featured Wiki Article: Sample Dailies + p This month's featured Wiki article is about Sample Dailies! We hope that it will help you as work on adding or revamping your daily tasks. Be sure to check it out, and let us know what you think by reaching out on Twitter, Tumblr, and Facebook. + p.small.muted by Beffymaroo and the Wiki Wizards h2 4/11/2017 - EGG HUNT QUEST, APRIL FOOL'S CHALLENGE WINNERS, AND CHANGE TO PARTY SIZES tr td