Merge branch 'release' into develop

This commit is contained in:
Sabe Jones 2019-12-31 06:52:22 -06:00
commit df72d240fd
69 changed files with 9958 additions and 9722 deletions

View file

@ -0,0 +1,118 @@
/* eslint-disable no-console */
const MIGRATION_NAME = '20191231_nye';
import { model as User } from '../../../website/server/models/user';
import { v4 as uuid } from 'uuid';
const progressCount = 1000;
let count = 0;
async function updateUser (user) {
count++;
const set = {'flags.newStuff': true};
let push;
set.migration = MIGRATION_NAME;
if (typeof user.items.gear.owned.head_special_nye2018 !== 'undefined') {
set['items.gear.owned.head_special_nye2019'] = false;
push = [
{
type: 'marketGear',
path: 'gear.flat.head_special_nye2019',
_id: uuid(),
},
];
} else if (typeof user.items.gear.owned.head_special_nye2017 !== 'undefined') {
set['items.gear.owned.head_special_nye2018'] = false;
push = [
{
type: 'marketGear',
path: 'gear.flat.head_special_nye2018',
_id: uuid(),
},
];
} else if (typeof user.items.gear.owned.head_special_nye2016 !== 'undefined') {
set['items.gear.owned.head_special_nye2017'] = false;
push = [
{
type: 'marketGear',
path: 'gear.flat.head_special_nye2017',
_id: uuid(),
},
];
} else if (typeof user.items.gear.owned.head_special_nye2015 !== 'undefined') {
set['items.gear.owned.head_special_nye2016'] = false;
push = [
{
type: 'marketGear',
path: 'gear.flat.head_special_nye2016',
_id: uuid(),
},
];
} else if (typeof user.items.gear.owned.head_special_nye2014 !== 'undefined') {
set['items.gear.owned.head_special_nye2015'] = false;
push = [
{
type: 'marketGear',
path: 'gear.flat.head_special_nye2015',
_id: uuid(),
},
];
} else if (typeof user.items.gear.owned.head_special_nye !== 'undefined') {
set['items.gear.owned.head_special_nye2014'] = false;
push = [
{
type: 'marketGear',
path: 'gear.flat.head_special_nye2014',
_id: uuid(),
},
];
} else {
set['items.gear.owned.head_special_nye'] = false;
push = [
{
type: 'marketGear',
path: 'gear.flat.head_special_nye',
_id: uuid(),
},
];
}
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
return await User.update({_id: user._id}, {$set: set, $push: {pinnedItems: {$each: push}}}).exec();
}
export default async function processUsers () {
let query = {
migration: {$ne: MIGRATION_NAME},
};
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
package-lock.json generated
View file

@ -1,6 +1,6 @@
{
"name": "habitica",
"version": "4.127.4",
"version": "4.128.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View file

@ -1,7 +1,7 @@
{
"name": "habitica",
"description": "A habit tracker app which treats your goals like a Role Playing Game.",
"version": "4.127.4",
"version": "4.128.0",
"main": "./website/server/index.js",
"dependencies": {
"@babel/core": "^7.7.7",

View file

@ -1,60 +1,66 @@
.promo_achievement_white {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -910px 0px;
background-position: -862px -233px;
width: 204px;
height: 102px;
}
.promo_armoire_backgrounds_201912 {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -424px -327px;
background-position: -424px -475px;
width: 423px;
height: 147px;
}
.promo_g1g1_2019 {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -403px -475px;
background-position: -469px -327px;
width: 357px;
height: 144px;
}
.promo_mystery_201912 {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -462px -623px;
background-position: -424px -623px;
width: 282px;
height: 147px;
}
.promo_snowballs {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -441px 0px;
width: 420px;
height: 174px;
}
.promo_take_this {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -910px -103px;
background-position: -862px -336px;
width: 96px;
height: 69px;
}
.promo_winter_potions_2020 {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: 0px -327px;
background-position: 0px -475px;
width: 423px;
height: 147px;
}
.promo_winter_quests_bundle {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -441px -148px;
background-position: 0px -623px;
width: 423px;
height: 147px;
}
.promo_winter_wonderland_2019 {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: 0px -475px;
background-position: -441px -175px;
width: 402px;
height: 147px;
}
.promo_winter_wonderland_2020 {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -441px 0px;
background-position: 0px -327px;
width: 468px;
height: 147px;
}
.scene_studying_hard {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: 0px -623px;
background-position: -862px 0px;
width: 220px;
height: 232px;
}
@ -66,7 +72,7 @@
}
.scene_todos {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -221px -623px;
background-position: 0px -771px;
width: 240px;
height: 195px;
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 115 KiB

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 346 KiB

After

Width:  |  Height:  |  Size: 336 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 335 KiB

After

Width:  |  Height:  |  Size: 338 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 KiB

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 159 KiB

After

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 KiB

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 137 KiB

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 173 KiB

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 KiB

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 149 KiB

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 KiB

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 143 KiB

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 163 KiB

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 178 KiB

After

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 159 KiB

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 KiB

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 KiB

After

Width:  |  Height:  |  Size: 129 KiB

View file

@ -2,8 +2,8 @@
// 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_market_flavor: 'nye';
$npc_quests_flavor: 'nye';
$npc_seasonal_flavor: 'nye';
$npc_timetravelers_flavor: 'winter';
$npc_tavern_flavor: 'winter';
$npc_tavern_flavor: 'nye';

View file

@ -212,7 +212,7 @@ export default {
},
visualBuffs () {
return {
snowball: 'snowman',
snowball: `avatar_snowball_${this.member.stats.class}`,
spookySparkles: 'ghost',
shinySeed: `avatar_floral_${this.member.stats.class}`,
seafoam: 'seafoam_star',

View file

@ -125,13 +125,13 @@ context('avatar.vue', () => {
it('returns an array of buffs', () => {
vm.member = {
stats: {
class: 'Warrior',
class: 'warrior',
},
};
expect(vm.visualBuffs).to.include({ snowball: 'snowman' });
expect(vm.visualBuffs).to.include({ snowball: 'avatar_snowball_warrior' });
expect(vm.visualBuffs).to.include({ spookySparkles: 'ghost' });
expect(vm.visualBuffs).to.include({ shinySeed: 'avatar_floral_Warrior' });
expect(vm.visualBuffs).to.include({ shinySeed: 'avatar_floral_warrior' });
expect(vm.visualBuffs).to.include({ seafoam: 'seafoam_star' });
});
});

View file

@ -1334,6 +1334,8 @@
"headSpecialFall2019HealerText": "Dark Miter",
"headSpecialFall2019HealerNotes": "Don this dark miter to harness the powers of the fearsome Lich. Increases Intelligence by <%= int %>. Limited Edition 2019 Autumn Gear.",
"headSpecialNye2019Text": "Outrageous Party Hat",
"headSpecialNye2019Notes": "You've received an Outrageous Party Hat! Wear it with pride while ringing in the New Year! Confers no benefit.",
"headSpecialWinter2020RogueText": "Floofy Stocking Cap",
"headSpecialWinter2020RogueNotes": "A Rogue walks down the street in that hat, people know they're not afraid of anything. Increases Perception by <%= per %>. Limited Edition 2019-2020 Winter Gear.",
"headSpecialWinter2020WarriorText": "Snow-Dusted Headdress",
@ -1440,8 +1442,10 @@
"headMystery201910Notes": "These flames reveal arcane secrets before your very eyes! Confers no benefit. October 2019 Subscriber Item.",
"headMystery201911Text": "Charmed Crystal Hat",
"headMystery201911Notes": "Each of the crystal points attached to this hat endows you with a special power: mystic clairvoyance, arcane wisdom, and... sorcerous plate spinning? All right then. Confers no benefit. November 2019 Subscriber Item.",
"headMystery201912Text": "Polar Pixie Crown",
"headMystery201912Notes": "This glittering snowflake grants you resistance to the biting cold no matter how high you fly! Confers no benefit. December 2019 Subscriber Item.",
"headMystery201912Text": "Fabled Fox Ears",
"headMystery201912Notes": "Your hearing will be so sharp, you'll hear the stars twinkling and the moon spinning. Confers no benefit. January 2020 Subscriber Item.",
"headMystery202001Text": "Polar Pixie Crown",
"headMystery202001Notes": "This glittering snowflake grants you resistance to the biting cold no matter how high you fly! Confers no benefit. December 2019 Subscriber Item.",
"headMystery301404Text": "Fancy Top Hat",
"headMystery301404Notes": "A fancy top hat for the finest of gentlefolk! January 3015 Subscriber Item. Confers no benefit.",
"headMystery301405Text": "Basic Top Hat",
@ -1916,6 +1920,8 @@
"backMystery201905Notes": "Fly to untold realms with these iridescent wings. Confers no benefit. May 2019 Subscriber Item.",
"backMystery201912Text": "Polar Pixie Wings",
"backMystery201912Notes": "Glide silently across sparkling snowfields and shimmering mountains with these icy wings. Confers no benefit. December 2019 Subscriber Item.",
"backMystery202001Text": "Five Tails of Fable",
"backMystery202001Notes": "These fluffy tails contain celestial power, and also a high level of cuteness! Confers no benefit. January 2020 Subscriber Item.",
"backSpecialWonderconRedText": "Mighty Cape",
"backSpecialWonderconRedNotes": "Swishes with strength and beauty. Confers no benefit. Special Edition Convention Item.",

View file

@ -650,7 +650,7 @@
"questYarnUnlockText": "Unlocks Yarn Eggs for purchase in the Market",
"winterQuestsText": "Winter Quest Bundle",
"winterQuestsNotes": "Contains 'Trapper Santa', 'Find the Cub', and 'The Fowl Frost'. Available until December 31. Note that Trapper Santa and Find the Cub have stackable quest achievements but give a rare pet and mount that can only be added to your stable once.",
"winterQuestsNotes": "Contains 'Trapper Santa', 'Find the Cub', and 'The Fowl Frost'. Available until January 31. Note that Trapper Santa and Find the Cub have stackable quest achievements but give a rare pet and mount that can only be added to your stable once.",
"questPterodactylText": "The Pterror-dactyl",
"questPterodactylNotes": "You're taking a stroll along the peaceful Stoïkalm Cliffs when an evil screech rends the air. You turn to find a hideous creature flying towards you and are overcome by a powerful terror. As you turn to flee, @Lilith of Alfheim grabs you. \"Don't panic! It's just a Pterror-dactyl.\"<br><br>@Procyon P nods. \"They nest nearby, but they're attracted to the scent of negative Habits and undone Dailies.\"<br><br>\"Don't worry,\" @Katy133 says. \"We just need to be extra productive to defeat it!\" You are filled with a renewed sense of purpose and turn to face your foe.",

View file

@ -166,6 +166,7 @@
"mysterySet201910": "Cryptic Flame Set",
"mysterySet201911": "Crystal Charmer Set",
"mysterySet201912": "Polar Pixie Set",
"mysterySet202001": "Fabled Fox Set",
"mysterySet301404": "Steampunk Standard Set",
"mysterySet301405": "Steampunk Accessories Set",
"mysterySet301703": "Peacock Steampunk Set",

View file

@ -400,6 +400,12 @@ const back = {
mystery: '201912',
value: 0,
},
202001: {
text: t('backMystery202001Text'),
notes: t('backMystery202001Notes'),
mystery: '202001',
value: 0,
},
};
const body = {
@ -775,6 +781,12 @@ const head = {
mystery: '201912',
value: 0,
},
202001: {
text: t('headMystery202001Text'),
notes: t('headMystery202001Notes'),
mystery: '202001',
value: 0,
},
301404: {
text: t('headMystery301404Text'),
notes: t('headMystery301404Notes'),

View file

@ -2614,6 +2614,12 @@ const head = {
value: 60,
int: 7,
},
nye2019: {
text: t('headSpecialNye2019Text'),
notes: t('headSpecialNye2019Notes'),
value: 0,
canOwn: ownsItem('head_special_nye2019'),
},
};
const headAccessory = {

View file

@ -1,5 +1,6 @@
import defaults from 'lodash/defaults';
import each from 'lodash/each';
import moment from 'moment';
import t from './translation';
import { tasksByCategory } from './tasks';
@ -117,6 +118,7 @@ api.cardTypes = {
nye: {
key: 'nye',
messageOptions: 5,
yearRound: moment().isBefore('2020-01-02'),
},
thankyou: {
key: 'thankyou',

View file

@ -8,8 +8,8 @@ const featuredItems = {
if (moment().isBetween('2019-12-19', '2020-02-02')) {
return [
{
type: 'armoire',
path: 'armoire',
type: 'card',
path: 'cardTypes.nye',
},
{
type: 'premiumHatchingPotion',

View file

@ -19,6 +19,7 @@ export default {
},
availableSpells: [
'snowball',
],
availableQuests: [

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 546 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 489 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 543 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,009 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9 KiB

View file

@ -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: NEW GUILDS AND USING HABITICAS SOCIAL SPACES';
const LAST_ANNOUNCEMENT_TITLE = 'DECEMBER LAST CHANCE, SNOWBALLS, NEW YEARS RESOLUTION BLOG POST, AND NEW YEARS HAT AND CARDS!';
const worldDmg = { // @TODO
bailey: false,
};
@ -31,38 +31,54 @@ api.getNews = {
<div class="mr-3 ${baileyClass}"></div>
<div class="media-body">
<h1 class="align-self-center">${res.t('newStuff')}</h1>
<h2>12/19/2019 - ${LAST_ANNOUNCEMENT_TITLE}</h2>
<h2>12/31/2019 - ${LAST_ANNOUNCEMENT_TITLE}</h2>
</div>
</div>
<hr/>
<div class="scene_studying_hard center-block"></div>
<h3>Monthly Guild Spotlight</h3>
<div class="npc_justin center-block"></div>
<h3>Party Hats</h3>
<p>
There's a new <a
href='https://habitica.wordpress.com/2019/12/26/new-and-notable-guild-spotlight-12/'
target='_blank'>Guild Spotlight on the blog</a> that highlights yet another selection of
the upcoming Guilds in Habitica dedicated to a variety of topics! Check it out now to
find some of Habitica's best new communities.
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!
</p>
<div class="small mb-3">by shanaqui</div>
<div class="scene_tavern center-block"></div>
<h3>Use Case Spotlight: Habitica's Social Spaces</h3>
<div class="small mb-3">by Lemoness and SabreCat</div>
<div class="inventory_special_nye center-block"></div>
<h3>New Year's Cards</h3>
<p>
This month's <a href='https://habitica.wordpress.com/2019/12/26/
use-case-spotlight-using-habiticas-social-spaces-to-motivate-yourself/' target='_blank'>
Use Case Spotlight</a> is about Using Habitica's Social Spaces for Motivation! 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 support and camaraderie as you pursue your goals.
Until January 1st only, the <a href='/shops/market'>Market</a> 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!
</p>
<div class="small mb-3">by Lemoness and SabreCat</div>
<h3>Blog Post: Jumpstart your 2020 Resolution with Habitica!</h3>
<p>
Plus, we're collecting user submissions for the next spotlight! How do you customize
Habitica to add extra excitement and motivation? Well 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!
Do you have a special resolution or goal for the coming year? Check out a new post on the
<a href='https://habitica.wordpress.com/2019/12/26/jump-starting-your-2020-new-years-
resolution-with-habitica/' target='_blank'>Habitica Blog</a> with our best tips and resources to
help you make and keep your 2020 resolution!
</p>
<div class="small mb-3">by shanaqui</div>
<div class="small mb-3">by Beffymaroo</div>
<div class="promo_snowballs center-block"></div>
<h3>Snowballs!</h3>
<p>
The <a href='/shops/seasonal'>Seasonal Shop</a> is also 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.
</p>
<div class="small mb-3">by Shaner and Lemoness</div>
<div class="promo_mystery_201912 center-block"></div>
<h3>Last Chance for Polar Pixie Set</h3>
<p>
Reminder: the 31st is the final day to <a href='/user/settings/subscription'>
subscribe</a> and receive the Polar Pixie item set! Subscribers also get a cute Jackalope
pet, and the ability to buy Gems with Gold. The longer your subscription, the more Gems
you can get!
</p>
<p>Thanks so much for your support! You help keep Habitica running.</p>
<div class="small mb-3">by Beffymaroo</div>
</div>
`,
});

View file

@ -131,6 +131,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;
user.items.gear.equipped.head = 'head_special_nye';
user.markModified('items');