diff --git a/migrations/20171230_nye_hats.js b/migrations/20171230_nye_hats.js new file mode 100644 index 0000000000..08db9a4158 --- /dev/null +++ b/migrations/20171230_nye_hats.js @@ -0,0 +1,103 @@ +var migrationName = '20171230_nye_hats.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 New Year's Eve party hats to users in sequence + */ + +var monk = require('monk'); +var connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE +var dbUsers = monk(connectionString).get('users', { castIds: false }); + +function processUsers(lastId) { + // specify a query to limit the affected users (empty for all users): + var query = { + 'migration': {$ne:migrationName}, + 'auth.timestamps.loggedin': {$gt:new Date('2017-11-30')}, + }; + + if (lastId) { + query._id = { + $gt: lastId + } + } + + dbUsers.find(query, { + sort: {_id: 1}, + limit: 250, + fields: [ + 'items.gear.owned', + ] // 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 = {}; + var push = {}; + + if (typeof user.items.gear.owned.head_special_nye2016 !== 'undefined') { + set = {'migration':migrationName, 'items.gear.owned.head_special_nye2017':false}; + push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.head_special_nye2017', '_id': monk.id()}}; + } else if (typeof user.items.gear.owned.head_special_nye2015 !== 'undefined') { + set = {'migration':migrationName, 'items.gear.owned.head_special_nye2016':false}; + push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.head_special_nye2016', '_id': monk.id()}}; + } else if (typeof user.items.gear.owned.head_special_nye2014 !== 'undefined') { + set = {'migration':migrationName, 'items.gear.owned.head_special_nye2015':false}; + push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.head_special_nye2015', '_id': monk.id()}}; + } else if (typeof user.items.gear.owned.head_special_nye !== 'undefined') { + set = {'migration':migrationName, 'items.gear.owned.head_special_nye2014':false}; + push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.head_special_nye2014', '_id': monk.id()}}; + } else { + set = {'migration':migrationName, 'items.gear.owned.head_special_nye':false}; + push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.head_special_nye', '_id': monk.id()}}; + } + + dbUsers.update({_id: user._id}, {$set: set, $push: push}); + + 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/website/client/assets/images/npc/nye/market_background.png b/website/client/assets/images/npc/nye/market_background.png new file mode 100644 index 0000000000..2aae6276de Binary files /dev/null and b/website/client/assets/images/npc/nye/market_background.png differ diff --git a/website/client/assets/images/npc/nye/market_banner_npc.png b/website/client/assets/images/npc/nye/market_banner_npc.png new file mode 100644 index 0000000000..454ef23f5e Binary files /dev/null and b/website/client/assets/images/npc/nye/market_banner_npc.png differ diff --git a/website/client/assets/images/npc/nye/npc_bailey.png b/website/client/assets/images/npc/nye/npc_bailey.png new file mode 100644 index 0000000000..d7659dfebe Binary files /dev/null and b/website/client/assets/images/npc/nye/npc_bailey.png differ diff --git a/website/client/assets/images/npc/nye/npc_justin.png b/website/client/assets/images/npc/nye/npc_justin.png new file mode 100644 index 0000000000..1e8ed19c1c Binary files /dev/null and b/website/client/assets/images/npc/nye/npc_justin.png differ diff --git a/website/client/assets/images/npc/nye/npc_matt.png b/website/client/assets/images/npc/nye/npc_matt.png new file mode 100644 index 0000000000..123dc34233 Binary files /dev/null and b/website/client/assets/images/npc/nye/npc_matt.png differ diff --git a/website/client/assets/images/npc/nye/quest_shop_background.png b/website/client/assets/images/npc/nye/quest_shop_background.png new file mode 100644 index 0000000000..08afb77867 Binary files /dev/null and b/website/client/assets/images/npc/nye/quest_shop_background.png differ diff --git a/website/client/assets/images/npc/nye/quest_shop_npc.png b/website/client/assets/images/npc/nye/quest_shop_npc.png new file mode 100644 index 0000000000..d232e12ef1 Binary files /dev/null and b/website/client/assets/images/npc/nye/quest_shop_npc.png differ diff --git a/website/client/assets/images/npc/nye/seasonal_shop_closed_background.png b/website/client/assets/images/npc/nye/seasonal_shop_closed_background.png new file mode 100644 index 0000000000..9367206b62 Binary files /dev/null and b/website/client/assets/images/npc/nye/seasonal_shop_closed_background.png differ diff --git a/website/client/assets/images/npc/nye/seasonal_shop_closed_npc.png b/website/client/assets/images/npc/nye/seasonal_shop_closed_npc.png new file mode 100644 index 0000000000..861ffad211 Binary files /dev/null and b/website/client/assets/images/npc/nye/seasonal_shop_closed_npc.png differ diff --git a/website/client/assets/images/npc/nye/seasonal_shop_opened_background.png b/website/client/assets/images/npc/nye/seasonal_shop_opened_background.png new file mode 100644 index 0000000000..4356a141b8 Binary files /dev/null and b/website/client/assets/images/npc/nye/seasonal_shop_opened_background.png differ diff --git a/website/client/assets/images/npc/nye/seasonal_shop_opened_npc.png b/website/client/assets/images/npc/nye/seasonal_shop_opened_npc.png new file mode 100644 index 0000000000..1a810d8e20 Binary files /dev/null and b/website/client/assets/images/npc/nye/seasonal_shop_opened_npc.png differ diff --git a/website/client/assets/images/npc/nye/tavern_background.png b/website/client/assets/images/npc/nye/tavern_background.png new file mode 100644 index 0000000000..3a27d7b615 Binary files /dev/null and b/website/client/assets/images/npc/nye/tavern_background.png differ diff --git a/website/client/assets/images/npc/nye/tavern_npc.png b/website/client/assets/images/npc/nye/tavern_npc.png new file mode 100644 index 0000000000..79d53bb471 Binary files /dev/null and b/website/client/assets/images/npc/nye/tavern_npc.png differ diff --git a/website/client/assets/scss/variables.scss b/website/client/assets/scss/variables.scss index 72408fce94..f41f113101 100644 --- a/website/client/assets/scss/variables.scss +++ b/website/client/assets/scss/variables.scss @@ -2,8 +2,8 @@ // possible values are: normal, fall, habitoween, thanksgiving, winter // more to be added on future seasons -$npc_market_flavor: 'winter'; -$npc_quests_flavor: 'winter'; -$npc_seasonal_flavor: 'winter'; +$npc_market_flavor: 'nye'; +$npc_quests_flavor: 'nye'; +$npc_seasonal_flavor: 'nye'; $npc_timetravelers_flavor: 'winter'; -$npc_tavern_flavor: 'winter'; +$npc_tavern_flavor: 'nye'; diff --git a/website/client/components/shops/market/index.vue b/website/client/components/shops/market/index.vue index 6ecf6c0dcc..43645db052 100644 --- a/website/client/components/shops/market/index.vue +++ b/website/client/components/shops/market/index.vue @@ -464,8 +464,8 @@ export default { categories.push({ identifier: 'cards', text: this.$t('cards'), - items: _map(_filter(this.content.cardTypes, (value) => { - return value.yearRound; + items: _map(_filter(this.content.cardTypes, (value, key) => { + return value.yearRound || key === 'nye'; }), (value) => { return { ...getItemInfo(this.user, 'card', value), diff --git a/website/client/components/shops/seasonal/index.vue b/website/client/components/shops/seasonal/index.vue index f4f5d63035..2c387b6f2d 100644 --- a/website/client/components/shops/seasonal/index.vue +++ b/website/client/components/shops/seasonal/index.vue @@ -77,7 +77,7 @@ div( v-for="(groupSets, categoryGroup) in getGroupedCategories(categories)", ) - h3.classgroup + h3.classgroup(v-if='categoryGroup !== "spells"') span.svg-icon.inline(v-html="icons[categoryGroup]") span.name(:class="categoryGroup") {{ getClassName(categoryGroup) }} diff --git a/website/client/components/static/newStuff.vue b/website/client/components/static/newStuff.vue index 17c3ca54b5..2769a0d68c 100644 --- a/website/client/components/static/newStuff.vue +++ b/website/client/components/static/newStuff.vue @@ -4,24 +4,31 @@ .align-self-center.right-margin(:class='baileyClass') .media-body h1.align-self-center(v-markdown='$t("newStuff")') - h2 12/21/2017 - DECEMBER SUBSCRIBER ITEMS, NEW YEAR'S RESOLUTION GUILD AND CHALLENGE, AND HELPFUL HOLIDAY BLOG POSTS + h2 12/30/2017 - NEW YEAR'S EVE CELEBRATION! PARTY HATS, NEW YEAR'S CARDS, SNOWBALLS, AND LAST CHANCE FOR CANDLEMANCER ITEM SET hr - .promo_mystery_201712.center-block - h3 December Subscriber Items Revealed! - p(v-markdown='"The December Subscriber Item Set has been revealed: [the Candlemancer Item Set](https://habitica.com/#/options/settings/subscription)! You only have 11 days to receive the item set when you subscribe. If you\'re already an active subscriber, reload the site and click Inventory>Items to claim your gear!"') - p Subscribers also receive the ability to buy gems for gold -- the longer you subscribe, the more gems you can buy per month! There are other perks as well, such as longer access to uncompressed data and a cute Jackalope pet. Best of all, subscriptions let us keep Habitica running. Thank you very much for your support -- it means a lot to us. - .small by Beffymaroo - h3 New Year's Resolution Guild and Official Challenge - p(v-markdown='"Get a start on 2018 with extra accountability! The Habitica team has launched our official [New Year\'s Resolution Guild](/groups/guild/6e6a8bd3-9f5f-4351-9188-9f11fcd80a99), which we\'ve designed to be a social hub that will provide support, encouragement, tips, and tricks throughout the entire year. Plus, each month we\'ll be running a special official Challenge designed to help you build resolutions that are destined for success and then stick with them as the year progresses. You can find the first one [here](/challenges/35999b79-ae6a-4f16-9557-b4923498e837)! It has a 15 gem prize, which will be awarded to five lucky winners on February 1st."') - p We hope that you enjoy our new series of official Challenges! - .small by beffymaroo, Lemoness, and SabreCat .media - .scene_winter_cleaning.right-margin .media-body - h3 Use Case and Guild Spotlights: Holiday Housekeeping - p(v-markdown='"This month\'s blog theme is Holiday Housekeeping! Visit our [Use Case Spotlight](https://habitica.wordpress.com/2017/12/18/use-case-spotlight-holiday-housekeeping/) to get suggestions on preparing for holiday festivities, then check out the [Guild Spotlight](https://habitica.wordpress.com/2017/12/20/its-most-wonderful-and-busy-time-of-the-year-guilds-to-help-with-holiday-tasks/) to find communities to support you as you put those ideas into action!"') - p We're collecting user submissions for the next spotlight! How do you use Habitica to Set Realistic Goals? We’ll be featuring player-submitted examples in Use Case Spotlights on the Habitica Blog next month, so post your suggestions in the Use Case Spotlight Guild now. We look forward to learning more about how you use Habitica to improve your life and get things done! - .small by Beffymaroo + h3 Party Hats! + p In honor of the new year, some free Party Hats are available in your Rewards! Each year you celebrate New Year's with Habitica, you unlock a new hat. Enjoy, and stay tuned for the matching robes in late January during our annual Habitica Birthday Bash! + .small by Lemoness, Beffymaroo, and SabreCat + .promo_nye_seasonal_shop.left-margin + .media + .promo_nye_card.right-margin + .media-body + h3 New Year's Cards (Until Jan 1st Only!) + p(v-markdown='"Until January 1st only, the [Market](/shops/market) is stocking New Year\'s Cards! Now you can send cards to your friends (and yourself) to wish them a Happy Habit New Year. All senders and recipients will receive the Auld Acquaintance badge!"') + .small by Lemoness and SabreCat + .media + .media-body + h3 Snowballs + p(v-markdown='"The [Seasonal Shop](/shops/seasonal) is stocking Snowballs for gold! Throw them at your friends to have an exciting effect. If you get hit with a snowball, you earn the Annoying Friends badge. The results of being hit with a Snowball will last until the end of your day, but you can also reverse them early by buying Salt from the Rewards column. Snowballs are available until January 31st."') + .small by Shaner and Lemoness + .promo_snowball.left-margin + h3 Last Chance for Candlemancer Armor + p(v-markdown='"Reminder: the 31st is the final day to [subscribe](/user/settings/subscription) and receive the Candlemancer Armor Set! Subscribing also lets you buy gems for gold, nets you our exclusive Jackalope Pet, and has tons of other great perks! Don\'t forget we\'re also running our Gift-One-Get-One subscription deal right now, so it\'s the perfect time to try out a subscription with a friend or family member!"') + p Thanks so much for your support! You help keep Habitica running. + .small by Beffymaroo + .promo_mystery_201712.center-block br diff --git a/website/common/locales/en/gear.json b/website/common/locales/en/gear.json index fac61c08b5..60398f89a4 100644 --- a/website/common/locales/en/gear.json +++ b/website/common/locales/en/gear.json @@ -978,6 +978,8 @@ "headSpecialFall2017HealerText": "Haunted House Helm", "headSpecialFall2017HealerNotes": "Invite spooky spirits and friendly creatures to seek your healing powers in this helm! Increases Intelligence by <%= int %>. Limited Edition 2017 Autumn Gear.", + "headSpecialNye2017Text": "Fanciful Party Hat", + "headSpecialNye2017Notes": "You've received a Fanciful Party Hat! Wear it with pride while ringing in the New Year! Confers no benefit.", "headSpecialWinter2018RogueText": "Reindeer Helm", "headSpecialWinter2018RogueNotes": "The perfect holiday disguise, with a built-in headlight! Increases Perception by <%= per %>. Limited Edition 2017-2018 Winter Gear.", "headSpecialWinter2018WarriorText": "Giftbox Helm", diff --git a/website/common/script/content/gear/sets/special/index.js b/website/common/script/content/gear/sets/special/index.js index d531e7abf5..f30de5702a 100644 --- a/website/common/script/content/gear/sets/special/index.js +++ b/website/common/script/content/gear/sets/special/index.js @@ -1886,6 +1886,12 @@ let head = { value: 60, int: 7, }, + nye2017: { + text: t('headSpecialNye2017Text'), + notes: t('headSpecialNye2017Notes'), + value: 0, + canOwn: ownsItem('head_special_nye2017'), + }, winter2018Rogue: { event: EVENTS.winter2018, specialClass: 'rogue', diff --git a/website/common/script/libs/shops-seasonal.config.js b/website/common/script/libs/shops-seasonal.config.js index 702be004fc..01e1c333c6 100644 --- a/website/common/script/libs/shops-seasonal.config.js +++ b/website/common/script/libs/shops-seasonal.config.js @@ -19,6 +19,7 @@ module.exports = { }, availableSpells: [ + 'snowball', ], availableQuests: [ diff --git a/website/raw_sprites/spritesmith/gear/events/winter/head_special_nye2017.png b/website/raw_sprites/spritesmith/gear/events/winter/head_special_nye2017.png new file mode 100644 index 0000000000..72eebfef52 Binary files /dev/null and b/website/raw_sprites/spritesmith/gear/events/winter/head_special_nye2017.png differ diff --git a/website/raw_sprites/spritesmith/gear/events/winter/shop/shop_head_special_nye2017.png b/website/raw_sprites/spritesmith/gear/events/winter/shop/shop_head_special_nye2017.png new file mode 100644 index 0000000000..d40f0fd322 Binary files /dev/null and b/website/raw_sprites/spritesmith/gear/events/winter/shop/shop_head_special_nye2017.png differ diff --git a/website/raw_sprites/spritesmith/npcs/npc_bailey.png b/website/raw_sprites/spritesmith/npcs/npc_bailey.png index db86596503..d7659dfebe 100644 Binary files a/website/raw_sprites/spritesmith/npcs/npc_bailey.png and b/website/raw_sprites/spritesmith/npcs/npc_bailey.png differ diff --git a/website/raw_sprites/spritesmith/npcs/npc_justin.png b/website/raw_sprites/spritesmith/npcs/npc_justin.png index bf42f04508..1e8ed19c1c 100644 Binary files a/website/raw_sprites/spritesmith/npcs/npc_justin.png and b/website/raw_sprites/spritesmith/npcs/npc_justin.png differ diff --git a/website/raw_sprites/spritesmith/npcs/npc_matt.png b/website/raw_sprites/spritesmith/npcs/npc_matt.png index ed0e3bab59..123dc34233 100644 Binary files a/website/raw_sprites/spritesmith/npcs/npc_matt.png and b/website/raw_sprites/spritesmith/npcs/npc_matt.png differ diff --git a/website/raw_sprites/spritesmith_large/promo_nye_card.png b/website/raw_sprites/spritesmith_large/promo_nye_card.png new file mode 100644 index 0000000000..c8994d0c2e Binary files /dev/null and b/website/raw_sprites/spritesmith_large/promo_nye_card.png differ diff --git a/website/raw_sprites/spritesmith_large/promo_nye_seasonal_shop.png b/website/raw_sprites/spritesmith_large/promo_nye_seasonal_shop.png new file mode 100644 index 0000000000..f37b309c95 Binary files /dev/null and b/website/raw_sprites/spritesmith_large/promo_nye_seasonal_shop.png differ diff --git a/website/raw_sprites/spritesmith_large/promo_snowball.png b/website/raw_sprites/spritesmith_large/promo_snowball.png new file mode 100644 index 0000000000..d7b74d5289 Binary files /dev/null and b/website/raw_sprites/spritesmith_large/promo_snowball.png differ diff --git a/website/server/models/user/hooks.js b/website/server/models/user/hooks.js index a557b8781a..c98cc3c921 100644 --- a/website/server/models/user/hooks.js +++ b/website/server/models/user/hooks.js @@ -137,6 +137,8 @@ function _setUpNewUser (user) { user.items.quests.dustbunnies = 1; user.purchased.background.violet = true; user.preferences.background = 'violet'; + user.items.gear.owned.head_special_nye = true; // eslint-disable-line camelcase + user.items.gear.equipped.head = 'head_special_nye'; if (user.registeredThrough === 'habitica-web') { taskTypes = ['habit', 'daily', 'todo', 'reward', 'tag'];