feat(content): new freebie glasses

Fixes #11171
This commit is contained in:
Sabe Jones 2019-05-30 15:13:23 -05:00
parent c9b3c646eb
commit 3a8312832c
35 changed files with 167 additions and 8 deletions

View file

@ -16,7 +16,7 @@ const IMG_DIST_PATH = 'website/client/assets/images/sprites/';
const CSS_DIST_PATH = 'website/client/assets/css/sprites/';
function checkForSpecialTreatment (name) {
let regex = /^hair|skin|beard|mustach|shirt|flower|^headAccessory_special_\w+Ears|^eyewear_special_\w+TopFrame/;
let regex = /^hair|skin|beard|mustach|shirt|flower|^headAccessory_special_\w+Ears|^eyewear_special_\w+TopFrame|^eyewear_special_\w+HalfMoon/;
return name.match(regex) || name === 'head_0';
}

View file

@ -0,0 +1,62 @@
/* eslint-disable no-console */
const MIGRATION_NAME = '20190530_halfmoon_glasses';
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 set = {
'items.gear.owned.eyewear_special_blackHalfMoon': true,
'items.gear.owned.eyewear_special_blueHalfMoon': true,
'items.gear.owned.eyewear_special_greenHalfMoon': true,
'items.gear.owned.eyewear_special_pinkHalfMoon': true,
'items.gear.owned.eyewear_special_redHalfMoon': true,
'items.gear.owned.eyewear_special_whiteHalfMoon': true,
'items.gear.owned.eyewear_special_yellowHalfMoon': true,
};
set.migration = MIGRATION_NAME;
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
return await User.update({_id: user._id}, {$set: set}).exec();
}
module.exports = async function processUsers () {
let query = {
migration: {$ne: MIGRATION_NAME},
'auth.timestamps.loggedin': {$gt: new Date('2019-05-01')},
};
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
}
};

View file

@ -80,6 +80,13 @@ describe('shared.ops.buy', () => {
headAccessory_special_redHeadband: true,
headAccessory_special_whiteHeadband: true,
headAccessory_special_yellowHeadband: true,
eyewear_special_blackHalfMoon: true,
eyewear_special_blueHalfMoon: true,
eyewear_special_greenHalfMoon: true,
eyewear_special_pinkHalfMoon: true,
eyewear_special_redHalfMoon: true,
eyewear_special_whiteHalfMoon: true,
eyewear_special_yellowHalfMoon: true,
});
});

View file

@ -75,6 +75,13 @@ describe('shared.ops.buyMarketGear', () => {
headAccessory_special_redHeadband: true,
headAccessory_special_whiteHeadband: true,
headAccessory_special_yellowHeadband: true,
eyewear_special_blackHalfMoon: true,
eyewear_special_blueHalfMoon: true,
eyewear_special_greenHalfMoon: true,
eyewear_special_pinkHalfMoon: true,
eyewear_special_redHalfMoon: true,
eyewear_special_whiteHalfMoon: true,
eyewear_special_yellowHalfMoon: true,
});
expect(analytics.track).to.be.calledOnce;
});

View file

