feat(content): Animal Tails

This commit is contained in:
Sabe Jones
2018-08-29 15:20:09 -05:00
parent cf4b920a67
commit f802a41f75
32 changed files with 171 additions and 66 deletions

View File

@@ -193,8 +193,10 @@ b-modal#avatar-modal(title="", :size='editing ? "lg" : "md"', :hide-header='true
.col-3.text-center.sub-menu-item(@click='changeSubPage("flower")', :class='{active: activeSubPage === "flower"}')
strong(v-once) {{$t('accent')}}
.row.sub-menu(v-if='editing')
.col-4.offset-2.text-center.sub-menu-item(@click='changeSubPage("ears")' :class='{active: activeSubPage === "ears"}')
.col-4.text-center.sub-menu-item(@click='changeSubPage("ears")' :class='{active: activeSubPage === "ears"}')
strong(v-once) {{$t('animalEars')}}
.col-4.text-center.sub-menu-item(@click='changeSubPage("tails")' :class='{active: activeSubPage === "tails"}')
strong(v-once) {{$t('animalTails')}}
.col-4.text-center.sub-menu-item(@click='changeSubPage("headband")' :class='{active: activeSubPage === "headband"}')
strong(v-once) {{$t('headband')}}
#glasses.row(v-if='activeSubPage === "glasses"')
@@ -203,17 +205,30 @@ b-modal#avatar-modal(title="", :size='editing ? "lg" : "md"', :hide-header='true
.sprite.customize-option(:class="`eyewear_special_${option.key}`", @click='option.click')
#animal-ears.row(v-if='activeSubPage === "ears"')
.section.col-12.customize-options
.option(v-for='option in animalEars',
.option(v-for='option in animalItems("headAccessory")',
:class='{active: option.active, locked: option.locked}')
.sprite.customize-option(:class="`headAccessory_special_${option.key}`", @click='option.click')
.gem-lock(v-if='option.locked')
.svg-icon.gem(v-html='icons.gem')
span 2
.col-12.text-center(v-if='!animalEarsOwned')
.col-12.text-center(v-if='!animalItemsOwned("headAccessory")')
.gem-lock
.svg-icon.gem(v-html='icons.gem')
span 5
button.btn.btn-secondary.purchase-all(@click='unlock(animalEarsUnlockString)') {{ $t('purchaseAll') }}
button.btn.btn-secondary.purchase-all(@click='unlock(animalItemsUnlockString("headAccessory"))') {{ $t('purchaseAll') }}
#animal-tails.row(v-if='activeSubPage === "tails"')
.section.col-12.customize-options
.option(v-for='option in animalItems("back")',
:class='{active: option.active, locked: option.locked}')
.sprite.customize-option(:class="`icon_back_special_${option.key}`", @click='option.click')
.gem-lock(v-if='option.locked')
.svg-icon.gem(v-html='icons.gem')
span 2
.col-12.text-center(v-if='!animalItemsOwned("back")')
.gem-lock
.svg-icon.gem(v-html='icons.gem')
span 5
button.btn.btn-secondary.purchase-all(@click='unlock(animalItemsUnlockString("back"))') {{ $t('purchaseAll') }}
#headband.row(v-if='activeSubPage === "headband"')
.col-12.customize-options
.option(v-for='option in headbands', :class='{active: option.active}')
@@ -1013,7 +1028,10 @@ export default {
baseHair4Keys: [15, 16, 17, 18, 19, 20],
baseHair5Keys: [1, 2],
baseHair6Keys: [1, 2, 3],
animalEarsKeys: ['bearEars', 'cactusEars', 'foxEars', 'lionEars', 'pandaEars', 'pigEars', 'tigerEars', 'wolfEars'],
animalItemKeys: {
back: ['bearTail', 'cactusTail', 'foxTail', 'lionTail', 'pandaTail', 'pigTail', 'tigerTail', 'wolfTail'],
headAccessory: ['bearEars', 'cactusEars', 'foxEars', 'lionEars', 'pandaEars', 'pigEars', 'tigerEars', 'wolfEars'],
},
chairKeys: ['black', 'blue', 'green', 'pink', 'red', 'yellow', 'handleless_black', 'handleless_blue', 'handleless_green', 'handleless_pink', 'handleless_red', 'handleless_yellow'],
icons: Object.freeze({
logoPurple,
@@ -1075,44 +1093,6 @@ export default {
});
return options;
},
animalEarsUnlockString () {
let animalItemKeys = this.animalEarsKeys.map(key => {
return `items.gear.owned.headAccessory_special_${key}`;
});
return animalItemKeys.join(',');
},
animalEarsOwned () {
// @TODO: For some resonse when I use $set on the user purchases object, this is not recomputed. Hack for now
let backgroundUpdate = this.backgroundUpdate; // eslint-disable-line
let own = true;
this.animalEarsKeys.forEach(key => {
if (!this.user.items.gear.owned[`headAccessory_special_${key}`]) own = false;
});
return own;
},
animalEars () {
// @TODO: For some resonse when I use $set on the user purchases object, this is not recomputed. Hack for now
let backgroundUpdate = this.backgroundUpdate; // eslint-disable-line
let keys = this.animalEarsKeys;
let options = keys.map(key => {
let newKey = `headAccessory_special_${key}`;
let userPurchased = this.user.items.gear.owned[newKey];
let locked = !userPurchased;
let option = {};
option.key = key;
option.active = this.user.preferences.costume ? this.user.items.gear.costume.headAccessory === newKey : this.user.items.gear.equipped.headAccessory === newKey;
option.locked = locked;
option.click = () => {
let type = this.user.preferences.costume ? 'costume' : 'equipped';
return locked ? this.unlock(`items.gear.owned.${newKey}`) : this.equip(newKey, type);
};
return option;
});
return options;
},
specialShirts () {
// @TODO: For some resonse when I use $set on the user purchases object, this is not recomputed. Hack for now
let backgroundUpdate = this.backgroundUpdate; // eslint-disable-line
@@ -1550,6 +1530,44 @@ export default {
backgroundPurchased () {
this.backgroundUpdate = new Date();
},
animalItemsUnlockString (category) {
const keys = this.animalItemKeys[category].map(key => {
return `items.gear.owned.${category}_special_${key}`;
});
return keys.join(',');
},
animalItemsOwned (category) {
// @TODO: For some resonse when I use $set on the user purchases object, this is not recomputed. Hack for now
let backgroundUpdate = this.backgroundUpdate; // eslint-disable-line
let own = true;
this.animalItemKeys[category].forEach(key => {
if (!this.user.items.gear.owned[`${category}_special_${key}`]) own = false;
});
return own;
},
animalItems (category) {
// @TODO: For some resonse when I use $set on the user purchases object, this is not recomputed. Hack for now
let backgroundUpdate = this.backgroundUpdate; // eslint-disable-line
let keys = this.animalItemKeys[category];
let options = keys.map(key => {
let newKey = `${category}_special_${key}`;
let userPurchased = this.user.items.gear.owned[newKey];
let locked = !userPurchased;
let option = {};
option.key = key;
option.active = this.user.preferences.costume ? this.user.items.gear.costume[category] === newKey : this.user.items.gear.equipped[category] === newKey;
option.locked = locked;
option.click = () => {
let type = this.user.preferences.costume ? 'costume' : 'equipped';
return locked ? this.unlock(`items.gear.owned.${newKey}`) : this.equip(newKey, type);
};
return option;
});
return options;
},
},
};
</script>

View File

@@ -1512,6 +1512,7 @@
"backCapitalized": "Back Accessory",
"backBase0Text": "No Back Accessory",
"backBase0Notes": "No Back Accessory.",
"animalTails": "Animal Tails",
"backMystery201402Text": "Golden Wings",
"backMystery201402Notes": "These shining wings have feathers that glitter in the sun! Confers no benefit. February 2014 Subscriber Item.",
@@ -1558,6 +1559,22 @@
"backSpecialAetherCloakNotes": "This cloak once belonged to the Lost Masterclasser herself. Increases Perception by <%= per %>.",
"backSpecialTurkeyTailBaseText": "Turkey Tail",
"backSpecialTurkeyTailBaseNotes": "Wear your noble Turkey Tail with pride while you celebrate! Confers no benefit.",
"backBearTailText": "Bear Tail",
"backBearTailNotes": "This tail makes you look like a brave bear! Confers no benefit.",
"backCactusTailText": "Cactus Tail",
"backCactusTailNotes": "This tail makes you look like a prickly cactus! Confers no benefit.",
"backFoxTailText": "Fox Tail",
"backFoxTailNotes": "This tail makes you look like a wily fox! Confers no benefit.",
"backLionTailText": "Lion Tail",
"backLionTailNotes": "This tail makes you look like a regal lion! Confers no benefit.",
"backPandaTailText": "Panda Tail",
"backPandaTailNotes": "This tail makes you look like a gentle panda! Confers no benefit.",
"backPigTailText": "Pig Tail",
"backPigTailNotes": "This tail makes you look like a whimsical pig! Confers no benefit.",
"backTigerTailText": "Tiger Tail",
"backTigerTailNotes": "This tail makes you look like a fierce tiger! Confers no benefit.",
"backWolfTailText": "Wolf Tail",
"backWolfTailNotes": "This tail makes you look like a loyal wolf! Confers no benefit.",
"body": "Body Accessory",
"bodyCapitalized": "Body Accessory",

View File

@@ -1029,6 +1029,86 @@ let back = {
value: 0,
canOwn: ownsItem('back_special_turkeyTailBase'),
},
bearTail: {
gearSet: 'animal',
text: t('backBearTailText'),
notes: t('backBearTailNotes'),
value: 20,
canOwn: ownsItem('back_special_bearTail'),
canBuy: () => {
return true;
},
},
cactusTail: {
gearSet: 'animal',
text: t('backCactusTailText'),
notes: t('backCactusTailNotes'),
value: 20,
canOwn: ownsItem('back_special_cactusTail'),
canBuy: () => {
return true;
},
},
foxTail: {
gearSet: 'animal',
text: t('backFoxTailText'),
notes: t('backFoxTailNotes'),
value: 20,
canOwn: ownsItem('back_special_foxTail'),
canBuy: () => {
return true;
},
},
lionTail: {
gearSet: 'animal',
text: t('backLionTailText'),
notes: t('backLionTailNotes'),
value: 20,
canOwn: ownsItem('back_special_lionTail'),
canBuy: () => {
return true;
},
},
pandaTail: {
gearSet: 'animal',
text: t('backPandaTailText'),
notes: t('backPandaTailNotes'),
value: 20,
canOwn: ownsItem('back_special_pandaTail'),
canBuy: () => {
return true;
},
},
pigTail: {
gearSet: 'animal',
text: t('backPigTailText'),
notes: t('backPigTailNotes'),
value: 20,
canOwn: ownsItem('back_special_pigTail'),
canBuy: () => {
return true;
},
},
tigerTail: {
gearSet: 'animal',
text: t('backTigerTailText'),
notes: t('backTigerTailNotes'),
value: 20,
canOwn: ownsItem('back_special_tigerTail'),
canBuy: () => {
return true;
},
},
wolfTail: {
gearSet: 'animal',
text: t('backWolfTailText'),
notes: t('backWolfTailNotes'),
value: 20,
canOwn: ownsItem('back_special_wolfTail'),
canBuy: () => {
return true;
},
},
};
let body = {

Binary file not shown.

After

Width:  |  Height:  |  Size: 474 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 471 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 531 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 474 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 486 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 570 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 525 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 636 B

After

Width:  |  Height:  |  Size: 636 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 247 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 768 B

After

Width:  |  Height:  |  Size: 768 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 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 = 'AUGUST SUBSCRIBER ITEMS AND WIKI SPOTLIGHT ON CUSTOMIZING THE HABITICA EXPERIENCE';
const LAST_ANNOUNCEMENT_TITLE = 'NEW AVATAR CUSTOMIZATIONS: ANIMAL TAILS';
const worldDmg = { // @TODO
bailey: false,
};
@@ -26,30 +26,20 @@ api.getNews = {
res.status(200).send({
html: `
<div class="bailey">
<div class="media">
<div class="media-body">
<div class="media align-items-center">
<div class="mr-3 ${baileyClass}"></div>
<div class="media-body">
<h1 class="align-self-center">${res.t('newStuff')}</h1>
<h2>8/23/2018 - ${LAST_ANNOUNCEMENT_TITLE}</h2>
<h2>8/29/2018 - ${LAST_ANNOUNCEMENT_TITLE}</h2>
</div>
</div>
<hr/>
<div class="media align-items-center">
<div class="media-body">
<h3>August Subscriber Set Revealed!</h3>
<p>Subscriber Items for August have been revealed: the Lava Dragon Item Set! You only have until August 31 to receive the item set when you <a href='/user/settings/subscription' target='_blank'>subscribe</a>. If you're already an active subscriber, reload the site and then head to Inventory > Items to claim your gear!</p>
</div>
<div class="promo_mystery_201808 ml-3"></div>
</div>
<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>
<div class="media align-items-center">
<div class="scene_casting_spells mr-3 mb-3"></div>
<div class="media-body">
<h3>Blog Post: Creating a Unique Experience</h3>
<p>This month's <a href='https://habitica.wordpress.com/2018/08/22/creating-a-unique-experience/' target='_blank'>featured Wiki article</a> is about using Habitica's features to create a unique experience! We hope that it will help you as you customize Habitica to make the app even more motivating and fun. Be sure to check it out, and let us know what you think by reaching out on <a href='https://twitter.com/habitica' target='_blank'>Twitter</a>, <a href='http://blog.habitrpg.com' target='_blank'>Tumblr</a>, and <a href='https://facebook.com/habitica' target='_blank'>Facebook</a>.</p>
<div class="small mb-3">by shanaqui and the Wiki Wizards</div>
<p>There are new customizations available for your avatar! Check out our new sets of tails to match the Animal Skins and Ears--you'll match your pets better than ever. You can find them in User > Avatar > Extra. Enjoy!</p>
<div class="small">by tricksy.fox, Beffymaroo, and SabreCat</div>
</div>
<div class="promo_animal_tails ml-3 mb-3"></div>
</div>
</div>
`,