mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-16 22:27:26 +01:00
Animal ears after death (#10691)
* Animal Ears purchasable with Gold if lost in Death * remove ears from pinned items when set is bought * standardise css and error handling for gems and coins * revert accidental new line
This commit is contained in:
@@ -208,9 +208,12 @@ b-modal#avatar-modal(title="", :size='editing ? "lg" : "md"', :hide-header='true
|
|||||||
.option(v-for='option in animalItems("headAccessory")',
|
.option(v-for='option in animalItems("headAccessory")',
|
||||||
:class='{active: option.active, locked: option.locked}')
|
:class='{active: option.active, locked: option.locked}')
|
||||||
.sprite.customize-option(:class="`headAccessory_special_${option.key}`", @click='option.click')
|
.sprite.customize-option(:class="`headAccessory_special_${option.key}`", @click='option.click')
|
||||||
.gem-lock(v-if='option.locked')
|
.gem-lock(v-if='option.gemLocked')
|
||||||
.svg-icon.gem(v-html='icons.gem')
|
.svg-icon.gem(v-html='icons.gem')
|
||||||
span 2
|
span 2
|
||||||
|
.gold-lock(v-if='option.goldLocked')
|
||||||
|
.svg-icon.gold(v-html='icons.gold')
|
||||||
|
span 20
|
||||||
.col-12.text-center(v-if='!animalItemsOwned("headAccessory")')
|
.col-12.text-center(v-if='!animalItemsOwned("headAccessory")')
|
||||||
.gem-lock
|
.gem-lock
|
||||||
.svg-icon.gem(v-html='icons.gem')
|
.svg-icon.gem(v-html='icons.gem')
|
||||||
@@ -221,9 +224,12 @@ b-modal#avatar-modal(title="", :size='editing ? "lg" : "md"', :hide-header='true
|
|||||||
.option(v-for='option in animalItems("back")',
|
.option(v-for='option in animalItems("back")',
|
||||||
:class='{active: option.active, locked: option.locked}')
|
:class='{active: option.active, locked: option.locked}')
|
||||||
.sprite.customize-option(:class="`icon_back_special_${option.key}`", @click='option.click')
|
.sprite.customize-option(:class="`icon_back_special_${option.key}`", @click='option.click')
|
||||||
.gem-lock(v-if='option.locked')
|
.gem-lock(v-if='option.gemLocked')
|
||||||
.svg-icon.gem(v-html='icons.gem')
|
.svg-icon.gem(v-html='icons.gem')
|
||||||
span 2
|
span 2
|
||||||
|
.gold-lock(v-if='option.goldLocked')
|
||||||
|
.svg-icon.gold(v-html='icons.gold')
|
||||||
|
span 20
|
||||||
.col-12.text-center(v-if='!animalItemsOwned("back")')
|
.col-12.text-center(v-if='!animalItemsOwned("back")')
|
||||||
.gem-lock
|
.gem-lock
|
||||||
.svg-icon.gem(v-html='icons.gem')
|
.svg-icon.gem(v-html='icons.gem')
|
||||||
@@ -585,20 +591,21 @@ b-modal#avatar-modal(title="", :size='editing ? "lg" : "md"', :hide-header='true
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-center .gem-lock {
|
.text-center {
|
||||||
|
.gem-lock, .gold-lock {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-right: 1em;
|
margin-right: 1em;
|
||||||
margin-bottom: 1.6em;
|
margin-bottom: 1.6em;
|
||||||
vertical-align: bottom;
|
vertical-align: bottom;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.gem-lock {
|
.gem-lock, .gold-lock {
|
||||||
.svg-icon {
|
.svg-icon {
|
||||||
width: 16px;
|
width: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
span {
|
span {
|
||||||
color: #24cc8f;
|
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
margin-left: .5em;
|
margin-left: .5em;
|
||||||
}
|
}
|
||||||
@@ -609,6 +616,14 @@ b-modal#avatar-modal(title="", :size='editing ? "lg" : "md"', :hide-header='true
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.gem-lock span {
|
||||||
|
color: $green-10
|
||||||
|
}
|
||||||
|
|
||||||
|
.gold-lock span {
|
||||||
|
color: $yellow-10
|
||||||
|
}
|
||||||
|
|
||||||
.option.active {
|
.option.active {
|
||||||
border-color: $purple-200;
|
border-color: $purple-200;
|
||||||
}
|
}
|
||||||
@@ -725,7 +740,7 @@ b-modal#avatar-modal(title="", :size='editing ? "lg" : "md"', :hide-header='true
|
|||||||
color: #24cc8f;
|
color: #24cc8f;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gem {
|
.gem, .coin {
|
||||||
width: 16px;
|
width: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -740,13 +755,13 @@ b-modal#avatar-modal(title="", :size='editing ? "lg" : "md"', :hide-header='true
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gem {
|
.gem, .coin {
|
||||||
width: 20px;
|
width: 20px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.gem {
|
.gem, .coin {
|
||||||
margin: 0 .5em;
|
margin: 0 .5em;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
vertical-align: bottom;
|
vertical-align: bottom;
|
||||||
@@ -852,6 +867,7 @@ import { mapState } from 'client/libs/store';
|
|||||||
import avatar from './avatar';
|
import avatar from './avatar';
|
||||||
import { getBackgroundShopSets } from '../../common/script/libs/shops';
|
import { getBackgroundShopSets } from '../../common/script/libs/shops';
|
||||||
import unlock from '../../common/script/ops/unlock';
|
import unlock from '../../common/script/ops/unlock';
|
||||||
|
import buy from '../../common/script/ops/buy/buy';
|
||||||
import guide from 'client/mixins/guide';
|
import guide from 'client/mixins/guide';
|
||||||
import notifications from 'client/mixins/notifications';
|
import notifications from 'client/mixins/notifications';
|
||||||
import appearance from 'common/script/content/appearance';
|
import appearance from 'common/script/content/appearance';
|
||||||
@@ -865,6 +881,7 @@ import skinIcon from 'assets/svg/skin.svg';
|
|||||||
import hairIcon from 'assets/svg/hair.svg';
|
import hairIcon from 'assets/svg/hair.svg';
|
||||||
import backgroundsIcon from 'assets/svg/backgrounds.svg';
|
import backgroundsIcon from 'assets/svg/backgrounds.svg';
|
||||||
import gem from 'assets/svg/gem.svg';
|
import gem from 'assets/svg/gem.svg';
|
||||||
|
import gold from 'assets/svg/gold.svg';
|
||||||
import pin from 'assets/svg/pin.svg';
|
import pin from 'assets/svg/pin.svg';
|
||||||
import isPinned from 'common/script/libs/isPinned';
|
import isPinned from 'common/script/libs/isPinned';
|
||||||
|
|
||||||
@@ -1042,6 +1059,7 @@ export default {
|
|||||||
backgroundsIcon,
|
backgroundsIcon,
|
||||||
gem,
|
gem,
|
||||||
pin,
|
pin,
|
||||||
|
gold,
|
||||||
}),
|
}),
|
||||||
modalPage: 1,
|
modalPage: 1,
|
||||||
activeTopPage: 'body',
|
activeTopPage: 'body',
|
||||||
@@ -1505,6 +1523,24 @@ export default {
|
|||||||
alert(e.message);
|
alert(e.message);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
async buy (item) {
|
||||||
|
const options = {
|
||||||
|
currency: 'gold',
|
||||||
|
key: item,
|
||||||
|
type: 'marketGear',
|
||||||
|
quantity: 1,
|
||||||
|
pinType: 'marketGear',
|
||||||
|
};
|
||||||
|
await axios.post(`/api/v4/user/buy/${item}`, options);
|
||||||
|
try {
|
||||||
|
buy(this.user, {
|
||||||
|
params: options,
|
||||||
|
});
|
||||||
|
this.backgroundUpdate = new Date();
|
||||||
|
} catch (e) {
|
||||||
|
alert(e.message);
|
||||||
|
}
|
||||||
|
},
|
||||||
setKeys (type, _set) {
|
setKeys (type, _set) {
|
||||||
return map(_set, (v, k) => {
|
return map(_set, (v, k) => {
|
||||||
if (type === 'background') k = v.key;
|
if (type === 'background') k = v.key;
|
||||||
@@ -1543,7 +1579,7 @@ export default {
|
|||||||
|
|
||||||
let own = true;
|
let own = true;
|
||||||
this.animalItemKeys[category].forEach(key => {
|
this.animalItemKeys[category].forEach(key => {
|
||||||
if (!this.user.items.gear.owned[`${category}_special_${key}`]) own = false;
|
if (this.user.items.gear.owned[`${category}_special_${key}`] === undefined) own = false;
|
||||||
});
|
});
|
||||||
return own;
|
return own;
|
||||||
},
|
},
|
||||||
@@ -1554,15 +1590,22 @@ export default {
|
|||||||
let options = keys.map(key => {
|
let options = keys.map(key => {
|
||||||
let newKey = `${category}_special_${key}`;
|
let newKey = `${category}_special_${key}`;
|
||||||
let userPurchased = this.user.items.gear.owned[newKey];
|
let userPurchased = this.user.items.gear.owned[newKey];
|
||||||
let locked = !userPurchased;
|
|
||||||
|
|
||||||
let option = {};
|
let option = {};
|
||||||
option.key = key;
|
option.key = key;
|
||||||
option.active = this.user.preferences.costume ? this.user.items.gear.costume[category] === newKey : this.user.items.gear.equipped[category] === newKey;
|
option.active = this.user.preferences.costume ? this.user.items.gear.costume[category] === newKey : this.user.items.gear.equipped[category] === newKey;
|
||||||
option.locked = locked;
|
option.gemLocked = userPurchased === undefined;
|
||||||
|
option.goldLocked = userPurchased === false;
|
||||||
|
option.locked = option.gemLocked || option.goldLocked;
|
||||||
option.click = () => {
|
option.click = () => {
|
||||||
|
if (option.gemLocked) {
|
||||||
|
return this.unlock(`items.gear.owned.${newKey}`);
|
||||||
|
} else if (option.goldLocked) {
|
||||||
|
return this.buy(newKey);
|
||||||
|
} else {
|
||||||
let type = this.user.preferences.costume ? 'costume' : 'equipped';
|
let type = this.user.preferences.costume ? 'costume' : 'equipped';
|
||||||
return locked ? this.unlock(`items.gear.owned.${newKey}`) : this.equip(newKey, type);
|
return this.equip(newKey, type);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
return option;
|
return option;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -73,6 +73,8 @@ module.exports = function unlock (user, req = {}, analytics) {
|
|||||||
if (path.indexOf('gear.') !== -1) {
|
if (path.indexOf('gear.') !== -1) {
|
||||||
// Using Object so path[1] won't create an array but an object {path: {1: value}}
|
// Using Object so path[1] won't create an array but an object {path: {1: value}}
|
||||||
setWith(user, pathPart, true, Object);
|
setWith(user, pathPart, true, Object);
|
||||||
|
let itemName = pathPart.split('.').pop();
|
||||||
|
removeItemByPath(user, `gear.flat.${itemName}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Using Object so path[1] won't create an array but an object {path: {1: value}}
|
// Using Object so path[1] won't create an array but an object {path: {1: value}}
|
||||||
|
|||||||
Reference in New Issue
Block a user