diff --git a/migrations/20180130_habit_birthday.js b/migrations/20180130_habit_birthday.js new file mode 100644 index 0000000000..05a3dc1c02 --- /dev/null +++ b/migrations/20180130_habit_birthday.js @@ -0,0 +1,118 @@ +var migrationName = '20180130_habit_birthday.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 party robes: most recent user doesn't have of 2014-2018. Also cake! + */ + +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('2018-01-01')}, // remove after first run to cover remaining users + }; + + 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) + 'items.gear.owned' + ], + }) + .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 push; + var set = {'migration':migrationName}; + + if (user.items && user.items.gear && user.items.gear.owned && user.items.gear.owned.hasOwnProperty('armor_special_birthday2017')) { + set['items.gear.owned.armor_special_birthday2018'] = false; + push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.armor_special_birthday2018', '_id': monk.id()}}; + } else if (user.items && user.items.gear && user.items.gear.owned && user.items.gear.owned.hasOwnProperty('armor_special_birthday2016')) { + set['items.gear.owned.armor_special_birthday2017'] = false; + push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.armor_special_birthday2017', '_id': monk.id()}}; + } else if (user.items && user.items.gear && user.items.gear.owned && user.items.gear.owned.hasOwnProperty('armor_special_birthday2015')) { + set['items.gear.owned.armor_special_birthday2016'] = false; + push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.armor_special_birthday2016', '_id': monk.id()}}; + } else if (user.items && user.items.gear && user.items.gear.owned && user.items.gear.owned.hasOwnProperty('armor_special_birthday')) { + set['items.gear.owned.armor_special_birthday2015'] = false; + push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.armor_special_birthday2015', '_id': monk.id()}}; + } else { + set['items.gear.owned.armor_special_birthday'] = false; + push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.armor_special_birthday', '_id': monk.id()}}; + } + + var inc = { + 'items.food.Cake_Skeleton':1, + 'items.food.Cake_Base':1, + 'items.food.Cake_CottonCandyBlue':1, + 'items.food.Cake_CottonCandyPink':1, + 'items.food.Cake_Shade':1, + 'items.food.Cake_White':1, + 'items.food.Cake_Golden':1, + 'items.food.Cake_Zombie':1, + 'items.food.Cake_Desert':1, + 'items.food.Cake_Red':1, + 'achievements.habitBirthdays':1 + }; + + dbUsers.update({_id: user._id}, {$set: set, $inc: inc, $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/birthday/market_background.png b/website/client/assets/images/npc/birthday/market_background.png new file mode 100644 index 0000000000..fd10a92176 Binary files /dev/null and b/website/client/assets/images/npc/birthday/market_background.png differ diff --git a/website/client/assets/images/npc/birthday/market_banner_npc.png b/website/client/assets/images/npc/birthday/market_banner_npc.png new file mode 100644 index 0000000000..2cff36057e Binary files /dev/null and b/website/client/assets/images/npc/birthday/market_banner_npc.png differ diff --git a/website/client/assets/images/npc/birthday/npc_bailey.png b/website/client/assets/images/npc/birthday/npc_bailey.png new file mode 100644 index 0000000000..77347e3749 Binary files /dev/null and b/website/client/assets/images/npc/birthday/npc_bailey.png differ diff --git a/website/client/assets/images/npc/birthday/npc_justin.png b/website/client/assets/images/npc/birthday/npc_justin.png new file mode 100644 index 0000000000..08ad42e374 Binary files /dev/null and b/website/client/assets/images/npc/birthday/npc_justin.png differ diff --git a/website/client/assets/images/npc/birthday/npc_matt.png b/website/client/assets/images/npc/birthday/npc_matt.png new file mode 100644 index 0000000000..056b638cdc Binary files /dev/null and b/website/client/assets/images/npc/birthday/npc_matt.png differ diff --git a/website/client/assets/images/npc/birthday/quest_shop_background.png b/website/client/assets/images/npc/birthday/quest_shop_background.png new file mode 100644 index 0000000000..3faa6a7962 Binary files /dev/null and b/website/client/assets/images/npc/birthday/quest_shop_background.png differ diff --git a/website/client/assets/images/npc/birthday/quest_shop_npc.png b/website/client/assets/images/npc/birthday/quest_shop_npc.png new file mode 100644 index 0000000000..9771fdf8b8 Binary files /dev/null and b/website/client/assets/images/npc/birthday/quest_shop_npc.png differ diff --git a/website/client/assets/images/npc/birthday/seasonal_shop_closed_background.png b/website/client/assets/images/npc/birthday/seasonal_shop_closed_background.png new file mode 100644 index 0000000000..9367206b62 Binary files /dev/null and b/website/client/assets/images/npc/birthday/seasonal_shop_closed_background.png differ diff --git a/website/client/assets/images/npc/birthday/seasonal_shop_closed_npc.png b/website/client/assets/images/npc/birthday/seasonal_shop_closed_npc.png new file mode 100644 index 0000000000..861ffad211 Binary files /dev/null and b/website/client/assets/images/npc/birthday/seasonal_shop_closed_npc.png differ diff --git a/website/client/assets/images/npc/birthday/seasonal_shop_opened_background.png b/website/client/assets/images/npc/birthday/seasonal_shop_opened_background.png new file mode 100644 index 0000000000..e6422bbb1d Binary files /dev/null and b/website/client/assets/images/npc/birthday/seasonal_shop_opened_background.png differ diff --git a/website/client/assets/images/npc/birthday/seasonal_shop_opened_npc.png b/website/client/assets/images/npc/birthday/seasonal_shop_opened_npc.png new file mode 100644 index 0000000000..c2be2ca618 Binary files /dev/null and b/website/client/assets/images/npc/birthday/seasonal_shop_opened_npc.png differ diff --git a/website/client/assets/images/npc/birthday/tavern_background.png b/website/client/assets/images/npc/birthday/tavern_background.png new file mode 100644 index 0000000000..df87ead02e Binary files /dev/null and b/website/client/assets/images/npc/birthday/tavern_background.png differ diff --git a/website/client/assets/images/npc/birthday/tavern_npc.png b/website/client/assets/images/npc/birthday/tavern_npc.png new file mode 100644 index 0000000000..e7cd1adbf0 Binary files /dev/null and b/website/client/assets/images/npc/birthday/tavern_npc.png differ diff --git a/website/client/assets/images/npc/birthday/time_travelers_background.png b/website/client/assets/images/npc/birthday/time_travelers_background.png new file mode 100644 index 0000000000..fa7eccb3c6 Binary files /dev/null and b/website/client/assets/images/npc/birthday/time_travelers_background.png differ diff --git a/website/client/assets/images/npc/birthday/time_travelers_closed_banner.png b/website/client/assets/images/npc/birthday/time_travelers_closed_banner.png new file mode 100644 index 0000000000..d6346979ac Binary files /dev/null and b/website/client/assets/images/npc/birthday/time_travelers_closed_banner.png differ diff --git a/website/client/assets/images/npc/birthday/time_travelers_open_banner.png b/website/client/assets/images/npc/birthday/time_travelers_open_banner.png new file mode 100644 index 0000000000..2087a149ff Binary files /dev/null and b/website/client/assets/images/npc/birthday/time_travelers_open_banner.png differ diff --git a/website/client/components/static/newStuff.vue b/website/client/components/static/newStuff.vue index f86cdc745a..1f3c47499b 100644 --- a/website/client/components/static/newStuff.vue +++ b/website/client/components/static/newStuff.vue @@ -4,25 +4,35 @@ .align-self-center.right-margin(:class='baileyClass') .media-body h1.align-self-center(v-markdown='$t("newStuff")') - h2 1/23/2018 - JANUARY SUBSCRIBER ITEMS, RESOLUTION PLOT-LINE, AND GUILDS FOR GOALS + h2 1/30/2018 - HABITICA BIRTHDAY CELEBRATION, LAST CHANCE FOR WINTER WONDERLAND ITEMS, AND CONTINUED RESOLUTION PLOT-LINE hr - h3 January Subscriber Items Revealed! - p(v-markdown='"The January Subscriber Item has been revealed: the Frost Sprite Item Set! You only have until January 31 to receive the item set when you [subscribe](/settings/subscription). If you\'re already an active subscriber, reload the site and then head to Inventory > Equipment 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 - .promo_mystery_201801.center-block - h3 Resolution Plot-Line: An Overheard Conversation - p As you stride through the streets of Habit City, you overhear a worried conference of whispers. Curious, you peek in to Productivity Plaza and discover Lemoness and Beffymaroo in solemn conversation. - p "On one hand, there's always the risk of discouragement when the eagerness of a fresh New Year's resolution gives way to everyday difficulties," Lemoness is saying. "But that just doesn't seem to match these reports. Habiticans who were making real progress are abruptly giving up all their goals overnight." - p "I agree," says Beffymaroo. "And look at these maps -- all the reports are happening in the exact same neighborhoods." - p "Clustered discouragement, cropping up all over the city?" Lemoness shakes her head. "I won't tempt fate by calling it a coincidence. It's time to investigate." - p Without further ado, both of them hurry away. What a strange conversation to overhear! Perhaps we'll learn more about this later.... + .promo_habit_birthday_2018.center-block + h3 Habitica Birthday Party! + p January 31st is Habitica's Birthday! Thank you so much for being a part of our community - it means a lot. + p Now come join us and the NPCs as we celebrate! + h4 Cake for Everybody! + p(v-markdown='"In honor of the festivities, everyone has been awarded an assortment of yummy cake to feed to your pets! Plus, for the next two days [Alexander the Merchant](/shops/market) is selling cake in his shop, and cake will sometimes drop when you complete your tasks. Cake works just like normal pet food, but if you want to know what type of pet likes each slice, [the wiki has spoilers](http://habitica.wikia.com/wiki/Food)."') + h4 Party Robes + p There are Party Robes available for free in the Rewards column! Don them with pride. + h4 Birthday Bash Achievement + p In honor of Habitica's birthday, everyone has been awarded the Habitica Birthday Bash achievement! This achievement stacks for each Birthday Bash you celebrate with us. .media .media-body - h3 New Goals for the New Year: Guilds for Setting (and Keeping) Realistic Goals - p(v-markdown='"There\'s a new [Guild Spotlight on the blog](https://habitica.wordpress.com/2018/01/23/new-goals-for-the-new-year-guilds-for-setting-and-keeping-realistic-goals/) that highlights the Guilds that can help you as set new goals for 2018 and strive to stay on track! Check it out now to find Habitica\'s best goal-setting communities."') + h3 Last Chance for Frost Sprite Set + p(v-markdown='"Reminder: this is the final day to [subscribe](/user/settings/subscription) and receive the Frost Sprite Set! Subscribing also lets you buy gems for gold. The longer your subscription, the more gems you get!"') + p Thanks so much for your support! You help keep Habitica running. .small by Beffymaroo - .scene_task_list.left-margin + h3 Last Chance for Starry Night and Holly Hatching Potions + p(v-markdown='"Reminder: this is the final day to [buy Starry Night and Holly Hatching Potions!](/shops/market) If they come back, it won\'t be until next year at the earliest, so don\'t delay!"') + .small by Vampitch, JinjooHat, Lemoness, and SabreCat + h3 Resolution Plot-Line: Broken Buildings + p Lemoness, SabreCat, and Beffymaroo call an important meeting to address the rumors that are flying about this strange outbreak of Habiticans who are suddenly losing all faith in their ability to complete their New Year's Resolutions. + p “Thank you all for coming,” Lemoness says. “I'm afraid that we have some very serious news to share, but we ask that you remain calm.” + .promo_starry_potions.left-margin + p “While it's natural to feel a little disheartened as the end of January approaches,” Beffymaroo says, “these sudden outbreaks appear to have some strange magical origin. We're still investigating the exact cause, but we do know that the buildings where the affected Habiticans live often seem to sustain some damage immediately before the attack.” + p SabreCat clears his throat. “For this reason, we strongly encourage everyone to stay away from broken-down structures, and if you feel any strange tremors or hear odd sounds, please report them immediately.” + p(v-markdown='"“Stay safe, Habiticans.” Lemoness flashes her best comforting smile. “And remember that if your New Year\'s Resolution goals seem daunting, you can always seek support in the [New Year\'s Resolution Guild](https://habitica.com/groups/guild/6e6a8bd3-9f5f-4351-9188-9f11fcd80a99).”"') + p How mysterious! Hopefully they'll get to the bottom of this soon. hr diff --git a/website/common/locales/en/gear.json b/website/common/locales/en/gear.json index bb6f7e3577..3cd4d14fcc 100644 --- a/website/common/locales/en/gear.json +++ b/website/common/locales/en/gear.json @@ -451,6 +451,8 @@ "armorSpecialBirthday2016Notes": "Happy Birthday, Habitica! Wear these Ridiculous Party Robes to celebrate this wonderful day. Confers no benefit.", "armorSpecialBirthday2017Text": "Whimsical Party Robes", "armorSpecialBirthday2017Notes": "Happy Birthday, Habitica! Wear these Whimsical Party Robes to celebrate this wonderful day. Confers no benefit.", + "armorSpecialBirthday2018Text": "Fanciful Party Robes", + "armorSpecialBirthday2018Notes": "Happy Birthday, Habitica! Wear these Fanciful Party Robes to celebrate this wonderful day. Confers no benefit.", "armorSpecialGaymerxText": "Rainbow Warrior Armor", "armorSpecialGaymerxNotes": "In celebration of the GaymerX Conference, this special armor is decorated with a radiant, colorful rainbow pattern! GaymerX is a game convention celebrating LGTBQ and gaming and is open to everyone.", diff --git a/website/common/script/content/gear/sets/special/index.js b/website/common/script/content/gear/sets/special/index.js index f30de5702a..f221af0bcb 100644 --- a/website/common/script/content/gear/sets/special/index.js +++ b/website/common/script/content/gear/sets/special/index.js @@ -867,6 +867,12 @@ let armor = { value: 90, con: 15, }, + birthday2018: { + text: t('armorSpecialBirthday2018Text'), + notes: t('armorSpecialBirthday2018Notes'), + value: 0, + canOwn: ownsItem('armor_special_birthday2018'), + }, }; let back = { diff --git a/website/common/script/content/index.js b/website/common/script/content/index.js index c5b33f81f3..4f5d46dbda 100644 --- a/website/common/script/content/index.js +++ b/website/common/script/content/index.js @@ -266,12 +266,12 @@ api.specialMounts = stable.specialMounts; api.mountInfo = stable.mountInfo; // For seasonal events, change these booleans: -let canBuyNormalFood = true; -let canDropNormalFood = true; +let canBuyNormalFood = false; +let canDropNormalFood = false; let canBuyCandyFood = false; let canDropCandyFood = false; -let canBuyCakeFood = false; -let canDropCakeFood = false; +let canBuyCakeFood = true; +let canDropCakeFood = true; api.food = { Meat: { diff --git a/website/raw_sprites/spritesmith/gear/events/birthday/broad_armor_special_birthday2018.png b/website/raw_sprites/spritesmith/gear/events/birthday/broad_armor_special_birthday2018.png new file mode 100644 index 0000000000..59cf8c2bbb Binary files /dev/null and b/website/raw_sprites/spritesmith/gear/events/birthday/broad_armor_special_birthday2018.png differ diff --git a/website/raw_sprites/spritesmith/gear/events/birthday/shop_armor_special_birthday2018.png b/website/raw_sprites/spritesmith/gear/events/birthday/shop_armor_special_birthday2018.png new file mode 100644 index 0000000000..cb1efa4ba9 Binary files /dev/null and b/website/raw_sprites/spritesmith/gear/events/birthday/shop_armor_special_birthday2018.png differ diff --git a/website/raw_sprites/spritesmith/gear/events/birthday/slim_armor_special_birthday2018.png b/website/raw_sprites/spritesmith/gear/events/birthday/slim_armor_special_birthday2018.png new file mode 100644 index 0000000000..4fc47c3359 Binary files /dev/null and b/website/raw_sprites/spritesmith/gear/events/birthday/slim_armor_special_birthday2018.png differ diff --git a/website/raw_sprites/spritesmith/npcs/npc_bailey.png b/website/raw_sprites/spritesmith/npcs/npc_bailey.png index db86596503..77347e3749 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..08ad42e374 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..056b638cdc 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_habit_birthday_2018.png b/website/raw_sprites/spritesmith_large/promo_habit_birthday_2018.png new file mode 100644 index 0000000000..f7441d9dc0 Binary files /dev/null and b/website/raw_sprites/spritesmith_large/promo_habit_birthday_2018.png differ diff --git a/website/raw_sprites/spritesmith_large/promo_starry_potions.png b/website/raw_sprites/spritesmith_large/promo_starry_potions.png new file mode 100644 index 0000000000..289599e67c Binary files /dev/null and b/website/raw_sprites/spritesmith_large/promo_starry_potions.png differ