@ -87,7 +87,7 @@ b-modal#avatar-modal(title="", :size='editing ? "lg" : "md"', :hide-header='true
button.btn.btn-secondary.purchase-all(@click='unlock(`skin.${set.keys.join(",skin.")}`)') {{ $t('purchaseAll') }}
#hair.section.customize-section(v-if='activeTopPage === "hair"')
.row.col-12.sub-menu.text-center
.col-3.text-center.sub-menu-item(@click='changeSubPage("color")', :class='{active: activeSubPage === "color"}')
.col-3.text-center.sub-menu-item(@click='changeSubPage("color")', :class='{active: activeSubPage === "color", "offset-2": !editing}')
strong(v-once) {{$t('color')}}
.col-3.text-center.sub-menu-item(@click='changeSubPage("bangs")', :class='{active: activeSubPage === "bangs"}')
strong(v-once) {{$t('bangs')}}
@ -139,6 +139,7 @@ b-modal#avatar-modal(title="", :size='editing ? "lg" : "md"', :hide-header='true
span 5
button.btn.btn-secondary.purchase-all(@click='unlock(`hair.base.${baseHair4Keys.join(",hair.base.")}`)') {{ $t('purchaseAll') }}
.col-12.customize-options
.head_0.option(v-if="!editing", @click='set({"preferences.hair.base": 0})', :class="[{ active: user.preferences.hair.base === 0 }, 'hair_base_0_' + user.preferences.hair.color]")
.option(v-for='option in baseHair1',
:class='{active: user.preferences.hair.base === option}')
.base.sprite.customize-option(:class="`hair_base_${option}_${user.preferences.hair.color}`", @click='set({"preferences.hair.base": option})')
@ -1125,7 +1126,10 @@ export default {
return options;
},
eyewear () {
let keys = ['blackTopFrame', 'blueTopFrame', 'greenTopFrame', 'pinkTopFrame', 'redTopFrame', 'whiteTopFrame', 'yellowTopFrame'];
let keys = [
'blackTopFrame', 'blueTopFrame', 'greenTopFrame', 'pinkTopFrame', 'redTopFrame', 'whiteTopFrame', 'yellowTopFrame',
'blackHalfMoon', 'blueHalfMoon', 'greenHalfMoon', 'pinkHalfMoon', 'redHalfMoon', 'whiteHalfMoon', 'yellowHalfMoon',
];
let options = keys.map(key => {
let newKey = `eyewear_special_${key}`;
let option = {};

View file

@ -1938,6 +1938,21 @@
"eyewearSpecialYellowTopFrameText": "Yellow Standard Eyeglasses",
"eyewearSpecialYellowTopFrameNotes": "Glasses with a yellow frame above the lenses. Confers no benefit.",
"eyewearSpecialBlackHalfMoonText": "Black Half-Moon Eyeglasses",
"eyewearSpecialBlackHalfMoonNotes": "Glasses with a black frame and crescent lenses. Confers no benefit.",
"eyewearSpecialBlueHalfMoonText": "Blue Half-Moon Eyeglasses",
"eyewearSpecialBlueHalfMoonNotes": "Glasses with a blue frame and crescent lenses. Confers no benefit.",
"eyewearSpecialGreenHalfMoonText": "Green Half-Moon Eyeglasses",
"eyewearSpecialGreenHalfMoonNotes": "Glasses with a green frame and crescent lenses. Confers no benefit.",
"eyewearSpecialPinkHalfMoonText": "Pink Half-Moon Eyeglasses",
"eyewearSpecialPinkHalfMoonNotes": "Glasses with a pink frame and crescent lenses. Confers no benefit.",
"eyewearSpecialRedHalfMoonText": "Red Half-Moon Eyeglasses",
"eyewearSpecialRedHalfMoonNotes": "Glasses with a red frame and crescent lenses. Confers no benefit.",
"eyewearSpecialWhiteHalfMoonText": "White Half-Moon Eyeglasses",
"eyewearSpecialWhiteHalfMoonNotes": "Glasses with a white frame and crescent lenses. Confers no benefit.",
"eyewearSpecialYellowHalfMoonText": "Yellow Half-Moon Eyeglasses",
"eyewearSpecialYellowHalfMoonNotes": "Glasses with a yellow frame and crescent lenses. Confers no benefit.",
"eyewearSpecialAetherMaskText": "Aether Mask",
"eyewearSpecialAetherMaskNotes": "This mask has a mysterious history. Increases Intelligence by <%= int %>.",

View file

@ -1441,6 +1441,55 @@ let eyewear = {
int: 10,
canOwn: ownsItem('eyewear_special_aetherMask'),
},
blackHalfMoon: {
gearSet: 'glasses',
text: t('eyewearSpecialBlackHalfMoonText'),
notes: t('eyewearSpecialBlackHalfMoonNotes'),
value: 0,
canOwn: ownsItem('eyewear_special_blackHalfMoon'),
},
blueHalfMoon: {
gearSet: 'glasses',
text: t('eyewearSpecialBlueHalfMoonText'),
notes: t('eyewearSpecialBlueHalfMoonNotes'),
value: 0,
canOwn: ownsItem('eyewear_special_blueHalfMoon'),
},
greenHalfMoon: {
gearSet: 'glasses',
text: t('eyewearSpecialGreenHalfMoonText'),
notes: t('eyewearSpecialGreenHalfMoonNotes'),
value: 0,
canOwn: ownsItem('eyewear_special_greenHalfMoon'),
},
pinkHalfMoon: {
gearSet: 'glasses',
text: t('eyewearSpecialPinkHalfMoonText'),
notes: t('eyewearSpecialPinkHalfMoonNotes'),
value: 0,
canOwn: ownsItem('eyewear_special_pinkHalfMoon'),
},
redHalfMoon: {
gearSet: 'glasses',
text: t('eyewearSpecialRedHalfMoonText'),
notes: t('eyewearSpecialRedHalfMoonNotes'),
value: 0,
canOwn: ownsItem('eyewear_special_redHalfMoon'),
},
whiteHalfMoon: {
gearSet: 'glasses',
text: t('eyewearSpecialWhiteHalfMoonText'),
notes: t('eyewearSpecialWhiteHalfMoonNotes'),
value: 0,
canOwn: ownsItem('eyewear_special_whiteHalfMoon'),
},
yellowHalfMoon: {
gearSet: 'glasses',
text: t('eyewearSpecialYellowHalfMoonText'),
notes: t('eyewearSpecialYellowHalfMoonNotes'),
value: 0,
canOwn: ownsItem('eyewear_special_yellowHalfMoon'),
},
};
let head = {

Binary file not shown.

After

Width:  |  Height:  |  Size: 386 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 345 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 341 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 355 B

After

Width:  |  Height:  |  Size: 226 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 370 B

After

Width:  |  Height:  |  Size: 250 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 370 B

After

Width:  |  Height:  |  Size: 249 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 370 B

After

Width:  |  Height:  |  Size: 251 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 370 B

After

Width:  |  Height:  |  Size: 239 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 370 B

After

Width:  |  Height:  |  Size: 225 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 370 B

After

Width:  |  Height:  |  Size: 233 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

View file

@ -3,7 +3,7 @@ import { authWithHeaders } from '../../middlewares/auth';
let api = {};
// @TODO export this const, cannot export it from here because only routes are exported from controllers
const LAST_ANNOUNCEMENT_TITLE = 'MAY SUBSCRIBER ITEMS REVEALED!';
const LAST_ANNOUNCEMENT_TITLE = 'NEW GLASSES OPTION FOR AVATARS AND LAST CHANCE FOR MAY LIMITED-TIME ITEMS';
const worldDmg = { // @TODO
bailey: false,
};
@ -30,14 +30,29 @@ api.getNews = {
<div class="mr-3 ${baileyClass}"></div>
<div class="media-body">
<h1 class="align-self-center">${res.t('newStuff')}</h1>
<h2>5/28/2019 - ${LAST_ANNOUNCEMENT_TITLE}</h2>
<h2>5/30/2019 - ${LAST_ANNOUNCEMENT_TITLE}</h2>
</div>
</div>
<hr/>
<div class="promo_halfmoon_glasses center-block"></div>
<h3>New Glasses Option for Avatars</h3>
<p>We have a new set of free avatar customizations available: half-moon glasses! We hope that all you glasses-wearing Habiticans out there will enjoy these new options. You can find them in User>Edit Avatar>Extras.</p>
<div class="small mb-3">by Breadstrings and SabreCat</div>
<div class="promo_mystery_201905 center-block"></div>
<p>The May Subscriber Item has been revealed: the Dazzling Dragon Item Set! You only have until May 31 to receive the item set <a href='/user/settings/subscription'>when you subscribe</a>. If you're already an active subscriber, reload the site and then head to Inventory > Items to claim your gear!</p>
<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.</p>
<div class="small mb-3">by beffymaroo</div>
<h3>Last Chance for Dazzling Dragon Set</h3>
<p>Reminder: tomorrow is the final day to <a href='/user/settings/subscription'>subscribe</a> and receive the Dazzling Dragon Set! Subscribing also lets you buy Gems with Gold. The longer your subscription, the more Gems you get!</p>
<p>Thanks so much for your support! You help keep Habitica running.</p>
<div class="small mb-3">by Beffymaroo</div>
<div class="promo_floral_sunshine_potions center-block"></div>
<h3>Last Chance for Sunshine and Floral Hatching Potions</h3>
<p>Reminder: tomorrow is the final day to <a href='/shops/market'>buy Sunshine and Floral Hatching Potions</a>! If they come back, it won't be until next year at the earliest, so don't delay!</p>
<div class="small mb-3">by OuttaMyMind, Lt.Cabel, Eslyn, Mako, and SabreCat</div>
<div class="promo_feathered_friends_bundle center-block"></div>
<h3>Last Chance for Feathered Friends Quest Bundle</h3>
<p>Tomorrow is also the final day to buy the discounted Feathered Friends Pet Quest Bundle, featuring the Falcon, Parrot, and Owl quests all for seven Gems! Be sure to get a few in your talons before they fly away! The bundle can be found in the <a href='/shops/quests'>Quest Shop</a>.</p>
<div class="small">by Lemoness and SabreCat</div>
<div class="small">Art by Casey, Teto Forever, Eevachu, UncommonCriminal, JonArinbjorn, Trogdorina, Onheiron, Squish</div>
<div class="small mb-3">Writing by Lemoness, Token, and Bartelmy</div>
</div>
`,
});