feat(event): Birthday 2020
91
migrations/archive/2020/20200131_habit_birthday.js
Normal file
@@ -0,0 +1,91 @@
|
||||
/* eslint-disable no-console */
|
||||
const MIGRATION_NAME = '20200131_habit_birthday';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
import { model as User } from '../../../website/server/models/user';
|
||||
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
async function updateUser (user) {
|
||||
count++;
|
||||
|
||||
const 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,
|
||||
};
|
||||
const set = {};
|
||||
let push;
|
||||
|
||||
set.migration = MIGRATION_NAME;
|
||||
|
||||
if (typeof user.items.gear.owned.armor_special_birthday2019 !== 'undefined') {
|
||||
set['items.gear.owned.armor_special_birthday2020'] = false;
|
||||
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.armor_special_birthday2020', _id: uuid()}};
|
||||
} else if (typeof user.items.gear.owned.armor_special_birthday2018 !== 'undefined') {
|
||||
set['items.gear.owned.armor_special_birthday2019'] = false;
|
||||
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.armor_special_birthday2019', _id: uuid()}};
|
||||
} else if (typeof user.items.gear.owned.armor_special_birthday2017 !== 'undefined') {
|
||||
set['items.gear.owned.armor_special_birthday2018'] = false;
|
||||
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.armor_special_birthday2018', _id: uuid()}};
|
||||
} else if (typeof user.items.gear.owned.armor_special_birthday2016 !== 'undefined') {
|
||||
set['items.gear.owned.armor_special_birthday2017'] = false;
|
||||
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.armor_special_birthday2017', _id: uuid()}};
|
||||
} else if (typeof user.items.gear.owned.armor_special_birthday2015 !== 'undefined') {
|
||||
set['items.gear.owned.armor_special_birthday2016'] = false;
|
||||
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.armor_special_birthday2016', _id: uuid()}};
|
||||
} else if (typeof user.items.gear.owned.armor_special_birthday !== 'undefined') {
|
||||
set['items.gear.owned.armor_special_birthday2015'] = false;
|
||||
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.armor_special_birthday2015', _id: uuid()}};
|
||||
} else {
|
||||
set['items.gear.owned.armor_special_birthday'] = false;
|
||||
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.armor_special_birthday', _id: uuid()}};
|
||||
}
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
|
||||
return await User.update({_id: user._id}, {$inc: inc, $set: set, $push: push}).exec();
|
||||
}
|
||||
|
||||
module.exports = async function processUsers () {
|
||||
let query = {
|
||||
migration: {$ne: MIGRATION_NAME},
|
||||
'auth.timestamps.loggedin': {$gt: new Date('2019-01-15')},
|
||||
};
|
||||
|
||||
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],
|
||||
};
|
||||
}
|
||||
|
||||
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
};
|
||||
@@ -2,11 +2,11 @@
|
||||
// possible values are: normal, fall, habitoween, thanksgiving, winter, nye, birthday, valentines, spring, summer
|
||||
// more to be added on future seasons
|
||||
|
||||
$npc_market_flavor: 'winter';
|
||||
$npc_quests_flavor: 'winter';
|
||||
$npc_seasonal_flavor: 'winter';
|
||||
$npc_timetravelers_flavor: 'winter';
|
||||
$npc_tavern_flavor: 'winter';
|
||||
$npc_market_flavor: 'birthday';
|
||||
$npc_quests_flavor: 'birthday';
|
||||
$npc_seasonal_flavor: 'birthday';
|
||||
$npc_timetravelers_flavor: 'birthday';
|
||||
$npc_tavern_flavor: 'birthday';
|
||||
|
||||
$restingToolbarHeight: 40px;
|
||||
$menuToolbarHeight: 56px;
|
||||
|
||||
@@ -581,6 +581,8 @@
|
||||
"armorSpecialBirthday2018Notes": "Happy Birthday, Habitica! Wear these Fanciful Party Robes to celebrate this wonderful day. Confers no benefit.",
|
||||
"armorSpecialBirthday2019Text": "Outlandish Party Robes",
|
||||
"armorSpecialBirthday2019Notes": "Happy Birthday, Habitica! Wear these Outlandish Party Robes to celebrate this wonderful day. Confers no benefit.",
|
||||
"armorSpecialBirthday2020Text": "Outrageous Party Robes",
|
||||
"armorSpecialBirthday2020Notes": "Happy Birthday, Habitica! Wear these Outrageous 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.",
|
||||
|
||||
@@ -1145,6 +1145,12 @@ const armor = {
|
||||
value: 90,
|
||||
con: 15,
|
||||
},
|
||||
birthday2020: {
|
||||
text: t('armorSpecialBirthday2020Text'),
|
||||
notes: t('armorSpecialBirthday2020Notes'),
|
||||
value: 0,
|
||||
canOwn: ownsItem('armor_special_birthday2020'),
|
||||
},
|
||||
};
|
||||
|
||||
const back = {
|
||||
|
||||
@@ -192,7 +192,7 @@ api.mountInfo = stable.mountInfo;
|
||||
|
||||
// For seasonal events, change this constant:
|
||||
|
||||
const FOOD_SEASON = 'Normal';
|
||||
const FOOD_SEASON = 'Cake';
|
||||
|
||||
api.food = {
|
||||
Meat: {
|
||||
|
||||
|
After Width: | Height: | Size: 750 B |
|
After Width: | Height: | Size: 691 B |
|
After Width: | Height: | Size: 705 B |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 6.3 KiB |
BIN
website/raw_sprites/spritesmith_large/promo_birthday_2020.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
@@ -4,7 +4,7 @@ const api = {};
|
||||
|
||||
// @TODO export this const, cannot export it from here because only routes are exported from
|
||||
// controllers
|
||||
const LAST_ANNOUNCEMENT_TITLE = 'HABITICA BLOG POSTS! FAVORITE GUILDS AND USE CASE SPOTLIGHT';
|
||||
const LAST_ANNOUNCEMENT_TITLE = 'HABITICA BIRTHDAY PARTY!';
|
||||
const worldDmg = { // @TODO
|
||||
bailey: false,
|
||||
};
|
||||
@@ -31,43 +31,33 @@ api.getNews = {
|
||||
<div class="mr-3 ${baileyClass}"></div>
|
||||
<div class="media-body">
|
||||
<h1 class="align-self-center">${res.t('newStuff')}</h1>
|
||||
<h2>1/23/2020 - ${LAST_ANNOUNCEMENT_TITLE}</h2>
|
||||
<h2>1/31/2020 - ${LAST_ANNOUNCEMENT_TITLE}</h2>
|
||||
</div>
|
||||
</div>
|
||||
<hr/>
|
||||
<div class="scene_beffymaroo center-block"></div>
|
||||
<h3>Guild Spotlight: Beffymaroo's Favorites</h3>
|
||||
<div class="promo_birthday_2020 center-block"></div>
|
||||
<h3>Habitica Birthday Bash</h3>
|
||||
<p>
|
||||
For this year's Guild Spotlight series, we're highlighting some favorites from Habitica's
|
||||
staff, moderators, and maybe some high-level contributors!
|
||||
January 31st is Habitica's Birthday! Thank you so much for being a part of our
|
||||
community - it means a lot.
|
||||
</p>
|
||||
<p>Now come join us and the NPCs as we celebrate!</p>
|
||||
<h3>Cake for Everybody!</h3>
|
||||
<p>
|
||||
This month we're kicking things off with some <a
|
||||
href='https://habitica.wordpress.com/2020/01/23/guild-spotlight-our-favourites/' target=
|
||||
'_blank'>picks from Beffymaroo!</a> If you want to curate your Habitica experience and
|
||||
join active, positive Guilds, this is a great way to pick up some new ideas for Guilds
|
||||
to join.
|
||||
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 <a href='/shops/market'>Alexander the
|
||||
Merchant</a> 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, <a href='http://habitica.wikia.com/wiki/Food' target='_blank'>the
|
||||
wiki has spoilers</a>.
|
||||
</p>
|
||||
<div class="small mb-3">by Beffymaroo and shanaqui</div>
|
||||
<div class="scene_rewards center-block"></div>
|
||||
<h3>Use Case Spotlight: Custom Habitica Mechanics</h3>
|
||||
<h3>Party Robes</h3>
|
||||
<p>There are Party Robes available for free in the Rewards column! Don them with pride.</p>
|
||||
<h3>Birthday Bash Achievement</h3>
|
||||
<p>
|
||||
This month's <a href=
|
||||
'https://habitica.wordpress.com/2020/01/23/use-case-spotlight-custom-habitica-mechanics/'
|
||||
target='_blank'>Use Case Spotlight</a> is about Custom Habitica Mechanics! It features a
|
||||
number of great suggestions submitted by Habiticans in the <a href=
|
||||
'/groups/guild/1d3a10bf-60aa-4806-a38b-82d1084a59e6'>Use Case Spotlights Guild</a>. We
|
||||
hope it helps any of you who might be looking for ways to enhance your Habitica
|
||||
experience.
|
||||
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.
|
||||
</p>
|
||||
<p>
|
||||
Plus, we're collecting user submissions for the next spotlight! How do you maximize
|
||||
participation in your quest party? 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!
|
||||
</p>
|
||||
<div class="small mb-3">by shanaqui</div>
|
||||
</div>
|
||||
`,
|
||||
});
|
||||
|
||||
@@ -131,8 +131,25 @@ function _setUpNewUser (user) {
|
||||
user.items.quests.dustbunnies = 1;
|
||||
user.purchased.background.violet = true;
|
||||
user.preferences.background = 'violet';
|
||||
if (moment().isBefore('2020-02-03')) {
|
||||
user.achievements.habitBirthdays = 1;
|
||||
user.items.gear.owned.armor_special_birthday = true;
|
||||
user.items.gear.equipped.armor = 'armor_special_birthday';
|
||||
user.items.food = {
|
||||
Cake_Skeleton: 1,
|
||||
Cake_Base: 1,
|
||||
Cake_CottonCandyBlue: 1,
|
||||
Cake_CottonCandyPink: 1,
|
||||
Cake_Shade: 1,
|
||||
Cake_White: 1,
|
||||
Cake_Golden: 1,
|
||||
Cake_Zombie: 1,
|
||||
Cake_Desert: 1,
|
||||
Cake_Red: 1,
|
||||
};
|
||||
}
|
||||
|
||||
user.markModified('items');
|
||||
user.markModified('items achievements');
|
||||
|
||||
if (user.registeredThrough === 'habitica-web') {
|
||||
taskTypes = ['habit', 'daily', 'todo', 'reward', 'tag'];
|
||||
|
||||