Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 061457b268 | |||
| e7ec9a6d65 | |||
| d1396e7bc6 | |||
| d5cedaa925 | |||
| b31268fbc2 | |||
| 35727228f0 | |||
| f4422b8d6c | |||
| 2d4dc9e23c | |||
| c39505d41c | |||
| c24545cae5 | |||
| 6bc70ca471 | |||
| b445bc8261 | |||
| 31281b43d3 | |||
| a8a915ea8e | |||
| dc3ee25e65 | |||
| 54f57445da | |||
| 95ef2b1789 | |||
| 4d32977e5c | |||
| 7fe2504906 | |||
| b74cee3d21 | |||
| 5af7733150 | |||
| 824bf62e0a | |||
| ac24a5dddd | |||
| 9111f59da4 |
@@ -1,5 +1,16 @@
|
||||
FROM node:boron
|
||||
|
||||
ENV ADMIN_EMAIL admin@habitica.com
|
||||
ENV AMAZON_PAYMENTS_CLIENT_ID amzn1.application-oa2-client.68ed9e6904ef438fbc1bf86bf494056e
|
||||
ENV AMAZON_PAYMENTS_SELLER_ID AMQ3SB4SG5E91
|
||||
ENV AMPLITUDE_KEY e8d4c24b3d6ef3ee73eeba715023dd43
|
||||
ENV BASE_URL https://habitica.com
|
||||
ENV FACEBOOK_KEY 128307497299777
|
||||
ENV GA_ID UA-33510635-1
|
||||
ENV GOOGLE_CLIENT_ID 1035232791481-32vtplgnjnd1aufv3mcu1lthf31795fq.apps.googleusercontent.com
|
||||
ENV NODE_ENV production
|
||||
ENV STRIPE_PUB_KEY pk_85fQ0yMECHNfHTSsZoxZXlPSwSNfA
|
||||
|
||||
# Upgrade NPM to v5 (Yarn is needed because of this bug https://github.com/npm/npm/issues/16807)
|
||||
# The used solution is suggested here https://github.com/npm/npm/issues/16807#issuecomment-313591975
|
||||
RUN yarn global add npm@5
|
||||
@@ -9,7 +20,7 @@ RUN npm install -g gulp mocha
|
||||
# Clone Habitica repo and install dependencies
|
||||
RUN mkdir -p /usr/src/habitrpg
|
||||
WORKDIR /usr/src/habitrpg
|
||||
RUN git clone --branch v4.0.3 https://github.com/HabitRPG/habitica.git /usr/src/habitrpg
|
||||
RUN git clone --branch v4.6.3 https://github.com/HabitRPG/habitica.git /usr/src/habitrpg
|
||||
RUN npm install
|
||||
RUN gulp build:prod --force
|
||||
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
var migrationName = '20171030_jackolanterns.js';
|
||||
var authorName = 'Sabe'; // in case script author needs to know when their ...
|
||||
var authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; //... own data is done
|
||||
|
||||
/*
|
||||
* Award the Jack-O'-Lantern ladder:
|
||||
* Ghost Jack-O-Lantern Mount to owners of Ghost Jack-O-Lantern Pet
|
||||
* Ghost Jack-O-Lantern Pet to owners of Jack-O-Lantern Mount
|
||||
* Jack-O-Lantern Mount to owners of Jack-O-Lantern Pet
|
||||
* Jack-O-Lantern Pet to everyone else
|
||||
*/
|
||||
|
||||
var monk = require('monk');
|
||||
var connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
|
||||
var dbUsers = monk(connectionString).get('users', { castIds: false });
|
||||
|
||||
function processUsers(lastId) {
|
||||
// specify a query to limit the affected users (empty for all users):
|
||||
var query = {
|
||||
'migration':{$ne:migrationName},
|
||||
};
|
||||
|
||||
if (lastId) {
|
||||
query._id = {
|
||||
$gt: lastId
|
||||
}
|
||||
}
|
||||
|
||||
dbUsers.find(query, {
|
||||
sort: {_id: 1},
|
||||
limit: 250,
|
||||
fields: [
|
||||
'items.pets',
|
||||
'items.mounts',
|
||||
] // specify fields we are interested in to limit retrieved data (empty if we're not reading data):
|
||||
})
|
||||
.then(updateUsers)
|
||||
.catch(function (err) {
|
||||
console.log(err);
|
||||
return exiting(1, 'ERROR! ' + err);
|
||||
});
|
||||
}
|
||||
|
||||
var progressCount = 1000;
|
||||
var count = 0;
|
||||
|
||||
function updateUsers (users) {
|
||||
if (!users || users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
displayData();
|
||||
return;
|
||||
}
|
||||
|
||||
var userPromises = users.map(updateUser);
|
||||
var lastUser = users[users.length - 1];
|
||||
|
||||
return Promise.all(userPromises)
|
||||
.then(function () {
|
||||
processUsers(lastUser._id);
|
||||
});
|
||||
}
|
||||
|
||||
function updateUser (user) {
|
||||
count++;
|
||||
|
||||
var set = {};
|
||||
var inc = {
|
||||
'items.food.Candy_Skeleton': 1,
|
||||
'items.food.Candy_Base': 1,
|
||||
'items.food.Candy_CottonCandyBlue': 1,
|
||||
'items.food.Candy_CottonCandyPink': 1,
|
||||
'items.food.Candy_Shade': 1,
|
||||
'items.food.Candy_White': 1,
|
||||
'items.food.Candy_Golden': 1,
|
||||
'items.food.Candy_Zombie': 1,
|
||||
'items.food.Candy_Desert': 1,
|
||||
'items.food.Candy_Red': 1,
|
||||
};
|
||||
|
||||
if (user && user.items && user.items.pets && user.items.pets['JackOLantern-Ghost']) {
|
||||
set = {'migration':migrationName, 'items.mounts.JackOLantern-Ghost': true};
|
||||
} else if (user && user.items && user.items.mounts && user.items.mounts['JackOLantern-Base']) {
|
||||
set = {'migration':migrationName, 'items.pets.JackOLantern-Ghost': 5};
|
||||
} else if (user && user.items && user.items.pets && user.items.pets['JackOLantern-Base']) {
|
||||
set = {'migration':migrationName, 'items.mounts.JackOLantern-Base': true};
|
||||
} else {
|
||||
set = {'migration':migrationName, 'items.pets.JackOLantern-Base': 5};
|
||||
}
|
||||
|
||||
dbUsers.update({_id: user._id}, {$set:set, $inc:inc});
|
||||
|
||||
if (count % progressCount == 0) console.warn(count + ' ' + user._id);
|
||||
if (user._id == authorUuid) console.warn(authorName + ' processed');
|
||||
}
|
||||
|
||||
function displayData() {
|
||||
console.warn('\n' + count + ' users processed\n');
|
||||
return exiting(0);
|
||||
}
|
||||
|
||||
function exiting(code, msg) {
|
||||
code = code || 0; // 0 = success
|
||||
if (code && !msg) { msg = 'ERROR!'; }
|
||||
if (msg) {
|
||||
if (code) { console.error(msg); }
|
||||
else { console.log( msg); }
|
||||
}
|
||||
process.exit(code);
|
||||
}
|
||||
|
||||
module.exports = processUsers;
|
||||
@@ -2,7 +2,7 @@ var _id = '';
|
||||
var update = {
|
||||
$addToSet: {
|
||||
'purchased.plan.mysteryItems':{
|
||||
$each:['shield_mystery_201709','back_mystery_201709']
|
||||
$each:['armor_mystery_201710','head_mystery_201710']
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "habitica",
|
||||
"description": "A habit tracker app which treats your goals like a Role Playing Game.",
|
||||
"version": "4.4.5",
|
||||
"version": "4.7.0",
|
||||
"main": "./website/server/index.js",
|
||||
"dependencies": {
|
||||
"@slack/client": "^3.8.1",
|
||||
|
||||
@@ -98,4 +98,24 @@ describe('POST /user/purchase/:type/:key', () => {
|
||||
await members[0].sync();
|
||||
expect(members[0].balance).to.equal(oldBalance);
|
||||
});
|
||||
|
||||
describe('bulk purchasing', () => {
|
||||
it('purchases a gem item', async () => {
|
||||
await user.post(`/user/purchase/${type}/${key}`, {quantity: 2});
|
||||
await user.sync();
|
||||
|
||||
expect(user.items[type][key]).to.equal(2);
|
||||
});
|
||||
|
||||
it('can convert gold to gems if subscribed', async () => {
|
||||
let oldBalance = user.balance;
|
||||
await user.update({
|
||||
'purchased.plan.customerId': 'group-plan',
|
||||
'stats.gp': 1000,
|
||||
});
|
||||
await user.post('/user/purchase/gems/gem', {quantity: 2});
|
||||
await user.sync();
|
||||
expect(user.balance).to.equal(oldBalance + 0.50);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
import {
|
||||
generateUser,
|
||||
translate as t,
|
||||
} from '../../../../helpers/api-integration/v3';
|
||||
import shared from '../../../../../website/common/script';
|
||||
} from '../../../../../helpers/api-integration/v3';
|
||||
import shared from '../../../../../../website/common/script';
|
||||
|
||||
let content = shared.content;
|
||||
|
||||
@@ -82,4 +82,19 @@ describe('POST /user/buy/:key', () => {
|
||||
itemText: item.text(),
|
||||
}));
|
||||
});
|
||||
|
||||
it('allows for bulk purchases', async () => {
|
||||
await user.update({
|
||||
'stats.gp': 400,
|
||||
'stats.hp': 20,
|
||||
});
|
||||
|
||||
let potion = content.potion;
|
||||
let res = await user.post('/user/buy/potion', {quantity: 2});
|
||||
await user.sync();
|
||||
|
||||
expect(user.stats.hp).to.equal(50);
|
||||
expect(res.data).to.eql(user.stats);
|
||||
expect(res.message).to.equal(t('messageBought', {itemText: potion.text()}));
|
||||
});
|
||||
});
|
||||
@@ -1,7 +1,7 @@
|
||||
import {
|
||||
generateUser,
|
||||
translate as t,
|
||||
} from '../../../../helpers/api-integration/v3';
|
||||
} from '../../../../../helpers/api-integration/v3';
|
||||
|
||||
describe('POST /user/buy-armoire', () => {
|
||||
let user;
|
||||
@@ -3,7 +3,7 @@
|
||||
import {
|
||||
generateUser,
|
||||
translate as t,
|
||||
} from '../../../../helpers/api-integration/v3';
|
||||
} from '../../../../../helpers/api-integration/v3';
|
||||
|
||||
describe('POST /user/buy-gear/:key', () => {
|
||||
let user;
|
||||
@@ -1,8 +1,8 @@
|
||||
import {
|
||||
generateUser,
|
||||
translate as t,
|
||||
} from '../../../../helpers/api-integration/v3';
|
||||
import shared from '../../../../../website/common/script';
|
||||
} from '../../../../../helpers/api-integration/v3';
|
||||
import shared from '../../../../../../website/common/script';
|
||||
|
||||
let content = shared.content;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {
|
||||
generateUser,
|
||||
translate as t,
|
||||
} from '../../../../helpers/api-integration/v3';
|
||||
} from '../../../../../helpers/api-integration/v3';
|
||||
|
||||
describe('POST /user/buy-mystery-set/:key', () => {
|
||||
let user;
|
||||
@@ -1,8 +1,8 @@
|
||||
import {
|
||||
generateUser,
|
||||
translate as t,
|
||||
} from '../../../../helpers/api-integration/v3';
|
||||
import shared from '../../../../../website/common/script';
|
||||
} from '../../../../../helpers/api-integration/v3';
|
||||
import shared from '../../../../../../website/common/script';
|
||||
|
||||
let content = shared.content;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import {
|
||||
generateUser,
|
||||
translate as t,
|
||||
} from '../../../../helpers/api-integration/v3';
|
||||
import shared from '../../../../../website/common/script';
|
||||
} from '../../../../../helpers/api-integration/v3';
|
||||
import shared from '../../../../../../website/common/script';
|
||||
|
||||
let content = shared.content;
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
generateNext,
|
||||
} from '../../../../helpers/api-unit.helper';
|
||||
import responseMiddleware from '../../../../../website/server/middlewares/response';
|
||||
import packageInfo from '../../../../../package.json';
|
||||
|
||||
describe('response middleware', () => {
|
||||
let res, req, next;
|
||||
@@ -34,6 +35,7 @@ describe('response middleware', () => {
|
||||
data: {field: 1},
|
||||
notifications: [],
|
||||
userV: res.locals.user._v,
|
||||
appVersion: packageInfo.version,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -51,6 +53,7 @@ describe('response middleware', () => {
|
||||
message: 'hello',
|
||||
notifications: [],
|
||||
userV: res.locals.user._v,
|
||||
appVersion: packageInfo.version,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -67,6 +70,7 @@ describe('response middleware', () => {
|
||||
data: {field: 1},
|
||||
notifications: [],
|
||||
userV: res.locals.user._v,
|
||||
appVersion: packageInfo.version,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -81,6 +85,7 @@ describe('response middleware', () => {
|
||||
data: {field: 1},
|
||||
notifications: [],
|
||||
userV: 0,
|
||||
appVersion: packageInfo.version,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -104,6 +109,7 @@ describe('response middleware', () => {
|
||||
},
|
||||
],
|
||||
userV: res.locals.user._v,
|
||||
appVersion: packageInfo.version,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
/* eslint-disable camelcase */
|
||||
import {
|
||||
generateUser,
|
||||
} from '../../helpers/common.helper';
|
||||
import buy from '../../../website/common/script/ops/buy';
|
||||
import {
|
||||
BadRequest,
|
||||
} from '../../../website/common/script/libs/errors';
|
||||
import i18n from '../../../website/common/script/i18n';
|
||||
|
||||
describe('shared.ops.buy', () => {
|
||||
let user;
|
||||
|
||||
beforeEach(() => {
|
||||
user = generateUser({
|
||||
items: {
|
||||
gear: {
|
||||
owned: {
|
||||
weapon_warrior_0: true,
|
||||
},
|
||||
equipped: {
|
||||
weapon_warrior_0: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
stats: { gp: 200 },
|
||||
});
|
||||
});
|
||||
|
||||
it('returns error when key is not provided', (done) => {
|
||||
try {
|
||||
buy(user);
|
||||
} catch (err) {
|
||||
expect(err).to.be.an.instanceof(BadRequest);
|
||||
expect(err.message).to.equal(i18n.t('missingKeyParam'));
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
it('recovers 15 hp', () => {
|
||||
user.stats.hp = 30;
|
||||
buy(user, {params: {key: 'potion'}});
|
||||
expect(user.stats.hp).to.eql(45);
|
||||
});
|
||||
|
||||
it('adds equipment to inventory', () => {
|
||||
user.stats.gp = 31;
|
||||
buy(user, {params: {key: 'armor_warrior_1'}});
|
||||
expect(user.items.gear.owned).to.eql({
|
||||
weapon_warrior_0: true,
|
||||
armor_warrior_1: true,
|
||||
eyewear_special_blackTopFrame: true,
|
||||
eyewear_special_blueTopFrame: true,
|
||||
eyewear_special_greenTopFrame: true,
|
||||
eyewear_special_pinkTopFrame: true,
|
||||
eyewear_special_redTopFrame: true,
|
||||
eyewear_special_whiteTopFrame: true,
|
||||
eyewear_special_yellowTopFrame: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,124 @@
|
||||
/* eslint-disable camelcase */
|
||||
import {
|
||||
generateUser,
|
||||
} from '../../../helpers/common.helper';
|
||||
import buy from '../../../../website/common/script/ops/buy';
|
||||
import {
|
||||
BadRequest,
|
||||
} from '../../../../website/common/script/libs/errors';
|
||||
import i18n from '../../../../website/common/script/i18n';
|
||||
import content from '../../../../website/common/script/content/index';
|
||||
|
||||
describe('shared.ops.buy', () => {
|
||||
let user;
|
||||
|
||||
beforeEach(() => {
|
||||
user = generateUser({
|
||||
items: {
|
||||
gear: {
|
||||
owned: {
|
||||
weapon_warrior_0: true,
|
||||
},
|
||||
equipped: {
|
||||
weapon_warrior_0: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
stats: { gp: 200 },
|
||||
});
|
||||
});
|
||||
|
||||
it('returns error when key is not provided', (done) => {
|
||||
try {
|
||||
buy(user);
|
||||
} catch (err) {
|
||||
expect(err).to.be.an.instanceof(BadRequest);
|
||||
expect(err.message).to.equal(i18n.t('missingKeyParam'));
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
it('recovers 15 hp', () => {
|
||||
user.stats.hp = 30;
|
||||
buy(user, {params: {key: 'potion'}});
|
||||
expect(user.stats.hp).to.eql(45);
|
||||
});
|
||||
|
||||
it('adds equipment to inventory', () => {
|
||||
user.stats.gp = 31;
|
||||
|
||||
buy(user, {params: {key: 'armor_warrior_1'}});
|
||||
|
||||
expect(user.items.gear.owned).to.eql({
|
||||
weapon_warrior_0: true,
|
||||
armor_warrior_1: true,
|
||||
eyewear_special_blackTopFrame: true,
|
||||
eyewear_special_blueTopFrame: true,
|
||||
eyewear_special_greenTopFrame: true,
|
||||
eyewear_special_pinkTopFrame: true,
|
||||
eyewear_special_redTopFrame: true,
|
||||
eyewear_special_whiteTopFrame: true,
|
||||
eyewear_special_yellowTopFrame: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('buys Steampunk Accessories Set', () => {
|
||||
user.purchased.plan.consecutive.trinkets = 1;
|
||||
|
||||
buy(user, {
|
||||
params: {
|
||||
key: '301404',
|
||||
},
|
||||
type: 'mystery',
|
||||
});
|
||||
|
||||
expect(user.purchased.plan.consecutive.trinkets).to.eql(0);
|
||||
expect(user.items.gear.owned).to.have.property('weapon_warrior_0', true);
|
||||
expect(user.items.gear.owned).to.have.property('weapon_mystery_301404', true);
|
||||
expect(user.items.gear.owned).to.have.property('armor_mystery_301404', true);
|
||||
expect(user.items.gear.owned).to.have.property('head_mystery_301404', true);
|
||||
expect(user.items.gear.owned).to.have.property('eyewear_mystery_301404', true);
|
||||
});
|
||||
|
||||
it('buys a Quest scroll', () => {
|
||||
user.stats.gp = 205;
|
||||
|
||||
buy(user, {
|
||||
params: {
|
||||
key: 'dilatoryDistress1',
|
||||
},
|
||||
type: 'quest',
|
||||
});
|
||||
|
||||
expect(user.items.quests).to.eql({dilatoryDistress1: 1});
|
||||
expect(user.stats.gp).to.equal(5);
|
||||
});
|
||||
|
||||
it('buys a special item', () => {
|
||||
user.stats.gp = 11;
|
||||
let item = content.special.thankyou;
|
||||
|
||||
let [data, message] = buy(user, {
|
||||
params: {
|
||||
key: 'thankyou',
|
||||
},
|
||||
type: 'special',
|
||||
});
|
||||
|
||||
expect(user.stats.gp).to.equal(1);
|
||||
expect(user.items.special.thankyou).to.equal(1);
|
||||
expect(data).to.eql({
|
||||
items: user.items,
|
||||
stats: user.stats,
|
||||
});
|
||||
expect(message).to.equal(i18n.t('messageBought', {
|
||||
itemText: item.text(),
|
||||
}));
|
||||
});
|
||||
|
||||
it('allows for bulk purchases', () => {
|
||||
user.stats.hp = 30;
|
||||
buy(user, {params: {key: 'potion'}, quantity: 2});
|
||||
expect(user.stats.hp).to.eql(50);
|
||||
});
|
||||
});
|
||||
@@ -2,15 +2,15 @@
|
||||
|
||||
import {
|
||||
generateUser,
|
||||
} from '../../helpers/common.helper';
|
||||
import count from '../../../website/common/script/count';
|
||||
import buyArmoire from '../../../website/common/script/ops/buyArmoire';
|
||||
import randomVal from '../../../website/common/script/libs/randomVal';
|
||||
import content from '../../../website/common/script/content/index';
|
||||
} from '../../../helpers/common.helper';
|
||||
import count from '../../../../website/common/script/count';
|
||||
import buyArmoire from '../../../../website/common/script/ops/buyArmoire';
|
||||
import randomVal from '../../../../website/common/script/libs/randomVal';
|
||||
import content from '../../../../website/common/script/content/index';
|
||||
import {
|
||||
NotAuthorized,
|
||||
} from '../../../website/common/script/libs/errors';
|
||||
import i18n from '../../../website/common/script/i18n';
|
||||
} from '../../../../website/common/script/libs/errors';
|
||||
import i18n from '../../../../website/common/script/i18n';
|
||||
|
||||
function getFullArmoire () {
|
||||
let fullArmoire = {};
|
||||
@@ -3,13 +3,13 @@
|
||||
import sinon from 'sinon'; // eslint-disable-line no-shadow
|
||||
import {
|
||||
generateUser,
|
||||
} from '../../helpers/common.helper';
|
||||
import buyGear from '../../../website/common/script/ops/buyGear';
|
||||
import shared from '../../../website/common/script';
|
||||
} from '../../../helpers/common.helper';
|
||||
import buyGear from '../../../../website/common/script/ops/buyGear';
|
||||
import shared from '../../../../website/common/script';
|
||||
import {
|
||||
NotAuthorized,
|
||||
} from '../../../website/common/script/libs/errors';
|
||||
import i18n from '../../../website/common/script/i18n';
|
||||
} from '../../../../website/common/script/libs/errors';
|
||||
import i18n from '../../../../website/common/script/i18n';
|
||||
|
||||
describe('shared.ops.buyGear', () => {
|
||||
let user;
|
||||
@@ -1,12 +1,12 @@
|
||||
/* eslint-disable camelcase */
|
||||
import {
|
||||
generateUser,
|
||||
} from '../../helpers/common.helper';
|
||||
import buyHealthPotion from '../../../website/common/script/ops/buyHealthPotion';
|
||||
} from '../../../helpers/common.helper';
|
||||
import buyHealthPotion from '../../../../website/common/script/ops/buyHealthPotion';
|
||||
import {
|
||||
NotAuthorized,
|
||||
} from '../../../website/common/script/libs/errors';
|
||||
import i18n from '../../../website/common/script/i18n';
|
||||
} from '../../../../website/common/script/libs/errors';
|
||||
import i18n from '../../../../website/common/script/i18n';
|
||||
|
||||
describe('shared.ops.buyHealthPotion', () => {
|
||||
let user;
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
import {
|
||||
generateUser,
|
||||
} from '../../helpers/common.helper';
|
||||
import buyMysterySet from '../../../website/common/script/ops/buyMysterySet';
|
||||
} from '../../../helpers/common.helper';
|
||||
import buyMysterySet from '../../../../website/common/script/ops/buyMysterySet';
|
||||
import {
|
||||
NotAuthorized,
|
||||
NotFound,
|
||||
} from '../../../website/common/script/libs/errors';
|
||||
import i18n from '../../../website/common/script/i18n';
|
||||
} from '../../../../website/common/script/libs/errors';
|
||||
import i18n from '../../../../website/common/script/i18n';
|
||||
|
||||
describe('shared.ops.buyMysterySet', () => {
|
||||
let user;
|
||||
@@ -1,12 +1,12 @@
|
||||
import {
|
||||
generateUser,
|
||||
} from '../../helpers/common.helper';
|
||||
import buyQuest from '../../../website/common/script/ops/buyQuest';
|
||||
} from '../../../helpers/common.helper';
|
||||
import buyQuest from '../../../../website/common/script/ops/buyQuest';
|
||||
import {
|
||||
NotAuthorized,
|
||||
NotFound,
|
||||
} from '../../../website/common/script/libs/errors';
|
||||
import i18n from '../../../website/common/script/i18n';
|
||||
} from '../../../../website/common/script/libs/errors';
|
||||
import i18n from '../../../../website/common/script/i18n';
|
||||
|
||||
describe('shared.ops.buyQuest', () => {
|
||||
let user;
|
||||
@@ -1,14 +1,14 @@
|
||||
import buySpecialSpell from '../../../website/common/script/ops/buySpecialSpell';
|
||||
import buySpecialSpell from '../../../../website/common/script/ops/buySpecialSpell';
|
||||
import {
|
||||
BadRequest,
|
||||
NotFound,
|
||||
NotAuthorized,
|
||||
} from '../../../website/common/script/libs/errors';
|
||||
import i18n from '../../../website/common/script/i18n';
|
||||
} from '../../../../website/common/script/libs/errors';
|
||||
import i18n from '../../../../website/common/script/i18n';
|
||||
import {
|
||||
generateUser,
|
||||
} from '../../helpers/common.helper';
|
||||
import content from '../../../website/common/script/content/index';
|
||||
} from '../../../helpers/common.helper';
|
||||
import content from '../../../../website/common/script/content/index';
|
||||
|
||||
describe('shared.ops.buySpecialSpell', () => {
|
||||
let user;
|
||||
@@ -138,6 +138,7 @@ describe('shared.ops.purchase', () => {
|
||||
user.balance = userGemAmount;
|
||||
user.stats.gp = goldPoints;
|
||||
user.purchased.plan.gemsBought = 0;
|
||||
user.purchased.plan.customerId = 'customer-id';
|
||||
});
|
||||
|
||||
it('purchases gems', () => {
|
||||
@@ -226,4 +227,39 @@ describe('shared.ops.purchase', () => {
|
||||
clock.restore();
|
||||
});
|
||||
});
|
||||
|
||||
context('bulk purchase', () => {
|
||||
let userGemAmount = 10;
|
||||
|
||||
before(() => {
|
||||
user.balance = userGemAmount;
|
||||
user.stats.gp = goldPoints;
|
||||
user.purchased.plan.gemsBought = 0;
|
||||
user.purchased.plan.customerId = 'customer-id';
|
||||
});
|
||||
|
||||
it('makes bulk purchases of gems', () => {
|
||||
let [, message] = purchase(user, {
|
||||
params: {type: 'gems', key: 'gem'},
|
||||
quantity: 2,
|
||||
});
|
||||
|
||||
expect(message).to.equal(i18n.t('plusOneGem'));
|
||||
expect(user.balance).to.equal(userGemAmount + 0.50);
|
||||
expect(user.purchased.plan.gemsBought).to.equal(2);
|
||||
expect(user.stats.gp).to.equal(goldPoints - planGemLimits.convRate * 2);
|
||||
});
|
||||
|
||||
it('makes bulk purchases of eggs', () => {
|
||||
let type = 'eggs';
|
||||
let key = 'TigerCub';
|
||||
|
||||
purchase(user, {
|
||||
params: {type, key},
|
||||
quantity: 2,
|
||||
});
|
||||
|
||||
expect(user.items[type][key]).to.equal(2);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -191,6 +191,7 @@ export default {
|
||||
|
||||
const isApiCall = url.indexOf('api/v3') !== -1;
|
||||
const userV = response.data && response.data.userV;
|
||||
const isCron = url.indexOf('/api/v3/cron') === 0 && method === 'post';
|
||||
|
||||
if (this.isUserLoaded && isApiCall && userV) {
|
||||
const oldUserV = this.user._v;
|
||||
@@ -202,7 +203,6 @@ export default {
|
||||
// exclude chat seen requests because with real time chat they would be too many
|
||||
const isChatSeen = url.indexOf('/chat/seen') !== -1 && method === 'post';
|
||||
// exclude POST /api/v3/cron because the user is synced automatically after cron runs
|
||||
const isCron = url.indexOf('/api/v3/cron') === 0 && method === 'post';
|
||||
|
||||
// Something has changed on the user object that was not tracked here, sync the user
|
||||
if (userV - oldUserV > 1 && !isCron && !isChatSeen && !isUserSync && !isTasksSync) {
|
||||
@@ -213,6 +213,17 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
// Verify the client is updated
|
||||
// const serverAppVersion = response.data.appVersion;
|
||||
// let serverAppVersionState = this.$store.state.serverAppVersion;
|
||||
// if (isApiCall && !serverAppVersionState) {
|
||||
// this.$store.state.serverAppVersion = serverAppVersion;
|
||||
// } else if (isApiCall && serverAppVersionState !== serverAppVersion) {
|
||||
// if (document.activeElement.tagName !== 'INPUT' || confirm(this.$t('habiticaHasUpdated'))) {
|
||||
// location.reload(true);
|
||||
// }
|
||||
// }
|
||||
|
||||
return response;
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.scene_positivity {
|
||||
.promo_jackolanterns {
|
||||
background-image: url(/static/sprites/spritesmith-largeSprites-0.png);
|
||||
background-position: 0px 0px;
|
||||
width: 531px;
|
||||
height: 243px;
|
||||
width: 140px;
|
||||
height: 441px;
|
||||
}
|
||||
|
||||
@@ -1,150 +1,246 @@
|
||||
.Pet-Wolf-White {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: 0px 0px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Zombie {
|
||||
.Pet-Wolf-Desert {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: -82px 0px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet_HatchingPotion_Aquatic {
|
||||
.Pet-Wolf-Ember {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: -164px -300px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Fairy {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: -82px -200px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Floral {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: -164px 0px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Ghost {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: 0px -100px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Golden {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: -82px -100px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Holly {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: -164px -100px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Peppermint {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: -246px 0px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Red {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: -246px -100px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-RoyalPurple {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: 0px -200px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Shade {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: 0px 0px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Shimmer {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: -164px -200px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Skeleton {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: -246px -200px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Spooky {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: -328px 0px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Thunderstorm {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: -328px -100px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Veteran {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: -328px -200px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-White {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: 0px -300px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Zombie {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: -82px -300px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet_HatchingPotion_Aquatic {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: -246px -300px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Base {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: 0px -100px;
|
||||
background-position: -315px -300px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_CottonCandyBlue {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: -69px -100px;
|
||||
background-position: -207px -469px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_CottonCandyPink {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: -138px -100px;
|
||||
background-position: -410px -69px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Cupid {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: -233px 0px;
|
||||
background-position: -410px -138px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Desert {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: -233px -69px;
|
||||
background-position: -410px -207px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Ember {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: 0px -169px;
|
||||
background-position: -410px -276px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Fairy {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: -69px -169px;
|
||||
background-position: 0px -400px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Floral {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: -138px -169px;
|
||||
background-position: -69px -400px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Ghost {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: -207px -169px;
|
||||
background-position: -138px -400px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Golden {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: 0px -307px;
|
||||
background-position: -207px -400px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Holly {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: -302px -69px;
|
||||
background-position: -276px -400px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Peppermint {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: -302px -138px;
|
||||
background-position: -345px -400px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Purple {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: 0px -238px;
|
||||
background-position: -479px 0px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Red {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: -69px -238px;
|
||||
background-position: -479px -69px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_RoyalPurple {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: -138px -238px;
|
||||
background-position: -479px -138px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Shade {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: -207px -238px;
|
||||
background-position: -479px -207px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Shimmer {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: -276px -238px;
|
||||
background-position: -479px -276px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Skeleton {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: -371px 0px;
|
||||
background-position: -479px -345px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Spooky {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: -371px -69px;
|
||||
background-position: 0px -469px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Thunderstorm {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: -371px -138px;
|
||||
background-position: -69px -469px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_White {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: -371px -207px;
|
||||
background-position: -138px -469px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Zombie {
|
||||
background-image: url(/static/sprites/spritesmith-main-20.png);
|
||||
background-position: -302px 0px;
|
||||
background-position: -410px 0px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
}
|
||||
.customize-option.skin_mergreen {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -992px -106px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -18,7 +18,7 @@
|
||||
}
|
||||
.customize-option.skin_merruby {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -389px -1013px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -30,7 +30,7 @@
|
||||
}
|
||||
.customize-option.skin_merruby_sleep {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -1026px -1104px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -42,7 +42,7 @@
|
||||
}
|
||||
.customize-option.skin_monster {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -1174px -834px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -54,7 +54,7 @@
|
||||
}
|
||||
.customize-option.skin_monster_sleep {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -1174px -561px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -66,7 +66,7 @@
|
||||
}
|
||||
.customize-option.skin_ogre {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -1356px -197px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -78,7 +78,7 @@
|
||||
}
|
||||
.customize-option.skin_ogre_sleep {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -844px -1104px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -90,7 +90,7 @@
|
||||
}
|
||||
.customize-option.skin_panda {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -207px -194px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -102,7 +102,7 @@
|
||||
}
|
||||
.customize-option.skin_panda_sleep {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -116px -194px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -114,7 +114,7 @@
|
||||
}
|
||||
.customize-option.skin_pastelBlue {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -355px -106px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -126,7 +126,7 @@
|
||||
}
|
||||
.customize-option.skin_pastelBlue_sleep {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -355px -15px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -138,7 +138,7 @@
|
||||
}
|
||||
.customize-option.skin_pastelGreen {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -116px -285px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -150,7 +150,7 @@
|
||||
}
|
||||
.customize-option.skin_pastelGreen_sleep {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -25px -285px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -162,7 +162,7 @@
|
||||
}
|
||||
.customize-option.skin_pastelOrange {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -298px -285px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -174,7 +174,7 @@
|
||||
}
|
||||
.customize-option.skin_pastelOrange_sleep {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -207px -285px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -186,7 +186,7 @@
|
||||
}
|
||||
.customize-option.skin_pastelPink {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -446px -106px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -198,7 +198,7 @@
|
||||
}
|
||||
.customize-option.skin_pastelPink_sleep {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -446px -15px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -210,7 +210,7 @@
|
||||
}
|
||||
.customize-option.skin_pastelPurple {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -25px -376px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -222,7 +222,7 @@
|
||||
}
|
||||
.customize-option.skin_pastelPurple_sleep {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -446px -197px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -234,7 +234,7 @@
|
||||
}
|
||||
.customize-option.skin_pastelRainbowChevron {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -207px -376px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -246,7 +246,7 @@
|
||||
}
|
||||
.customize-option.skin_pastelRainbowChevron_sleep {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -116px -376px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -258,7 +258,7 @@
|
||||
}
|
||||
.customize-option.skin_pastelRainbowDiagonal {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -389px -376px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -270,7 +270,7 @@
|
||||
}
|
||||
.customize-option.skin_pastelRainbowDiagonal_sleep {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -298px -376px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -282,7 +282,7 @@
|
||||
}
|
||||
.customize-option.skin_pastelYellow {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -537px -106px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -294,7 +294,7 @@
|
||||
}
|
||||
.customize-option.skin_pastelYellow_sleep {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -537px -15px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -306,7 +306,7 @@
|
||||
}
|
||||
.customize-option.skin_pig {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -537px -288px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -318,7 +318,7 @@
|
||||
}
|
||||
.customize-option.skin_pig_sleep {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -537px -197px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -330,7 +330,7 @@
|
||||
}
|
||||
.customize-option.skin_polar {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -116px -467px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -342,7 +342,7 @@
|
||||
}
|
||||
.customize-option.skin_polar_sleep {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -25px -467px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -354,7 +354,7 @@
|
||||
}
|
||||
.customize-option.skin_pumpkin {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -298px -467px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -366,7 +366,7 @@
|
||||
}
|
||||
.customize-option.skin_pumpkin2 {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -480px -467px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -378,7 +378,7 @@
|
||||
}
|
||||
.customize-option.skin_pumpkin2_sleep {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -389px -467px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -390,7 +390,7 @@
|
||||
}
|
||||
.customize-option.skin_pumpkin_sleep {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -207px -467px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -402,7 +402,7 @@
|
||||
}
|
||||
.customize-option.skin_rainbow {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -628px -106px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -414,7 +414,7 @@
|
||||
}
|
||||
.customize-option.skin_rainbow_sleep {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -628px -15px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -426,7 +426,7 @@
|
||||
}
|
||||
.customize-option.skin_reptile {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -628px -288px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -438,7 +438,7 @@
|
||||
}
|
||||
.customize-option.skin_reptile_sleep {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -628px -197px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -450,7 +450,7 @@
|
||||
}
|
||||
.customize-option.skin_shadow {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -25px -558px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -462,7 +462,7 @@
|
||||
}
|
||||
.customize-option.skin_shadow2 {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -207px -558px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -474,7 +474,7 @@
|
||||
}
|
||||
.customize-option.skin_shadow2_sleep {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -116px -558px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -486,7 +486,7 @@
|
||||
}
|
||||
.customize-option.skin_shadow_sleep {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -628px -379px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -498,7 +498,7 @@
|
||||
}
|
||||
.customize-option.skin_shark {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -389px -558px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -510,7 +510,7 @@
|
||||
}
|
||||
.customize-option.skin_shark_sleep {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -298px -558px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -522,7 +522,7 @@
|
||||
}
|
||||
.customize-option.skin_skeleton {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -571px -558px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -534,7 +534,7 @@
|
||||
}
|
||||
.customize-option.skin_skeleton2 {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -719px -106px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -546,7 +546,7 @@
|
||||
}
|
||||
.customize-option.skin_skeleton2_sleep {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -719px -15px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -558,7 +558,7 @@
|
||||
}
|
||||
.customize-option.skin_skeleton_sleep {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -480px -558px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -570,7 +570,7 @@
|
||||
}
|
||||
.customize-option.skin_snowy {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -719px -288px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -582,7 +582,7 @@
|
||||
}
|
||||
.customize-option.skin_snowy_sleep {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -719px -197px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -594,7 +594,7 @@
|
||||
}
|
||||
.customize-option.skin_sugar {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -719px -470px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -606,7 +606,7 @@
|
||||
}
|
||||
.customize-option.skin_sugar_sleep {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -719px -379px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -618,7 +618,7 @@
|
||||
}
|
||||
.customize-option.skin_tiger {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -116px -649px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -630,7 +630,7 @@
|
||||
}
|
||||
.customize-option.skin_tiger_sleep {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -25px -649px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -642,7 +642,7 @@
|
||||
}
|
||||
.customize-option.skin_transparent {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -298px -649px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -654,7 +654,7 @@
|
||||
}
|
||||
.customize-option.skin_transparent_sleep {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -207px -649px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -666,7 +666,7 @@
|
||||
}
|
||||
.customize-option.skin_tropicalwater {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -480px -649px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -678,7 +678,7 @@
|
||||
}
|
||||
.customize-option.skin_tropicalwater_sleep {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -389px -649px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -690,7 +690,7 @@
|
||||
}
|
||||
.customize-option.skin_winterstar {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -662px -649px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -702,7 +702,7 @@
|
||||
}
|
||||
.customize-option.skin_winterstar_sleep {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -571px -649px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -714,7 +714,7 @@
|
||||
}
|
||||
.customize-option.skin_wolf {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -810px -106px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -726,7 +726,7 @@
|
||||
}
|
||||
.customize-option.skin_wolf_sleep {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -810px -15px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -738,7 +738,7 @@
|
||||
}
|
||||
.customize-option.skin_zombie {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -810px -288px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -750,7 +750,7 @@
|
||||
}
|
||||
.customize-option.skin_zombie2 {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -810px -470px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -762,7 +762,7 @@
|
||||
}
|
||||
.customize-option.skin_zombie2_sleep {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -810px -379px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
@@ -774,7 +774,7 @@
|
||||
}
|
||||
.customize-option.skin_zombie_sleep {
|
||||
background-image: url(/static/sprites/spritesmith-main-5.png);
|
||||
background-position: -810px -197px;
|
||||
background-position: ;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 8.2 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 9.3 KiB |
|
After Width: | Height: | Size: 9.9 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 8.7 KiB |
@@ -1,9 +1,9 @@
|
||||
// this variables are used to determine which shop npc/backgrounds should be loaded
|
||||
// possible values are: normal, fall
|
||||
// possible values are: normal, fall, habitoween
|
||||
// more to be added on future seasons
|
||||
|
||||
$npc_market_flavor: "fall";
|
||||
$npc_quests_flavor: "fall";
|
||||
$npc_seasonal_flavor: "fall";
|
||||
$npc_market_flavor: "habitoween";
|
||||
$npc_quests_flavor: "habitoween";
|
||||
$npc_seasonal_flavor: "habitoween";
|
||||
$npc_timetravelers_flavor: "fall";
|
||||
$npc_tavern_flavor: "fall";
|
||||
$npc_tavern_flavor: "habitoween";
|
||||
|
||||
@@ -86,15 +86,12 @@ b-modal#avatar-modal(title="", :size='editing ? "lg" : "md"', :hide-header='true
|
||||
span 5
|
||||
button.btn.btn-secondary.purchase-all(@click='unlock(`skin.${set.keys.join(",skin.")}`)') {{ $t('purchaseAll') }}
|
||||
#hair.section.customize-section(v-if='activeTopPage === "hair"')
|
||||
.row.sub-menu.text-center
|
||||
.col-3.offset-1.text-center.sub-menu-item(@click='changeSubPage("color")', :class='{active: activeSubPage === "color"}')
|
||||
.row.col-12.sub-menu.text-center
|
||||
.col-3.text-center.sub-menu-item(@click='changeSubPage("color")', :class='{active: activeSubPage === "color"}')
|
||||
strong(v-once) {{$t('color')}}
|
||||
.col-4.text-center.sub-menu-item(@click='changeSubPage("bangs")', :class='{active: activeSubPage === "bangs"}')
|
||||
.col-3.text-center.sub-menu-item(@click='changeSubPage("bangs")', :class='{active: activeSubPage === "bangs"}')
|
||||
strong(v-once) {{$t('bangs')}}
|
||||
.col-3.text-center.sub-menu-item(@click='changeSubPage("ponytail")', :class='{active: activeSubPage === "ponytail"}')
|
||||
strong(v-once) {{$t('ponytail')}}
|
||||
.row.sub-menu.text-center
|
||||
.col-3.offset-3.text-center.sub-menu-item(@click='changeSubPage("style")', :class='{active: activeSubPage === "style"}', v-if='editing')
|
||||
.col-3.text-center.sub-menu-item(@click='changeSubPage("style")', :class='{active: activeSubPage === "style"}', v-if='editing')
|
||||
strong(v-once) {{$t('style')}}
|
||||
.col-3.text-center.sub-menu-item(@click='changeSubPage("facialhair")', :class='{active: activeSubPage === "facialhair"}', v-if='editing')
|
||||
strong(v-once) {{$t('facialhair')}}
|
||||
@@ -141,14 +138,6 @@ b-modal#avatar-modal(title="", :size='editing ? "lg" : "md"', :hide-header='true
|
||||
.svg-icon.gem(v-html='icons.gem')
|
||||
span 5
|
||||
button.btn.btn-secondary.purchase-all(@click='unlock(`hair.base.${baseHair4Keys.join(",hair.base.")}`)') {{ $t('purchaseAll') }}
|
||||
#bangs.row(v-if='activeSubPage === "bangs"')
|
||||
.col-12.customize-options
|
||||
.head_0.option(@click='set({"preferences.hair.bangs": 0})',
|
||||
:class="[{ active: user.preferences.hair.bangs === 0 }, 'hair_bangs_0_' + user.preferences.hair.color]")
|
||||
.option(v-for='option in ["1", "2", "3", "4"]',
|
||||
:class='{active: user.preferences.hair.bangs === option}')
|
||||
.bangs.sprite.customize-option(:class="`hair_bangs_${option}_${user.preferences.hair.color}`", @click='set({"preferences.hair.bangs": option})')
|
||||
#base-hair.row(v-if='activeSubPage === "ponytail"')
|
||||
.col-12.customize-options
|
||||
.head_0.option(@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',
|
||||
@@ -166,6 +155,13 @@ b-modal#avatar-modal(title="", :size='editing ? "lg" : "md"', :hide-header='true
|
||||
.svg-icon.gem(v-html='icons.gem')
|
||||
span 5
|
||||
button.btn.btn-secondary.purchase-all(@click='unlock(`hair.base.${baseHair2Keys.join(",hair.base.")}`)') {{ $t('purchaseAll') }}
|
||||
#bangs.row(v-if='activeSubPage === "bangs"')
|
||||
.col-12.customize-options
|
||||
.head_0.option(@click='set({"preferences.hair.bangs": 0})',
|
||||
:class="[{ active: user.preferences.hair.bangs === 0 }, 'hair_bangs_0_' + user.preferences.hair.color]")
|
||||
.option(v-for='option in ["1", "2", "3", "4"]',
|
||||
:class='{active: user.preferences.hair.bangs === option}')
|
||||
.bangs.sprite.customize-option(:class="`hair_bangs_${option}_${user.preferences.hair.color}`", @click='set({"preferences.hair.bangs": option})')
|
||||
#facialhair.row(v-if='activeSubPage === "facialhair"')
|
||||
.col-12.customize-options(v-if='editing')
|
||||
.head_0.option(@click='set({"preferences.hair.beard": 0})', :class="[{ active: user.preferences.hair.beard === 0 }, 'hair_base_0_' + user.preferences.hair.color]")
|
||||
@@ -285,7 +281,7 @@ b-modal#avatar-modal(title="", :size='editing ? "lg" : "md"', :hide-header='true
|
||||
.col-12.text-center(v-if='!ownsSet("background", set.items) && set.identifier !== "incentiveBackgrounds"')
|
||||
.gem-amount
|
||||
.svg-icon.gem(v-html='icons.gem')
|
||||
span 5
|
||||
span 15
|
||||
button.btn.btn-secondary(@click='unlock(setKeys("background", set.items))') Purchase Set
|
||||
|
||||
.container.interests-section(v-if='modalPage === 3 && !editing')
|
||||
|
||||
@@ -32,13 +32,20 @@ export default {
|
||||
user: 'user.data',
|
||||
groupPlans: 'groupPlans',
|
||||
}),
|
||||
isLeader () {
|
||||
currentGroup () {
|
||||
let groupFound = this.groupPlans.find(group => {
|
||||
return group._id === this.groupId;
|
||||
});
|
||||
|
||||
if (!groupFound) return false;
|
||||
return groupFound.leader === this.user._id;
|
||||
return groupFound;
|
||||
},
|
||||
isLeader () {
|
||||
if (!this.currentGroup) return false;
|
||||
return this.currentGroup.leader === this.user._id;
|
||||
},
|
||||
isManager () {
|
||||
if (!this.currentGroup) return false;
|
||||
return Boolean(this.currentGroup.managers[this.user._id]);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -40,11 +40,11 @@ div
|
||||
span.dropdown-icon-item
|
||||
.svg-icon.inline(v-html="icons.starIcon")
|
||||
span.text {{$t('promoteToLeader')}}
|
||||
b-dropdown-item(@click='addManager(member)', v-if='isLeader && groupIsSubscribed')
|
||||
b-dropdown-item(@click='addManager(member._id)', v-if='isLeader && groupIsSubscribed')
|
||||
span.dropdown-icon-item
|
||||
.svg-icon.inline(v-html="icons.starIcon")
|
||||
span.text {{$t('addManager')}}
|
||||
b-dropdown-item(@click='removeManager(member)', v-if='isLeader && groupIsSubscribed')
|
||||
b-dropdown-item(@click='removeManager(member._id)', v-if='isLeader && groupIsSubscribed')
|
||||
span.dropdown-icon-item
|
||||
.svg-icon.inline(v-html="icons.removeIcon")
|
||||
span.text {{$t('removeManager2')}}
|
||||
|
||||
@@ -2,14 +2,18 @@
|
||||
.row.standard-page
|
||||
.col-6
|
||||
h2 {{ $t('API') }}
|
||||
small {{ $t('APIText') }}
|
||||
p {{ $t('APIText') }}
|
||||
|
||||
.section
|
||||
h6 {{ $t('userId') }}
|
||||
pre.prettyprint {{user.id}}
|
||||
h6 {{ $t('APIToken') }}
|
||||
pre.prettyprint {{apiToken}}
|
||||
small(v-html='$t("APITokenWarning", { hrefTechAssistanceEmail })')
|
||||
.d-flex.align-items-center.mb-3
|
||||
button.btn.btn-secondary(
|
||||
@click="showApiToken = !showApiToken"
|
||||
) {{ $t(`${showApiToken ? 'hide' : 'show'}APIToken`) }}
|
||||
pre.prettyprint.ml-4.mb-0(v-if="showApiToken") {{apiToken}}
|
||||
p(v-html='$t("APITokenWarning", { hrefTechAssistanceEmail })')
|
||||
|
||||
.section
|
||||
h3 {{ $t('thirdPartyApps') }}
|
||||
@@ -78,6 +82,7 @@ export default {
|
||||
url: '',
|
||||
},
|
||||
hrefTechAssistanceEmail: `<a href="mailto:${TECH_ASSISTANCE_EMAIL}">${TECH_ASSISTANCE_EMAIL}</a>`,
|
||||
showApiToken: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
||||
@@ -23,8 +23,10 @@
|
||||
<script>
|
||||
import axios from 'axios';
|
||||
import { mapState } from 'client/libs/store';
|
||||
import notifications from 'client/mixins/notifications';
|
||||
|
||||
export default {
|
||||
mixins: [notifications],
|
||||
data () {
|
||||
return {
|
||||
codes: {
|
||||
@@ -51,10 +53,12 @@ export default {
|
||||
// })
|
||||
},
|
||||
async enterCoupon () {
|
||||
let code = await axios.get(`/api/v3/coupons/enter/${this.couponCode}`);
|
||||
let code = await axios.post(`/api/v3/coupons/enter/${this.couponCode}`);
|
||||
if (!code) return;
|
||||
// @TODO: what needs to be updated? User.sync();
|
||||
// @TODO: mixin Notification.text(env.t('promoCodeApplied'));
|
||||
|
||||
this.$store.state.user.data = code.data.data;
|
||||
|
||||
this.text(this.$t('promoCodeApplied'));
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -115,7 +115,8 @@
|
||||
div
|
||||
ul.list-inline
|
||||
li(v-for='network in SOCIAL_AUTH_NETWORKS')
|
||||
button.btn.btn-primary(v-if='!user.auth[network.key].id', @click='socialLogin(network.key, user)') {{ $t('registerWithSocial', {network: network.name}) }}
|
||||
// @TODO this is broken
|
||||
button.btn.btn-primary(v-if='!user.auth[network.key].id', @click='socialAuth(network.key, user)') {{ $t('registerWithSocial', {network: network.name}) }}
|
||||
button.btn.btn-primary(disabled='disabled', v-if='!hasBackupAuthOption(network.key) && user.auth[network.key].id') {{ $t('registeredWithSocial', {network: network.name}) }}
|
||||
button.btn.btn-danger(@click='deleteSocialAuth(network.key)', v-if='hasBackupAuthOption(network.key) && user.auth[network.key].id') {{ $t('detachSocial', {network: network.name}) }}
|
||||
hr
|
||||
@@ -377,7 +378,7 @@ export default {
|
||||
auth,
|
||||
});
|
||||
|
||||
this.$router.go('/tasks');
|
||||
window.location.href = '/';
|
||||
},
|
||||
async changeClassForUser (confirmationNeeded) {
|
||||
if (confirmationNeeded && !confirm(this.$t('changeClassConfirmCost'))) return;
|
||||
|
||||
@@ -41,25 +41,32 @@
|
||||
:item="item"
|
||||
)
|
||||
|
||||
div(:class="{'notEnough': !this.enoughCurrency(getPriceClass(), item.value)}")
|
||||
span.svg-icon.inline.icon-32(aria-hidden="true", v-html="icons[getPriceClass()]")
|
||||
span.value(:class="getPriceClass()") {{ item.value }}
|
||||
.purchase-amount(:class="{'notEnough': !this.enoughCurrency(getPriceClass(), item.value * selectedAmountToBuy)}")
|
||||
.how-many-to-buy(v-if='item.purchaseType !== "gear"')
|
||||
strong {{ $t('howManyToBuy') }}
|
||||
div(v-if='item.purchaseType !== "gear"')
|
||||
.box
|
||||
input(type='number', min='0', v-model='selectedAmountToBuy')
|
||||
span.svg-icon.inline.icon-32(aria-hidden="true", v-html="icons[getPriceClass()]")
|
||||
span.value(:class="getPriceClass()") {{ item.value }}
|
||||
|
||||
.gems-left(v-if='item.key === "gem"')
|
||||
strong(v-if='gemsLeft > 0') {{ gemsLeft }} {{ $t('gemsRemaining') }}
|
||||
strong(v-if='gemsLeft === 0') {{ $t('maxBuyGems') }}
|
||||
|
||||
div(v-if='attemptingToPurchaseMoreGemsThanAreLeft')
|
||||
| {{$t('notEnoughGemsToBuy')}}
|
||||
|
||||
button.btn.btn-primary(
|
||||
@click="purchaseGems()",
|
||||
v-if="getPriceClass() === 'gems' && !this.enoughCurrency(getPriceClass(), item.value)"
|
||||
v-if="getPriceClass() === 'gems' && !this.enoughCurrency(getPriceClass(), item.value * selectedAmountToBuy)"
|
||||
) {{ $t('purchaseGems') }}
|
||||
|
||||
button.btn.btn-primary(
|
||||
@click="buyItem()",
|
||||
v-else,
|
||||
:disabled='item.key === "gem" && gemsLeft === 0',
|
||||
:class="{'notEnough': !preventHealthPotion || !this.enoughCurrency(getPriceClass(), item.value)}"
|
||||
:disabled='item.key === "gem" && gemsLeft === 0 || attemptingToPurchaseMoreGemsThanAreLeft',
|
||||
:class="{'notEnough': !preventHealthPotion || !this.enoughCurrency(getPriceClass(), item.value * selectedAmountToBuy)}"
|
||||
) {{ $t('buyNow') }}
|
||||
|
||||
div.limitedTime(v-if="item.event")
|
||||
@@ -101,6 +108,37 @@
|
||||
width: 282px;
|
||||
}
|
||||
|
||||
.purchase-amount {
|
||||
margin-top: 24px;
|
||||
|
||||
.how-many-to-buy {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.box {
|
||||
display: inline-block;
|
||||
width: 74px;
|
||||
height: 40px;
|
||||
border-radius: 2px;
|
||||
background-color: #ffffff;
|
||||
box-shadow: 0 2px 2px 0 rgba(26, 24, 29, 0.16), 0 1px 4px 0 rgba(26, 24, 29, 0.12);
|
||||
margin-right: 24px;
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
border: none;
|
||||
}
|
||||
|
||||
input::-webkit-contacts-auto-fill-button {
|
||||
visibility: hidden;
|
||||
display: none !important;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content-text {
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 14px;
|
||||
@@ -217,6 +255,8 @@
|
||||
|
||||
<script>
|
||||
import bModal from 'bootstrap-vue/lib/components/modal';
|
||||
import bDropdown from 'bootstrap-vue/lib/components/dropdown';
|
||||
import bDropdownItem from 'bootstrap-vue/lib/components/dropdown-item';
|
||||
import * as Analytics from 'client/libs/analytics';
|
||||
import spellsMixin from 'client/mixins/spells';
|
||||
import planGemLimits from 'common/script/libs/planGemLimits';
|
||||
@@ -248,6 +288,8 @@
|
||||
mixins: [currencyMixin, notifications, spellsMixin, buyMixin],
|
||||
components: {
|
||||
bModal,
|
||||
bDropdown,
|
||||
bDropdownItem,
|
||||
BalanceInfo,
|
||||
EquipmentAttributesGrid,
|
||||
Item,
|
||||
@@ -264,6 +306,7 @@
|
||||
clock: svgClock,
|
||||
}),
|
||||
|
||||
selectedAmountToBuy: 1,
|
||||
isPinned: false,
|
||||
};
|
||||
},
|
||||
@@ -306,10 +349,15 @@
|
||||
if (!this.user.purchased.plan) return 0;
|
||||
return planGemLimits.convCap + this.user.purchased.plan.consecutive.gemCapExtra - this.user.purchased.plan.gemsBought;
|
||||
},
|
||||
attemptingToPurchaseMoreGemsThanAreLeft () {
|
||||
if (this.item && this.item.key && this.item.key === 'gem' && this.selectedAmountToBuy > this.gemsLeft) return true;
|
||||
return false;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
item: function itemChanged () {
|
||||
this.isPinned = this.item && this.item.pinned;
|
||||
this.selectedAmountToBuy = 1;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
@@ -320,7 +368,7 @@
|
||||
if (this.item.cast) {
|
||||
this.castStart(this.item);
|
||||
} else if (this.genericPurchase) {
|
||||
this.makeGenericPurchase(this.item);
|
||||
this.makeGenericPurchase(this.item, 'buyModal', this.selectedAmountToBuy);
|
||||
this.purchased(this.item.text);
|
||||
}
|
||||
|
||||
|
||||
@@ -355,7 +355,7 @@
|
||||
|
||||
}
|
||||
|
||||
.gems-left {
|
||||
.market .gems-left {
|
||||
position: absolute;
|
||||
right: -.5em;
|
||||
top: -.5em;
|
||||
@@ -739,11 +739,6 @@ export default {
|
||||
}
|
||||
},
|
||||
itemSelected (item) {
|
||||
if (item.purchaseType !== 'gear' && this.$store.state.recentlyPurchased[item.key]) {
|
||||
this.makeGenericPurchase(item);
|
||||
return;
|
||||
}
|
||||
|
||||
this.$root.$emit('buyModal::showItem', item);
|
||||
},
|
||||
featuredItemSelected (item) {
|
||||
|
||||
@@ -18,20 +18,23 @@
|
||||
div.inner-content
|
||||
questDialogContent(:item="item")
|
||||
|
||||
div
|
||||
.purchase-amount
|
||||
.how-many-to-buy
|
||||
strong {{ $t('howManyToBuy') }}
|
||||
.box
|
||||
input(type='number', min='0', v-model='selectedAmountToBuy')
|
||||
span.svg-icon.inline.icon-32(aria-hidden="true", v-html="(priceType === 'gems') ? icons.gem : icons.gold")
|
||||
span.value(:class="priceType") {{ item.value }}
|
||||
|
||||
button.btn.btn-primary(
|
||||
@click="purchaseGems()",
|
||||
v-if="priceType === 'gems' && !this.enoughCurrency(priceType, item.value)"
|
||||
v-if="priceType === 'gems' && !this.enoughCurrency(priceType, item.value * selectedAmountToBuy)"
|
||||
) {{ $t('purchaseGems') }}
|
||||
|
||||
|
||||
button.btn.btn-primary(
|
||||
@click="buyItem()",
|
||||
v-else,
|
||||
:class="{'notEnough': !this.enoughCurrency(priceType, item.value)}"
|
||||
:class="{'notEnough': !this.enoughCurrency(priceType, item.value * selectedAmountToBuy)}"
|
||||
) {{ $t('buyNow') }}
|
||||
|
||||
div.right-sidebar(v-if="item.drop")
|
||||
@@ -52,9 +55,12 @@
|
||||
#buy-quest-modal {
|
||||
@include centeredModal();
|
||||
|
||||
.modal-dialog {
|
||||
margin-top: 25em;
|
||||
}
|
||||
|
||||
.content {
|
||||
text-align: center;
|
||||
max-height: 80vh;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
@@ -167,6 +173,37 @@
|
||||
pointer-events: none;
|
||||
opacity: 0.55;
|
||||
}
|
||||
|
||||
.purchase-amount {
|
||||
margin-top: 24px;
|
||||
|
||||
.how-many-to-buy {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.box {
|
||||
display: inline-block;
|
||||
width: 74px;
|
||||
height: 40px;
|
||||
border-radius: 2px;
|
||||
background-color: #ffffff;
|
||||
box-shadow: 0 2px 2px 0 rgba(26, 24, 29, 0.16), 0 1px 4px 0 rgba(26, 24, 29, 0.12);
|
||||
margin-right: 24px;
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
border: none;
|
||||
}
|
||||
|
||||
input::-webkit-contacts-auto-fill-button {
|
||||
visibility: hidden;
|
||||
display: none !important;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -210,6 +247,7 @@
|
||||
}),
|
||||
|
||||
isPinned: false,
|
||||
selectedAmountToBuy: 1,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
@@ -238,10 +276,11 @@
|
||||
},
|
||||
methods: {
|
||||
onChange ($event) {
|
||||
this.selectedAmountToBuy = 1;
|
||||
this.$emit('change', $event);
|
||||
},
|
||||
buyItem () {
|
||||
this.makeGenericPurchase(this.item, 'buyQuestModal');
|
||||
this.makeGenericPurchase(this.item, 'buyQuestModal', this.selectedAmountToBuy);
|
||||
this.purchased(this.item.text);
|
||||
this.hideDialog();
|
||||
},
|
||||
|
||||
@@ -477,11 +477,6 @@ export default {
|
||||
|
||||
this.selectedItemToBuy = item;
|
||||
|
||||
if (this.$store.state.recentlyPurchased[item.key]) {
|
||||
this.makeGenericPurchase(item);
|
||||
return;
|
||||
}
|
||||
|
||||
this.$root.$emit('show::modal', 'buy-quest-modal');
|
||||
},
|
||||
},
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
}
|
||||
|
||||
.text {
|
||||
max-height: 220px;
|
||||
margin-bottom: 8px;
|
||||
overflow-y: scroll;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
@@ -502,12 +502,6 @@
|
||||
},
|
||||
itemSelected (item) {
|
||||
if (item.locked) return;
|
||||
|
||||
if (this.$store.state.recentlyPurchased[item.key]) {
|
||||
this.makeGenericPurchase(item);
|
||||
return;
|
||||
}
|
||||
|
||||
this.$root.$emit('buyModal::showItem', item);
|
||||
},
|
||||
},
|
||||
|
||||
@@ -83,7 +83,6 @@
|
||||
@click.prevent.stop="togglePinned(ctx.item)"
|
||||
)
|
||||
span.svg-icon.inline.icon-12.color(v-html="icons.pin")
|
||||
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
@@ -4,13 +4,25 @@
|
||||
.align-self-center.right-margin(:class='baileyClass')
|
||||
.media-body
|
||||
h1.align-self-center(v-markdown='$t("newStuff")')
|
||||
h2 10/20/2017 - USE CASE SPOTLIGHT: CULTIVATING POSITIVITY
|
||||
h2 10/30/2017 - HAPPY HABITOWEEN!
|
||||
hr
|
||||
h3 Use Case Spotlight on Positivity
|
||||
p(v-markdown='"This month\'s [Use Case Spotlight](https://habitica.wordpress.com/2017/10/17/use-case-spotlight-cultivating-positivity/) is about Cultivating Positivity! It features a number of great suggestions submitted by Habiticans in the [Use Case Spotlights Guild](https://habitica.com/groups/guild/1d3a10bf-60aa-4806-a38b-82d1084a59e6). We hope it helps any of you who might be looking to build and maintain a more positive outlook!"')
|
||||
p Plus, we're collecting user submissions for the next spotlight! How do you use Habitica to manage Money Matters? 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!
|
||||
.small by Beffymaroo
|
||||
.scene_positivity.center-block
|
||||
.media
|
||||
.media-body
|
||||
h3 It's Habitoween!
|
||||
p It's the last day of the Fall Festival, and all the NPCs are looking monstrous. Plus, we have lots of fun things in store....
|
||||
h3 Jack O' Lantern Pets and Mounts!
|
||||
p(v-markdown='"The Flourishing Fields are full of cute carved pumpkins - and it looks like one has [followed you home](/inventory/stable)!"')
|
||||
p Each Habitoween, you'll get a new and exciting Jack o'Lantern variety! What kind of Jack o' Lantern? It all depends on how many Habitoweens you've celebrated with us. Happy Fall Festival!
|
||||
.small by Lemoness
|
||||
h3 Candy for Everyone!
|
||||
p(v-markdown='"It\'s a feast for your pets and mounts! In honor of the end of the Fall Festival, we\'ve given everyone an assortment of candy. You can feed it to your pets in the [Stable](/inventory/stable)! Enjoy."')
|
||||
.small by SabreCat and Lemoness
|
||||
.promo_jackolanterns.left-margin
|
||||
h3 Last Chance for Fall Festival Items and Imperious Imp Set
|
||||
p This is your last chance to get all Fall Festival items before they vanish at the end of October 31st! This includes Limited-Edition Outfits, Seasonal Shop purchases, Seasonal Edition Skins and Hair Colors, and yes, even Spooky and Ghost Hatching Potions. Grab them all while you still can!
|
||||
p(v-markdown='"Plus, today is the final day to [subscribe](/user/settings/subscription) and receive the Imperious Imp Item Set!"')
|
||||
p Thanks so much for your supporting the site -- you're helping us keep Habitica alive. Happy Habitoween!
|
||||
.small by Lemoness
|
||||
br
|
||||
</template>
|
||||
|
||||
@@ -28,9 +40,9 @@
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
/* .small {
|
||||
.small {
|
||||
margin-bottom: 1em;
|
||||
} */
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
<template lang="pug">
|
||||
.tasks-column(:class='type')
|
||||
b-modal(ref="editTaskModal")
|
||||
buy-quest-modal(:item="selectedItemToBuy || {}",
|
||||
:priceType="selectedItemToBuy ? selectedItemToBuy.currency : ''",
|
||||
:withPin="true",
|
||||
@change="resetItemToBuy($event)"
|
||||
v-if='type === "reward"')
|
||||
.d-flex
|
||||
h2.tasks-column-title(v-once) {{ $t(types[type].label) }}
|
||||
.filters.d-flex.justify-content-end
|
||||
@@ -15,7 +20,7 @@
|
||||
v-model="quickAddText", @keyup.enter="quickAdd",
|
||||
ref="quickAdd",
|
||||
)
|
||||
.sortable-tasks(ref="tasksList", v-sortable='', @onsort='sorted')
|
||||
.sortable-tasks(ref="tasksList", v-sortable='activeFilters[type].label !== "scheduled"', @onsort='sorted', data-sortableId)
|
||||
task(
|
||||
v-for="task in taskList",
|
||||
:key="task.id", :task="task",
|
||||
@@ -200,6 +205,7 @@ import sortable from 'client/directives/sortable.directive';
|
||||
import buyMixin from 'client/mixins/buy';
|
||||
import { mapState, mapActions } from 'client/libs/store';
|
||||
import shopItem from '../shops/shopItem';
|
||||
import BuyQuestModal from 'client/components/shops/quests/buyQuestModal.vue';
|
||||
|
||||
import { shouldDo } from 'common/script/cron';
|
||||
import inAppRewards from 'common/script/libs/inAppRewards';
|
||||
@@ -215,6 +221,7 @@ export default {
|
||||
mixins: [buyMixin],
|
||||
components: {
|
||||
Task,
|
||||
BuyQuestModal,
|
||||
bModal,
|
||||
shopItem,
|
||||
},
|
||||
@@ -278,6 +285,8 @@ export default {
|
||||
|
||||
forceRefresh: new Date(),
|
||||
quickAddText: '',
|
||||
|
||||
selectedItemToBuy: {},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -288,8 +297,25 @@ export default {
|
||||
}),
|
||||
taskList () {
|
||||
// @TODO: This should not default to user's tasks. It should require that you pass options in
|
||||
if (this.taskListOverride) return this.taskListOverride;
|
||||
return this.tasks[`${this.type}s`];
|
||||
const filter = this.activeFilters[this.type];
|
||||
|
||||
let taskList = this.tasks[`${this.type}s`];
|
||||
if (this.taskListOverride) taskList = this.taskListOverride;
|
||||
|
||||
if (taskList.length > 0 && ['scheduled', 'due'].indexOf(filter.label) === -1) {
|
||||
let taskListSorted = this.$store.dispatch('tasks:order', [
|
||||
taskList,
|
||||
this.user.tasksOrder,
|
||||
]);
|
||||
|
||||
taskList = taskListSorted[`${this.type}s`];
|
||||
}
|
||||
|
||||
if (filter.sort) {
|
||||
taskList = sortBy(taskList, filter.sort);
|
||||
}
|
||||
|
||||
return taskList;
|
||||
},
|
||||
inAppRewards () {
|
||||
let watchRefresh = this.forceRefresh; // eslint-disable-line
|
||||
@@ -365,19 +391,25 @@ export default {
|
||||
loadCompletedTodos: 'tasks:fetchCompletedTodos',
|
||||
createTask: 'tasks:create',
|
||||
}),
|
||||
sorted (data) {
|
||||
async sorted (data) {
|
||||
const filteredList = this.taskList.filter(this.activeFilters[this.type].filter);
|
||||
const sorting = this.taskList;
|
||||
const taskIdToMove = this.taskList[data.oldIndex]._id;
|
||||
const taskIdToMove = filteredList[data.oldIndex]._id;
|
||||
|
||||
// Server
|
||||
const taskIdToReplace = filteredList[data.newIndex];
|
||||
const newIndexOnServer = this.taskList.findIndex(taskId => taskId === taskIdToReplace);
|
||||
let newOrder = await this.$store.dispatch('tasks:move', {
|
||||
taskId: taskIdToMove,
|
||||
position: newIndexOnServer,
|
||||
});
|
||||
this.user.tasksOrder[`${this.type}s`] = newOrder;
|
||||
|
||||
// Client
|
||||
if (sorting) {
|
||||
const deleted = sorting.splice(data.oldIndex, 1);
|
||||
sorting.splice(data.newIndex, 0, deleted[0]);
|
||||
}
|
||||
|
||||
this.$store.dispatch('tasks:move', {
|
||||
taskId: taskIdToMove,
|
||||
position: data.newIndex,
|
||||
});
|
||||
},
|
||||
quickAdd () {
|
||||
const task = taskDefaults({type: this.type, text: this.quickAddText});
|
||||
@@ -393,10 +425,6 @@ export default {
|
||||
this.loadCompletedTodos();
|
||||
}
|
||||
this.activeFilters[type] = filter;
|
||||
|
||||
if (filter.sort) {
|
||||
this.tasks[`${type}s`] = sortBy(this.tasks[`${type}s`], filter.sort);
|
||||
}
|
||||
},
|
||||
setColumnBackgroundVisibility () {
|
||||
this.$nextTick(() => {
|
||||
@@ -465,10 +493,21 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
if (rewardItem.purchaseType === 'quests') {
|
||||
this.selectedItemToBuy = rewardItem;
|
||||
this.$root.$emit('show::modal', 'buy-quest-modal');
|
||||
return;
|
||||
}
|
||||
|
||||
if (rewardItem.purchaseType !== 'gear' || !rewardItem.locked) {
|
||||
this.$emit('openBuyDialog', rewardItem);
|
||||
}
|
||||
},
|
||||
resetItemToBuy ($event) {
|
||||
if (!$event) {
|
||||
this.selectedItemToBuy = null;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,23 +1,45 @@
|
||||
import Sortable from 'sortablejs';
|
||||
import uuid from 'uuid';
|
||||
|
||||
let emit = (vnode, eventName, data) => {
|
||||
let handlers = vnode.data && vnode.data.on ||
|
||||
vnode.componentOptions && vnode.componentOptions.listeners;
|
||||
let emit = (vNode, eventName, data) => {
|
||||
let handlers = vNode.data && vNode.data.on ||
|
||||
vNode.componentOptions && vNode.componentOptions.listeners;
|
||||
|
||||
if (handlers && handlers[eventName]) {
|
||||
handlers[eventName].fns(data);
|
||||
}
|
||||
};
|
||||
|
||||
let sortableReferences = {};
|
||||
|
||||
function createSortable (el, vNode) {
|
||||
let sortableRef = Sortable.create(el, {
|
||||
onSort: (evt) => {
|
||||
emit(vNode, 'onsort', {
|
||||
oldIndex: evt.oldIndex,
|
||||
newIndex: evt.newIndex,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
let uniqueId = uuid();
|
||||
sortableReferences[uniqueId] = sortableRef;
|
||||
el.dataset.sortableId = uniqueId;
|
||||
}
|
||||
|
||||
export default {
|
||||
bind (el, binding, vnode) {
|
||||
Sortable.create(el, {
|
||||
onSort: (evt) => {
|
||||
emit(vnode, 'onsort', {
|
||||
oldIndex: evt.oldIndex,
|
||||
newIndex: evt.newIndex,
|
||||
});
|
||||
},
|
||||
});
|
||||
bind (el, binding, vNode) {
|
||||
createSortable(el, vNode);
|
||||
},
|
||||
unbind (el) {
|
||||
if (sortableReferences[el.dataset.sortableId]) sortableReferences[el.dataset.sortableId].destroy();
|
||||
},
|
||||
update (el, vNode) {
|
||||
if (sortableReferences[el.dataset.sortableId] && !vNode.value) {
|
||||
sortableReferences[el.dataset.sortableId].destroy();
|
||||
delete sortableReferences[el.dataset.sortableId];
|
||||
return;
|
||||
}
|
||||
if (!sortableReferences[el.dataset.sortableId]) createSortable(el, vNode);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
export default {
|
||||
methods: {
|
||||
makeGenericPurchase (item, type = 'buyModal') {
|
||||
makeGenericPurchase (item, type = 'buyModal', quantity = 1) {
|
||||
this.$store.dispatch('shops:genericPurchase', {
|
||||
pinType: item.pinType,
|
||||
type: item.purchaseType,
|
||||
key: item.key,
|
||||
currency: item.currency,
|
||||
quantity,
|
||||
});
|
||||
|
||||
if (item.purchaseType !== 'gear') {
|
||||
this.$store.state.recentlyPurchased[item.key] = true;
|
||||
}
|
||||
|
||||
this.$root.$emit('playSound', 'Reward');
|
||||
|
||||
if (type !== 'buyModal') {
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
import axios from 'axios';
|
||||
import buyOp from 'common/script/ops/buy';
|
||||
import buyQuestOp from 'common/script/ops/buyQuest';
|
||||
import purchaseOp from 'common/script/ops/purchaseWithSpell';
|
||||
import buyMysterySetOp from 'common/script/ops/buyMysterySet';
|
||||
import hourglassPurchaseOp from 'common/script/ops/hourglassPurchase';
|
||||
import sellOp from 'common/script/ops/sell';
|
||||
import unlockOp from 'common/script/ops/unlock';
|
||||
import buyArmoire from 'common/script/ops/buyArmoire';
|
||||
import rerollOp from 'common/script/ops/reroll';
|
||||
import { getDropClass } from 'client/libs/notifications';
|
||||
|
||||
// @TODO: Purchase means gems and buy means gold. That wording is misused below, but we should also change
|
||||
// the generic buy functions to something else. Or have a Gold Vendor and Gem Vendor, etc
|
||||
|
||||
export function buyItem (store, params) {
|
||||
const quantity = params.quantity || 1;
|
||||
const user = store.state.user.data;
|
||||
let opResult = buyOp(user, {params});
|
||||
let opResult = buyOp(user, {params, quantity});
|
||||
|
||||
return {
|
||||
result: opResult,
|
||||
@@ -21,32 +22,77 @@ export function buyItem (store, params) {
|
||||
}
|
||||
|
||||
export function buyQuestItem (store, params) {
|
||||
const quantity = params.quantity || 1;
|
||||
const user = store.state.user.data;
|
||||
let opResult = buyQuestOp(user, {params});
|
||||
let opResult = buyOp(user, {
|
||||
params,
|
||||
type: 'quest',
|
||||
quantity,
|
||||
});
|
||||
|
||||
return {
|
||||
result: opResult,
|
||||
httpCall: axios.post(`/api/v3/user/buy-quest/${params.key}`),
|
||||
httpCall: axios.post(`/api/v3/user/buy/${params.key}`, {type: 'quest'}),
|
||||
};
|
||||
}
|
||||
|
||||
async function buyArmoire (store, params) {
|
||||
const quantity = params.quantity || 1;
|
||||
|
||||
let buyResult = buyOp(store.state.user.data, {
|
||||
params: {
|
||||
key: 'armoire',
|
||||
},
|
||||
type: 'armoire',
|
||||
quantity,
|
||||
});
|
||||
|
||||
// We need the server result because armoir has random item in the result
|
||||
let result = await axios.post('/api/v3/user/buy/armoire', {
|
||||
type: 'armoire',
|
||||
quantity,
|
||||
});
|
||||
buyResult = result.data.data;
|
||||
|
||||
if (buyResult) {
|
||||
const resData = buyResult;
|
||||
const item = resData.armoire;
|
||||
|
||||
const isExperience = item.type === 'experience';
|
||||
|
||||
if (item.type === 'gear') {
|
||||
store.state.user.data.items.gear.owned[item.dropKey] = true;
|
||||
}
|
||||
|
||||
// @TODO: We might need to abstract notifications to library rather than mixin
|
||||
store.dispatch('snackbars:add', {
|
||||
title: '',
|
||||
text: isExperience ? item.value : item.dropText,
|
||||
type: isExperience ? 'xp' : 'drop',
|
||||
icon: isExperience ? null : getDropClass({type: item.type, key: item.dropKey}),
|
||||
timeout: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function purchase (store, params) {
|
||||
const quantity = params.quantity || 1;
|
||||
const user = store.state.user.data;
|
||||
let opResult = purchaseOp(user, {params});
|
||||
let opResult = purchaseOp(user, {params, quantity});
|
||||
|
||||
return {
|
||||
result: opResult,
|
||||
httpCall: axios.post(`/api/v3/user/purchase/${params.type}/${params.key}`),
|
||||
httpCall: axios.post(`/api/v3/user/purchase/${params.type}/${params.key}`, {quantity}),
|
||||
};
|
||||
}
|
||||
|
||||
export function purchaseMysterySet (store, params) {
|
||||
const user = store.state.user.data;
|
||||
let opResult = buyMysterySetOp(user, {params, noConfirm: true});
|
||||
let opResult = buyOp(user, {params, noConfirm: true, type: 'mystery'});
|
||||
|
||||
return {
|
||||
result: opResult,
|
||||
httpCall: axios.post(`/api/v3/user/buy-mystery-set/${params.key}`),
|
||||
httpCall: axios.post(`/api/v3/user/buy/${params.key}`, {type: 'mystery'}),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -75,32 +121,7 @@ export async function genericPurchase (store, params) {
|
||||
case 'mystery_set':
|
||||
return purchaseMysterySet(store, params);
|
||||
case 'armoire': // eslint-disable-line
|
||||
let buyResult = buyArmoire(store.state.user.data);
|
||||
|
||||
// We need the server result because armoir has random item in the result
|
||||
let result = await axios.post('/api/v3/user/buy-armoire');
|
||||
buyResult = result.data.data;
|
||||
|
||||
if (buyResult) {
|
||||
const resData = buyResult;
|
||||
const item = resData.armoire;
|
||||
|
||||
const isExperience = item.type === 'experience';
|
||||
|
||||
if (item.type === 'gear') {
|
||||
store.state.user.data.items.gear.owned[item.dropKey] = true;
|
||||
}
|
||||
|
||||
// @TODO: We might need to abstract notifications to library rather than mixin
|
||||
store.dispatch('snackbars:add', {
|
||||
title: '',
|
||||
text: isExperience ? item.value : item.dropText,
|
||||
type: isExperience ? 'xp' : 'drop',
|
||||
icon: isExperience ? null : getDropClass({type: item.type, key: item.dropKey}),
|
||||
timeout: true,
|
||||
});
|
||||
}
|
||||
|
||||
await buyArmoire(store, params);
|
||||
return;
|
||||
case 'fortify': {
|
||||
let rerollResult = rerollOp(store.state.user.data);
|
||||
@@ -134,9 +155,5 @@ export async function genericPurchase (store, params) {
|
||||
export function sellItems (store, params) {
|
||||
const user = store.state.user.data;
|
||||
sellOp(user, {params, query: {amount: params.amount}});
|
||||
axios
|
||||
.post(`/api/v3/user/sell/${params.type}/${params.key}?amount=${params.amount}`);
|
||||
// TODO
|
||||
// .then((res) => console.log('equip', res))
|
||||
// .catch((err) => console.error('equip', err));
|
||||
axios.post(`/api/v3/user/sell/${params.type}/${params.key}?amount=${params.amount}`);
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@ export default function () {
|
||||
actions,
|
||||
getters,
|
||||
state: {
|
||||
serverAppVersion: '',
|
||||
title: 'Habitica',
|
||||
isUserLoggedIn,
|
||||
isUserLoaded: false, // Means the user and the user's tasks are ready
|
||||
@@ -134,7 +135,6 @@ export default function () {
|
||||
modalStack: [],
|
||||
brokenChallengeTask: {},
|
||||
equipmentDrawerOpen: true,
|
||||
recentlyPurchased: {},
|
||||
groupPlans: [],
|
||||
groupNotifications: [],
|
||||
},
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
"profile": "Профил",
|
||||
"avatar": "Персонализиране на героя",
|
||||
"editAvatar": "Редактиране на героя",
|
||||
"noDescription": "This Habitican hasn't added a description.",
|
||||
"noPhoto": "This Habitican hasn't added a photo.",
|
||||
"noDescription": "Този хабитиканец не е добавил описание.",
|
||||
"noPhoto": "Този хабитиканец не е добавил снимка.",
|
||||
"other": "Други",
|
||||
"fullName": "Пълно име",
|
||||
"displayName": "Екранно име",
|
||||
|
||||
@@ -578,6 +578,8 @@
|
||||
"armorMystery201704Notes": "Приказните същества са създали тази броня от утринна роса, за да уловят цветовете на изгрева. Не променя показателите. Предмет за абонати: април 2017 г.",
|
||||
"armorMystery201707Text": "Желемантска броня",
|
||||
"armorMystery201707Notes": "Тази броня ще Ви помогне да се слеете с морските същества, докато изпълнявате подводните си мисии или преживявате други приключения под водата. Не променя показателите. Предмет за абонати: юли 2017 г.",
|
||||
"armorMystery201710Text": "Облекло на надменно дяволче",
|
||||
"armorMystery201710Notes": "Люспесто, лъскаво и здраво! Не променя показателите. Предмет за абонати: октомври 2017 г.",
|
||||
"armorMystery301404Text": "Изтънчен костюм",
|
||||
"armorMystery301404Notes": "Спретнат и елегантен! Не променя показателите. Предмет за абонати: февруари 3015 г.",
|
||||
"armorMystery301703Text": "Изтънчена паунова рокля",
|
||||
@@ -926,6 +928,8 @@
|
||||
"headMystery201705Notes": "Всички са чували за подвизите на свирепите и продуктивни Грифонски воини от Хабитика! Присъединете се към престижните им редици с този пернат шлем. Не променя показателите. Предмет за абонати: май 2017 г.",
|
||||
"headMystery201707Text": "Желемантски шлем",
|
||||
"headMystery201707Notes": "Трябват ли Ви допълнителни ръце за задачите Ви? Този шлем от полупрозрачно желе има даста пипала, които могат да Ви свършат работа. Не променя показателите. Предмет за абонати: юли 2017 г.",
|
||||
"headMystery201710Text": "Шлем на надменно дяволче",
|
||||
"headMystery201710Notes": "С този шлем ще изглеждате страховито… но пък няма да имате добро 3-измерно зрение! Не променя показателите. Предмет за абонати: октомври 2017 г.",
|
||||
"headMystery301404Text": "Украсен цилиндър",
|
||||
"headMystery301404Notes": "Украсен цилиндър за най-изтънчените и високопоставени членове на обществото. Не променя показателите. Предмет за абонати: януари 3015 г.",
|
||||
"headMystery301405Text": "Обикновен цилиндър",
|
||||
|
||||
@@ -273,5 +273,7 @@
|
||||
"emptyMessagesLine1": "Нямате съобщения",
|
||||
"emptyMessagesLine2": "Изпратете съобщение, за да започнете разговор",
|
||||
"letsgo": "Хойде!",
|
||||
"selected": "Избрано"
|
||||
"selected": "Избрано",
|
||||
"howManyToBuy": "Колко искате да купите?",
|
||||
"habiticaHasUpdated": "There is a new Habitica update. Refresh to get the latest version!"
|
||||
}
|
||||
@@ -536,7 +536,7 @@
|
||||
"questLostMasterclasser3DropZombiePotion": "Зомбираща излюпваща отвара",
|
||||
"questLostMasterclasser4Text": "Загадката на класовите повелители, част 4: Изгубената класова повелителка",
|
||||
"questLostMasterclasser4Notes": "Показваш се от портала, но все още се оказваш свързан в някакъв странен, движещ се несъществуващ свят. „Това беше доста смело“ — казва студен глас. — „Трябва да призная, че не очаквах директен сблъсък толкова скоро.“ — От разбъркания вихър тъмнина се появява жена. — „Добре дошъл в Бездната.“<br><br>Опитваш се да превъзмогнеш внезапния пристъп на гадене. — „Ти ли си Зиня?“ — питаш.<br><br>„Какво старо име за такъв млад идеалист“ — казва тя, преплитайки езика си, а светът под теб се извива. — „Не. Сега можеш да ме наричаш Анти'зиня, като се има предвид това което направих и разруших.“<br><br>Внезапно, порталът се отваря отново зад теб и четиримата класови повелители излизат от него и се втурват към теб. В очите на Анти'зиня проблясва злобба. — „Виждам, че моите жалки заместители успяха да те проследят.“<br><br>Ти я поглеждаш учудено — „Заместители?“<br><br>Като главен Етермант, аз бях първата класова повелителка. Тези четиримата са посмешища, всеки от тях притежава само част от това, което аз някога имах! Аз владеех всички заклинания и изучих всички умения. Аз оформях света ти според прищявките си — докато самият изменнически етер не се срина под тежестта на талантите ми и моите съвсем разумни очаквания. Бях затворена в тази бездна, която се образува, повече от хиляда години, докато се възстановявах. Представи си отвращението ми, когато научих как е покварено наследството ми“ — тя се изсмива, предизвиквайки ехо. — „Планът ми беше да унищожа владенията им, а след това и тях, но предполагам, че редът не е от голямо значение.“ — и с изблик на неестествена сила тя се втурва напред, а в Бездната настава хаос.",
|
||||
"questLostMasterclasser4Completion": "Под яростта на последния ти удар загубената класова повелителка изпищява от ужас и разочарование, а тялото и започва да примигва и да избледнява. Бездната замръзва около нея и тя пада напред, за момент изглеждайки променена, по-млада, по-спокойна, с мирно изражение на лицето… но след тва всичко се стопява за миг и вие се озовавате на колене в пустинните пясъци.<br><br>„Изглежда имаме още много да учим за собствената си история“ — казва крал Манта, докато се взира в развалините. — „След като главния Етермант се претовари и загуби контрол над способностите си, изливането на бездната трябва да е изсмукало живота от цялата земя. Всичко сигурно се е превърнало в пустиня като тази тук.“<br><br>„Нищо чудно, че древните, които са основали Хабитика, са държали на баланса между продуктивност и здраве“ — мърмори си под носа Веселата жетварка. — „Да построим наново техния свят би било тежка задача, изискваща сериозна работа, но те биха искали да предотвратим това подобна катастрофа да се случи отново.“<br><br>„Охо, вижте предметите, които бяха обладани преди!“ — казва Първоаприлският шегаджия. И наистина, всички те блещукат с бледа, светла прозрачност от последния изблик на етер, произведен, когато довърши духа на Анти'зиня. — „Какъв изумителен ефект. Трябва да си водя бележки.“<br><br>„Концентрираните остатъци от етер в тази област сигурно са направили и тези животни невидими“ — казва лейди Глетчер, почесвайки малка невидима област зад ухото си. Усещаш невидима пухкава глава да докосва ръката ти и разбираш, че ще има да се обясняваш в конюшнята. Поглеждайки развалините още веднъж, забелязваш останките на първия класов повелител: блестящата ѝ мантия. Поставяйки я на раменете си, ти и спътниците ти се запътвате обратно към Хабитград, осмисляйки всичко, което научихте.<br><br>",
|
||||
"questLostMasterclasser4Completion": "Под яростта на последния ти удар загубената класова повелителка изпищява от ужас и разочарование, а тялото и започва да примигва и да избледнява. Бездната замръзва около нея и тя пада напред, за момент изглеждайки променена, по-млада, по-спокойна, с мирно изражение на лицето… но след това всичко се стопява за миг и вие се озовавате на колене в пустинните пясъци.<br><br>„Изглежда имаме още много да учим за собствената си история“ — казва крал Манта, докато се взира в развалините. — „След като главния Етермант се претовари и загуби контрол над способностите си, изливането на бездната трябва да е изсмукало живота от цялата земя. Всичко сигурно се е превърнало в пустиня като тази тук.“<br><br>„Нищо чудно, че древните, които са основали Хабитика, са държали на баланса между продуктивност и здраве“ — мърмори си под носа Веселата жетварка. — „Да построим наново техния свят би било тежка задача, изискваща сериозна работа, но те биха искали да предотвратим това подобна катастрофа да се случи отново.“<br><br>„Охо, вижте предметите, които бяха обладани преди!“ — казва Първоаприлският шегаджия. И наистина, всички те блещукат с бледа, светла прозрачност от последния изблик на етер, произведен, когато довърши духа на Анти'зиня. — „Какъв изумителен ефект. Трябва да си водя бележки.“<br><br>„Концентрираните остатъци от етер в тази област сигурно са направили и тези животни невидими“ — казва лейди Глетчер, почесвайки малка невидима област зад ухото си. Усещаш невидима пухкава глава да докосва ръката ти и разбираш, че ще има да се обясняваш в конюшнята. Поглеждайки развалините още веднъж, забелязваш останките на първия класов повелител: блестящата ѝ мантия. Поставяйки я на раменете си, ти и спътниците ти се запътвате обратно към Хабитград, осмисляйки всичко, което научихте.<br><br>",
|
||||
"questLostMasterclasser4Boss": "Анти'зиня",
|
||||
"questLostMasterclasser4RageTitle": "Завихрена бездна",
|
||||
"questLostMasterclasser4RageDescription": "Завихрена бездна: Тази лента се запълва, когато не изпълнявате ежедневните си задачи. Когато се запълни докрай, Анти'зиня ще отнеме от маната на групата!",
|
||||
|
||||
@@ -72,6 +72,8 @@
|
||||
"APIv3": "ППИ версия 3",
|
||||
"APIText": "Можете да копирате тези стойности и да ги използвате във външни приложения. Имайте предвид, че Вашият жетон за ППИ е нещо като парола - и не го споделяйте. Понякога от Вас може да изискват Вашия потребителски идентификатор и в това няма нищо опасно, но никога не публикувайте своя жетон за ППИ там, където той може да бъде видян от другиго, включително в Github.",
|
||||
"APIToken": "Жетон за ППИ (Това е на практика парола — вижте предупреждението по-горе!)",
|
||||
"showAPIToken": "Показване на жетона за ППИ",
|
||||
"hideAPIToken": "Скриване на жетона за ППИ",
|
||||
"APITokenWarning": "Ако Ви трябва нов жетон за ППИ (ако например старият Ви вече не е таен), пишете на <%= hrefTechAssistanceEmail %>, посочвайки потребителския си идентификатор и текущия си жетон. След като той бъде подновен, ще трябва отново да разрешите достъпа на всичко, което сте използвали, като излезете от профила си в уеб сайта и мобилното приложение, и след това въведете новия си жетон във всички инструменти за Хабитика, които използвате.",
|
||||
"thirdPartyApps": "Външни приложения",
|
||||
"dataToolDesc": "Страница, която може да Ви покаже разнообразна информация, извлечена от Вашия профил в Хабитика, като например статистики относно Вашите задачи, екипировка и умения.",
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
"spellRogueToolsOfTradeText": "Майсторски усет",
|
||||
"spellRogueToolsOfTradeNotes": "Лавките Ви талантите подсилват усета на цялата група! (Зависи от: неподсиления УСЕ)",
|
||||
"spellRogueStealthText": "Невидимост",
|
||||
"spellRogueStealthNotes": "With each cast, a few of your undone Dailies won't cause damage tonight. Their streaks and colors won't change. (Based on: PER)",
|
||||
"spellRogueStealthNotes": "При всяко изпълнение част от незавършените Ви ежедневни задачи няма да Ви нанесат щети след края на деня. Сериите и цветовете им няма да се променят. (Зависи от: УСЕ)",
|
||||
"spellRogueStealthDaliesAvoided": "<%= originalText %> Брой избегнати ежедневни задачи: <%= number %>.",
|
||||
"spellRogueStealthMaxedOut": "Вие вече сте избегнали всичките си ежедневни задачи. Няма нужда да правите това заклинание отново.",
|
||||
"spellHealerHealText": "Лечебна светлина",
|
||||
|
||||
@@ -134,6 +134,7 @@
|
||||
"mysterySet201707": "Желемантски комплект",
|
||||
"mysterySet201708": "Комплект на воина на лавата",
|
||||
"mysterySet201709": "Комплект на ученика-магьосник",
|
||||
"mysterySet201710": "Комплект на надменното дяволче",
|
||||
"mysterySet301404": "Стандартен изтънчен комплект",
|
||||
"mysterySet301405": "Комплект изтънчени принадлежности",
|
||||
"mysterySet301703": "Изтънчен паунов комплект",
|
||||
@@ -201,5 +202,6 @@
|
||||
"subscriptionAlreadySubscribed1": "За да видите подробности за абонамента си или да го прекратите, подновите или промените, моля, щракнете върху <a href='/user/settings/subscription'>Потребителската иконка и изберете Настройки > Абонамент</a>.",
|
||||
"purchaseAll": "Купуване на всичко",
|
||||
"gemsPurchaseNote": "Абонатите могат да купуват диаманти със злато на пазара! За по-лесен достъп можете също да закачите диаманта към колоната си с награди.",
|
||||
"gemsRemaining": "оставащи диаманта"
|
||||
"gemsRemaining": "оставащи диаманта",
|
||||
"notEnoughGemsToBuy": "Не можете да закупите толкова диаманти"
|
||||
}
|
||||
@@ -578,6 +578,8 @@
|
||||
"armorMystery201704Notes": "Fairy folk crafted this armor from morning dew to capture the colors of the sunrise. Confers no benefit. April 2017 Subscriber Item.",
|
||||
"armorMystery201707Text": "Jellymancer Armor",
|
||||
"armorMystery201707Notes": "This armor will help you blend in with the creatures of the ocean while you pursue undersea quests and adventures. Confers no benefit. July 2017 Subscriber Item.",
|
||||
"armorMystery201710Text": "Imperious Imp Apparel",
|
||||
"armorMystery201710Notes": "Scaly, shiny, and strong! Confers no benefit. October 2017 Subscriber Item.",
|
||||
"armorMystery301404Text": "Steampunk oblek",
|
||||
"armorMystery301404Notes": "Elegantní a fešácký, joj! Nepřináší žádný benefit. Předmět pro předplatitele únor 3015.",
|
||||
"armorMystery301703Text": "Steampunk Peacock Gown",
|
||||
@@ -926,6 +928,8 @@
|
||||
"headMystery201705Notes": "Habitica is known for its fierce and productive Gryphon Warriors! Join their prestigious ranks when you don this feathery helm. Confers no benefit. May 2017 Subscriber Item.",
|
||||
"headMystery201707Text": "Jellymancer Helm",
|
||||
"headMystery201707Notes": "Need some extra hands for your tasks? This translucent jelly helm has quite a few tentacles to lend you help! Confers no benefit. July 2017 Subscriber Item.",
|
||||
"headMystery201710Text": "Imperious Imp Helm",
|
||||
"headMystery201710Notes": "This helm makes you look intimidating... but it won't do any favors for your depth perception! Confers no benefit. October 2017 Subscriber Item.",
|
||||
"headMystery301404Text": "Fešný cylindr",
|
||||
"headMystery301404Notes": "Fešný cylindr pro ty největší džentlmeny. Předmět pro předplatitele leden 2015. Nepřináší žádný benefit.",
|
||||
"headMystery301405Text": "Obyčejný cylindr",
|
||||
|
||||
@@ -273,5 +273,7 @@
|
||||
"emptyMessagesLine1": "You don't have any messages",
|
||||
"emptyMessagesLine2": "Send a message to start a conversation!",
|
||||
"letsgo": "Let's Go!",
|
||||
"selected": "Selected"
|
||||
"selected": "Selected",
|
||||
"howManyToBuy": "How many would you like to buy?",
|
||||
"habiticaHasUpdated": "There is a new Habitica update. Refresh to get the latest version!"
|
||||
}
|
||||
@@ -536,7 +536,7 @@
|
||||
"questLostMasterclasser3DropZombiePotion": "Zombie Hatching Potion",
|
||||
"questLostMasterclasser4Text": "The Mystery of the Masterclassers, Part 4: The Lost Masterclasser",
|
||||
"questLostMasterclasser4Notes": "You surface from the portal, but you’re still suspended in a strange, shifting netherworld. “That was bold,” says a cold voice. “I have to admit, I hadn’t planned for a direct confrontation yet.” A woman rises from the churning whirlpool of darkness. “Welcome to the Realm of Void.”<br><br>You try to fight back your rising nausea. “Are you Zinnya?” you ask.<br><br>“That old name for a young idealist,” she says, mouth twisting, and the world writhes beneath you. “No. If anything, you should call me the Anti’zinnya now, given all that I have done and undone.”<br><br>Suddenly, the portal reopens behind you, and as the four Masterclassers burst out, bolting towards you, Anti’zinnya’s eyes flash with hatred. “I see that my pathetic replacements have managed to follow you.”<br><br>You stare. “Replacements?”<br><br>“As the Master Aethermancer, I was the first Masterclasser — the only Masterclasser. These four are a mockery, each possessing only a fragment of what I once had! I commanded every spell and learned every skill. I shaped your very world to my whim — until the traitorous aether itself collapsed under the weight of my talents and my perfectly reasonable expectations. I have been trapped for millennia in this resulting void, recuperating. Imagine my disgust when I learned how my legacy had been corrupted.” She lets out a low, echoing laugh. “My plan was to destroy their domains before destroying them, but I suppose the order is irrelevant.” With a burst of uncanny strength, she charges forward, and the Realm of Void explodes into chaos.",
|
||||
"questLostMasterclasser4Completion": "Under the onslaught of your final attack, the Lost Masterclasser screams in frustration, her body flickering into translucence. The thrashing void stills around her as she slumps forward, and for a moment, she seems to change, becoming younger, calmer, with an expression of peace upon her face… but then everything melts away with scarcely a whisper, and you’re kneeling once more in the desert sand.<br><br>“It seems that we have much to learn about our own history,” King Manta says, staring at the broken ruins. “After the Master Aethermancer grew overwhelmed and lost control of her abilities, the outpouring of void must have leached the life from the entire land. Everything probably became deserts like this.”<br><br>“No wonder the ancients who founded Habitica stressed a balance of productivity and wellness,” the Joyful Reaper murmurs. “Rebuilding their world would have been a daunting task requiring considerable hard work, but they would have wanted to prevent such a catastrophe from happening again.”<br><br>“Oho, look at those formerly possessed items!” says the April Fool. Sure enough, all of them shimmer with a pale, glimmering translucence from the final burst of aether released when you laid Anti’zinnya’s spirit to rest. “What a dazzling effect. I must take notes.”<br><br>“The concentrated remnants of aether in this area probably caused caused these animals to go invisible, too,” says Lady Glaciate, scratching a patch of emptiness behind the ears. You feel an unseen fluffy head nudge your hand, and suspect that you’ll have to do some explaining at the Stables back home. As you look at the ruins one last time, you spot all that remains of the first Masterclasser: her shimmering cloak. Lifting it onto your shoulders, you head back to Habit City, pondering everything that you have learned.<br><br>",
|
||||
"questLostMasterclasser4Completion": "Under the onslaught of your final attack, the Lost Masterclasser screams in frustration, her body flickering into translucence. The thrashing void stills around her as she slumps forward, and for a moment, she seems to change, becoming younger, calmer, with an expression of peace upon her face… but then everything melts away with scarcely a whisper, and you’re kneeling once more in the desert sand.<br><br>“It seems that we have much to learn about our own history,” King Manta says, staring at the broken ruins. “After the Master Aethermancer grew overwhelmed and lost control of her abilities, the outpouring of void must have leached the life from the entire land. Everything probably became deserts like this.”<br><br>“No wonder the ancients who founded Habitica stressed a balance of productivity and wellness,” the Joyful Reaper murmurs. “Rebuilding their world would have been a daunting task requiring considerable hard work, but they would have wanted to prevent such a catastrophe from happening again.”<br><br>“Oho, look at those formerly possessed items!” says the April Fool. Sure enough, all of them shimmer with a pale, glimmering translucence from the final burst of aether released when you laid Anti’zinnya’s spirit to rest. “What a dazzling effect. I must take notes.”<br><br>“The concentrated remnants of aether in this area probably caused these animals to go invisible, too,” says Lady Glaciate, scratching a patch of emptiness behind the ears. You feel an unseen fluffy head nudge your hand, and suspect that you’ll have to do some explaining at the Stables back home. As you look at the ruins one last time, you spot all that remains of the first Masterclasser: her shimmering cloak. Lifting it onto your shoulders, you head back to Habit City, pondering everything that you have learned.<br><br>",
|
||||
"questLostMasterclasser4Boss": "Anti'zinnya",
|
||||
"questLostMasterclasser4RageTitle": "Siphoning Void",
|
||||
"questLostMasterclasser4RageDescription": "Siphoning Void: This bar fills when you don't complete your Dailies. When it is full, Anti'zinnya will remove the party's Mana!",
|
||||
|
||||
@@ -72,6 +72,8 @@
|
||||
"APIv3": "API v3",
|
||||
"APIText": "Zkopíruj je pro použití v aplikacích třetích stran. Avšak, stejně jako bys nikomu neřekl své heslo, tak nikomu neříkej svůj API Token. Někdy můžeš být požádán o své uživatelské ID, ale nikdy neuveřejňuj svůj API Token tam, kde ho uvidí ostatní a to včetně Githubu.",
|
||||
"APIToken": "API token (toto je heslo - přečti si upozornění nahoře!)",
|
||||
"showAPIToken": "Show API Token",
|
||||
"hideAPIToken": "Hide API Token",
|
||||
"APITokenWarning": "If you need a new API Token (e.g., if you accidentally shared it), email <%= hrefTechAssistanceEmail %> with your User ID and current Token. Once it is reset you will need to re-authorize everything by logging out of the website and mobile app and by providing the new Token to any other Habitica tools that you use.",
|
||||
"thirdPartyApps": "Programy třetí strany",
|
||||
"dataToolDesc": "Webová stránka, která zobrazuje určité informace z tvého Habitica účtu, jako statistiky o tvých úkolech, vybavení a schopnostech.",
|
||||
|
||||
@@ -134,6 +134,7 @@
|
||||
"mysterySet201707": "Jellymancer Set",
|
||||
"mysterySet201708": "Lava Warrior Set",
|
||||
"mysterySet201709": "Sorcery Student Set",
|
||||
"mysterySet201710": "Imperious Imp Set",
|
||||
"mysterySet301404": "Standardní steampunkový set",
|
||||
"mysterySet301405": "Set steampunkových doplňků",
|
||||
"mysterySet301703": "Peacock Steampunk Set",
|
||||
@@ -201,5 +202,6 @@
|
||||
"subscriptionAlreadySubscribed1": "To see your subscription details and cancel, renew, or change your subscription, please go to <a href='/user/settings/subscription'>User icon > Settings > Subscription</a>.",
|
||||
"purchaseAll": "Purchase All",
|
||||
"gemsPurchaseNote": "Subscribers can buy gems for gold in the Market! For easy access, you can also pin the gem to your Rewards column.",
|
||||
"gemsRemaining": "gems remaining"
|
||||
"gemsRemaining": "gems remaining",
|
||||
"notEnoughGemsToBuy": "You are unable to buy that amount of gems"
|
||||
}
|
||||
@@ -578,6 +578,8 @@
|
||||
"armorMystery201704Notes": "Fefolket frembragte denne rustning fra morgendug for at fange solopgangens farver. Giver ingen fordele. April 2017 Abonnentgenstand",
|
||||
"armorMystery201707Text": "Jellymancer Armor",
|
||||
"armorMystery201707Notes": "This armor will help you blend in with the creatures of the ocean while you pursue undersea quests and adventures. Confers no benefit. July 2017 Subscriber Item.",
|
||||
"armorMystery201710Text": "Imperious Imp Apparel",
|
||||
"armorMystery201710Notes": "Scaly, shiny, and strong! Confers no benefit. October 2017 Subscriber Item.",
|
||||
"armorMystery301404Text": "Steampunk-dragt",
|
||||
"armorMystery301404Notes": "Nydelig og elegant, selvfølgelig! Giver ingen bonusser. Februar 3015 Abonnentting.",
|
||||
"armorMystery301703Text": "Steampunk Peacock Gown",
|
||||
@@ -926,6 +928,8 @@
|
||||
"headMystery201705Notes": "Habitica is known for its fierce and productive Gryphon Warriors! Join their prestigious ranks when you don this feathery helm. Confers no benefit. May 2017 Subscriber Item.",
|
||||
"headMystery201707Text": "Jellymancer Helm",
|
||||
"headMystery201707Notes": "Need some extra hands for your tasks? This translucent jelly helm has quite a few tentacles to lend you help! Confers no benefit. July 2017 Subscriber Item.",
|
||||
"headMystery201710Text": "Imperious Imp Helm",
|
||||
"headMystery201710Notes": "This helm makes you look intimidating... but it won't do any favors for your depth perception! Confers no benefit. October 2017 Subscriber Item.",
|
||||
"headMystery301404Text": "Smart Tophat",
|
||||
"headMystery301404Notes": "En smart tophat for de fineste folk! Giver ingen bonusser. Januar 3015 Abonnentting.",
|
||||
"headMystery301405Text": "Simpel Tophat",
|
||||
|
||||
@@ -273,5 +273,7 @@
|
||||
"emptyMessagesLine1": "You don't have any messages",
|
||||
"emptyMessagesLine2": "Send a message to start a conversation!",
|
||||
"letsgo": "Let's Go!",
|
||||
"selected": "Selected"
|
||||
"selected": "Selected",
|
||||
"howManyToBuy": "How many would you like to buy?",
|
||||
"habiticaHasUpdated": "There is a new Habitica update. Refresh to get the latest version!"
|
||||
}
|
||||
@@ -536,7 +536,7 @@
|
||||
"questLostMasterclasser3DropZombiePotion": "Zombie Hatching Potion",
|
||||
"questLostMasterclasser4Text": "The Mystery of the Masterclassers, Part 4: The Lost Masterclasser",
|
||||
"questLostMasterclasser4Notes": "You surface from the portal, but you’re still suspended in a strange, shifting netherworld. “That was bold,” says a cold voice. “I have to admit, I hadn’t planned for a direct confrontation yet.” A woman rises from the churning whirlpool of darkness. “Welcome to the Realm of Void.”<br><br>You try to fight back your rising nausea. “Are you Zinnya?” you ask.<br><br>“That old name for a young idealist,” she says, mouth twisting, and the world writhes beneath you. “No. If anything, you should call me the Anti’zinnya now, given all that I have done and undone.”<br><br>Suddenly, the portal reopens behind you, and as the four Masterclassers burst out, bolting towards you, Anti’zinnya’s eyes flash with hatred. “I see that my pathetic replacements have managed to follow you.”<br><br>You stare. “Replacements?”<br><br>“As the Master Aethermancer, I was the first Masterclasser — the only Masterclasser. These four are a mockery, each possessing only a fragment of what I once had! I commanded every spell and learned every skill. I shaped your very world to my whim — until the traitorous aether itself collapsed under the weight of my talents and my perfectly reasonable expectations. I have been trapped for millennia in this resulting void, recuperating. Imagine my disgust when I learned how my legacy had been corrupted.” She lets out a low, echoing laugh. “My plan was to destroy their domains before destroying them, but I suppose the order is irrelevant.” With a burst of uncanny strength, she charges forward, and the Realm of Void explodes into chaos.",
|
||||
"questLostMasterclasser4Completion": "Under the onslaught of your final attack, the Lost Masterclasser screams in frustration, her body flickering into translucence. The thrashing void stills around her as she slumps forward, and for a moment, she seems to change, becoming younger, calmer, with an expression of peace upon her face… but then everything melts away with scarcely a whisper, and you’re kneeling once more in the desert sand.<br><br>“It seems that we have much to learn about our own history,” King Manta says, staring at the broken ruins. “After the Master Aethermancer grew overwhelmed and lost control of her abilities, the outpouring of void must have leached the life from the entire land. Everything probably became deserts like this.”<br><br>“No wonder the ancients who founded Habitica stressed a balance of productivity and wellness,” the Joyful Reaper murmurs. “Rebuilding their world would have been a daunting task requiring considerable hard work, but they would have wanted to prevent such a catastrophe from happening again.”<br><br>“Oho, look at those formerly possessed items!” says the April Fool. Sure enough, all of them shimmer with a pale, glimmering translucence from the final burst of aether released when you laid Anti’zinnya’s spirit to rest. “What a dazzling effect. I must take notes.”<br><br>“The concentrated remnants of aether in this area probably caused caused these animals to go invisible, too,” says Lady Glaciate, scratching a patch of emptiness behind the ears. You feel an unseen fluffy head nudge your hand, and suspect that you’ll have to do some explaining at the Stables back home. As you look at the ruins one last time, you spot all that remains of the first Masterclasser: her shimmering cloak. Lifting it onto your shoulders, you head back to Habit City, pondering everything that you have learned.<br><br>",
|
||||
"questLostMasterclasser4Completion": "Under the onslaught of your final attack, the Lost Masterclasser screams in frustration, her body flickering into translucence. The thrashing void stills around her as she slumps forward, and for a moment, she seems to change, becoming younger, calmer, with an expression of peace upon her face… but then everything melts away with scarcely a whisper, and you’re kneeling once more in the desert sand.<br><br>“It seems that we have much to learn about our own history,” King Manta says, staring at the broken ruins. “After the Master Aethermancer grew overwhelmed and lost control of her abilities, the outpouring of void must have leached the life from the entire land. Everything probably became deserts like this.”<br><br>“No wonder the ancients who founded Habitica stressed a balance of productivity and wellness,” the Joyful Reaper murmurs. “Rebuilding their world would have been a daunting task requiring considerable hard work, but they would have wanted to prevent such a catastrophe from happening again.”<br><br>“Oho, look at those formerly possessed items!” says the April Fool. Sure enough, all of them shimmer with a pale, glimmering translucence from the final burst of aether released when you laid Anti’zinnya’s spirit to rest. “What a dazzling effect. I must take notes.”<br><br>“The concentrated remnants of aether in this area probably caused these animals to go invisible, too,” says Lady Glaciate, scratching a patch of emptiness behind the ears. You feel an unseen fluffy head nudge your hand, and suspect that you’ll have to do some explaining at the Stables back home. As you look at the ruins one last time, you spot all that remains of the first Masterclasser: her shimmering cloak. Lifting it onto your shoulders, you head back to Habit City, pondering everything that you have learned.<br><br>",
|
||||
"questLostMasterclasser4Boss": "Anti'zinnya",
|
||||
"questLostMasterclasser4RageTitle": "Siphoning Void",
|
||||
"questLostMasterclasser4RageDescription": "Siphoning Void: This bar fills when you don't complete your Dailies. When it is full, Anti'zinnya will remove the party's Mana!",
|
||||
|
||||
@@ -72,6 +72,8 @@
|
||||
"APIv3": "API v3",
|
||||
"APIText": "Kopiér disse til brug i tredjeparts-applikationer. Dog skal du tænke på din API Nøgle som et kodeord, og lade være med at dele den offentligt. Du kan nogen gange blive bedt om dit Bruger ID, men skriv aldrig din API Nøgle hvor andre kan se den, heller ikke på Github.",
|
||||
"APIToken": "API Nøgle (det er et kodeord - se advarsel ovenfor!)",
|
||||
"showAPIToken": "Show API Token",
|
||||
"hideAPIToken": "Hide API Token",
|
||||
"APITokenWarning": "Hvis du har brug for en ny API Nøgle (f.eks. hvis du har delt den ved et uheld), så send en email til <%= hrefTechAssistanceEmail %> med dit Bruger ID og din nuværende Nøgle. Når den er nulstillet skal du godkende alt på ny ved at logge ud af websted og mobil-app og forsyne alle dine andre Habitica-værktøjer med den nye nøgl.e",
|
||||
"thirdPartyApps": "Tredjeparts-Apps",
|
||||
"dataToolDesc": "En side som viser dig visse oplysninger om din Habitica bruger, såsom statistisk omkring dine opgaver, udstyr og evner.",
|
||||
|
||||
@@ -134,6 +134,7 @@
|
||||
"mysterySet201707": "Jellymancer Set",
|
||||
"mysterySet201708": "Lava Warrior Set",
|
||||
"mysterySet201709": "Sorcery Student Set",
|
||||
"mysterySet201710": "Imperious Imp Set",
|
||||
"mysterySet301404": "Steampunk Standardsæt",
|
||||
"mysterySet301405": "Steampunk Tilbehørssæt",
|
||||
"mysterySet301703": "Påfugle-Steampunk-sæt",
|
||||
@@ -201,5 +202,6 @@
|
||||
"subscriptionAlreadySubscribed1": "To see your subscription details and cancel, renew, or change your subscription, please go to <a href='/user/settings/subscription'>User icon > Settings > Subscription</a>.",
|
||||
"purchaseAll": "Purchase All",
|
||||
"gemsPurchaseNote": "Subscribers can buy gems for gold in the Market! For easy access, you can also pin the gem to your Rewards column.",
|
||||
"gemsRemaining": "gems remaining"
|
||||
"gemsRemaining": "gems remaining",
|
||||
"notEnoughGemsToBuy": "You are unable to buy that amount of gems"
|
||||
}
|
||||
@@ -3,8 +3,8 @@
|
||||
"profile": "Profil",
|
||||
"avatar": "Avatar anpassen",
|
||||
"editAvatar": "Avatar bearbeiten",
|
||||
"noDescription": "This Habitican hasn't added a description.",
|
||||
"noPhoto": "This Habitican hasn't added a photo.",
|
||||
"noDescription": "Dieser Habiticaner hat noch keine Beschreibung hinzugefügt.",
|
||||
"noPhoto": "Dieser Habiticaner hat noch kein Foto hinzugefügt.",
|
||||
"other": "Anderes",
|
||||
"fullName": "Name",
|
||||
"displayName": "Angezeigter Name",
|
||||
|
||||
@@ -239,9 +239,9 @@
|
||||
"weaponSpecialFall2017WarriorText": "Zuckermaislanze",
|
||||
"weaponSpecialFall2017WarriorNotes": "All deine Gegner werden vor dieser lecker aussehenden Lanze flüchten, egal ob es Geister, Monster oder rote To-Dos sind. Erhöht Stärke um <%= str %>. Limitierte Ausgabe 2017 Herbstausrüstung.",
|
||||
"weaponSpecialFall2017MageText": "Gruseliger Stab",
|
||||
"weaponSpecialFall2017MageNotes": "Die Augen des leuchtenden Schädels auf diesem Stab strahlen Magie und Rätselhaftigkeit aus. Erhöht Intelligenz um <%= int %> und Wahrnehmung um <%= per %>. Limitierte Ausgabe 2017 Herbstausrüstung.",
|
||||
"weaponSpecialFall2017HealerText": "Unheimliche Kandelaber",
|
||||
"weaponSpecialFall2017HealerNotes": "Das Licht vertreibt Angst und zeigt anderen, dass du hier bist um zu helfen. Erhöht Intelligenz um <%= int %>. Limitierte Ausgabe 2017 Herbstausrüstung.",
|
||||
"weaponSpecialFall2017MageNotes": "Die Augen des leuchtenden Schädels auf diesem Stab strahlen vor Magie und Geheimnissen. Erhöht Intelligenz um <%= int %> und Wahrnehmung um <%= per %>. Limitierte Ausgabe 2017 Herbstausrüstung.",
|
||||
"weaponSpecialFall2017HealerText": "Gruseliger Kandelaber",
|
||||
"weaponSpecialFall2017HealerNotes": "Das Licht vertreibt Angst und zeigt anderen, dass Du hier bist um zu helfen. Erhöht Intelligenz um <%= int %>. Limitierte Ausgabe 2017 Herbstausrüstung.",
|
||||
"weaponMystery201411Text": "Forke des Feierns",
|
||||
"weaponMystery201411Notes": "Erstich Deine Feinde oder verschling Dein Lieblingsessen - diese flexible Forke ist universell einsetzbar! Gewährt keinen Attributbonus. Abonnentengegenstand, November 2014.",
|
||||
"weaponMystery201502Text": "Schimmernder Flügelstab der Liebe und auch der Wahrheit",
|
||||
@@ -518,10 +518,10 @@
|
||||
"armorSpecialFall2017RogueNotes": "Du musst dich verstecken? Hocke dich inzwischen der Jack-O’Lanterns hin und dieses Gewand wird dich verbergen! Erhöht Wahrnehmung um <%= per %>. Limitierte Ausgabe 2017 Herbstausrüstung.",
|
||||
"armorSpecialFall2017WarriorText": "Starke und Süße Rüstung",
|
||||
"armorSpecialFall2017WarriorNotes": "Diese Rüstung wird dich wie eine leckere Bonbon-Hülle schützen. Erhöht Ausdauer um <%= con %>. Limitierte Ausgabe 2017 Herbstausrüstung.",
|
||||
"armorSpecialFall2017MageText": "Maskerade Roben",
|
||||
"armorSpecialFall2017MageNotes": "Welches Maskeraden-Komplet wäre schon vollständig ohne des dramatischen und langen Gewandes? Erhöht Intelligenz um <%= int %>. Limitierte Ausgabe 2017 Herbstausrüstung.",
|
||||
"armorSpecialFall2017MageText": "Maskerade-Robe",
|
||||
"armorSpecialFall2017MageNotes": "Welches Maskerade-Ensemble wäre schon komplett ohne eine dramatisch schwingende Robe? Erhöht Intelligenz um <%= int %>. Limitierte Ausgabe 2017 Herbstausrüstung.",
|
||||
"armorSpecialFall2017HealerText": "Spukhaus-Rüstung",
|
||||
"armorSpecialFall2017HealerNotes": "Dein Herz ist eine offene Tür. Und deine Schultern sind Dachziegeln! Erhöht Ausdauer um <%= con %>. Limitierte Ausgabe 2017 Herbstausrüstung.",
|
||||
"armorSpecialFall2017HealerNotes": "Dein Herz ist eine offene Tür. Und Deine Schultern sind Dachziegeln! Erhöht Ausdauer um <%= con %>. Limitierte Ausgabe 2017 Herbstausrüstung.",
|
||||
"armorMystery201402Text": "Robe des Nachrichtenbringers",
|
||||
"armorMystery201402Notes": "Schimmernd, stabil und mit vielen Taschen für Briefe. Gewährt keinen Attributbonus. Abonnentengegenstand, Februar 2014.",
|
||||
"armorMystery201403Text": "Waldwanderer-Rüstung",
|
||||
@@ -578,6 +578,8 @@
|
||||
"armorMystery201704Notes": "Feen haben diese Rüstung aus Morgentau gefertigt, um die Farben des Sonnenaufgangs einzufangen. Gewährt keinen Attributbonus. Abonnentengegenstand, April 2017.",
|
||||
"armorMystery201707Text": "Quallenzauberer-Rüstung",
|
||||
"armorMystery201707Notes": "Mit dieser Rüstung kannst Du Dich unter die Kreaturen des Ozeans mischen, während Du Unterwasser-Quests und Abenteuern nachschwimmst. Abonnentengegenstand, Juli 2017.",
|
||||
"armorMystery201710Text": "Imperious Imp Apparel",
|
||||
"armorMystery201710Notes": "Scaly, shiny, and strong! Confers no benefit. October 2017 Subscriber Item.",
|
||||
"armorMystery301404Text": "Steampunkanzug",
|
||||
"armorMystery301404Notes": "Adrett und schneidig, hoho! Gewährt keinen Attributbonus. Abonnentengegenstand, Februar 3015.",
|
||||
"armorMystery301703Text": "Steampunk-Pfauen-Robe",
|
||||
@@ -861,11 +863,11 @@
|
||||
"headSpecialFall2017RogueText": "Jack-o-Lantern-Helm",
|
||||
"headSpecialFall2017RogueNotes": "Bereit für Süßes? Es wird Zeit diesen festlichen, glühenden Helm aufzusetzen! Erhöht Wahrnehmung um <%= per %>. Limitierte Ausgabe 2017 Herbstausrüstung.",
|
||||
"headSpecialFall2017WarriorText": "Zuckermaishelm",
|
||||
"headSpecialFall2017WarriorNotes": "Dieser Helm mag aussehen wie eine Leckerei, jedoch werden launische Aufgaben ihn nicht so süß finden! Erhöht Stärke um <%= str %>. Limitierte Ausgabe 2017 Herbstausrüstung.. ",
|
||||
"headSpecialFall2017MageText": "Maskeradenhelm",
|
||||
"headSpecialFall2017WarriorNotes": "Dieser Helm mag wie eine Leckerei aussehen, jedoch werden launische Aufgaben ihn nicht so süß finden! Erhöht Stärke um <%= str %>. Limitierte Ausgabe 2017 Herbstausrüstung.",
|
||||
"headSpecialFall2017MageText": "Maskerade-Helm",
|
||||
"headSpecialFall2017MageNotes": "Wenn du mit diesem federigen Kopfschmuck erscheinst, wird jeder über die Identität des zauberhaften Unbekannten im Raum rätseln! Erhöht Wahrnehmung um <%= per %>. Limitierte Ausgabe 2017 Herbstausrüstung.",
|
||||
"headSpecialFall2017HealerText": "Spukhaus-Helm",
|
||||
"headSpecialFall2017HealerNotes": "Lade spukende Geister und gutgesinnte Kreaturen dazu ein deine heilenden Kräfte in diesem Helm aufzusuchen! Erhöht Intelligenz um <%= int %>. Limitierte Ausgabe 2017 Herbstausrüstung.",
|
||||
"headSpecialFall2017HealerNotes": "Lade spukende Geister und gutgesinnte Kreaturen dazu ein Deine heilenden Kräfte in diesem Helm aufzusuchen! Erhöht Intelligenz um <%= int %>. Limitierte Ausgabe 2017 Herbstausrüstung.",
|
||||
"headSpecialGaymerxText": "Regenbogenkriegerhelm",
|
||||
"headSpecialGaymerxNotes": "Zur Feier der GaymerX-Konferenz ist dieser spezielle Helm dekoriert mit einem strahlenden, farbenfrohen Regenbogenmuster! GaymerX ist eine Videospiel-Tagung, die LGBTQ und Videospiele feiert und für alle offen ist.",
|
||||
"headMystery201402Text": "Geflügelter Helm",
|
||||
@@ -926,6 +928,8 @@
|
||||
"headMystery201705Notes": "Habitica ist bekannt für seine wilden und produktiven Greifen-Krieger! Reihe Dich ein in in ihre angesehenen Ränge indem Du diesen gefiederten Helm aufsetzt. Gewährt keinen Attributbonus. Abonnentengegenstand, Mai 2017.",
|
||||
"headMystery201707Text": "Quallenschirmhut",
|
||||
"headMystery201707Notes": "Brauchst Du ein paar extra Hände für Deine Aufgaben? Dieser durchscheinende Quallenschirm hat ein paar Tentakeln, die Dir helfen! Gewährt keinen Attributbonus. Abonnentengegenstand, Juli 2017.",
|
||||
"headMystery201710Text": "Imperious Imp Helm",
|
||||
"headMystery201710Notes": "This helm makes you look intimidating... but it won't do any favors for your depth perception! Confers no benefit. October 2017 Subscriber Item.",
|
||||
"headMystery301404Text": "Schicker Zylinder",
|
||||
"headMystery301404Notes": "Ein schicker Zylinder für die feinsten Ehrenleute! Gewährt keinen Attributbonus. Abonnentengegenstand, Januar 3015.",
|
||||
"headMystery301405Text": "Einfacher Zylinder",
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
"subscriberItemText": "Abonnenten bekommen jeden Monat einen Überraschungsgegenstand. Dieser wird üblicherweise ungefähr eine Woche vor Monatsende herausgegeben. Schaue auf der 'Überraschungsgegenstand'-Seite des Wikis für mehr Informationen nach.",
|
||||
"all": "Alle",
|
||||
"none": "Keine",
|
||||
"more": "<%= count %> more",
|
||||
"more": "<%= count %> mehr",
|
||||
"and": "und",
|
||||
"loginSuccess": "Anmeldung erfolgreich!",
|
||||
"youSure": "Bist Du sicher?",
|
||||
@@ -273,5 +273,7 @@
|
||||
"emptyMessagesLine1": "Du hast im Moment keine Nachrichten",
|
||||
"emptyMessagesLine2": "Beginne eine Unterhaltung, indem Du eine Nachricht verschickst!",
|
||||
"letsgo": "Auf geht's!",
|
||||
"selected": "Ausgewählt"
|
||||
"selected": "Ausgewählt",
|
||||
"howManyToBuy": "Wie viele möchtest Du kaufen?",
|
||||
"habiticaHasUpdated": "There is a new Habitica update. Refresh to get the latest version!"
|
||||
}
|
||||
@@ -141,7 +141,7 @@
|
||||
"report": "Melden",
|
||||
"abuseFlag": "Verletzung der Community-Richtlinien melden",
|
||||
"abuseFlagModalHeading": "<%= name %> melden?",
|
||||
"abuseFlagModalBody": "Are you sure you want to report this post? You should ONLY report a post that violates the <%= firstLinkStart %>Community Guidelines<%= linkEnd %> and/or <%= secondLinkStart %>Terms of Service<%= linkEnd %>. Inappropriately reporting a post is a violation of the Community Guidelines and may give you an infraction. Appropriate reasons to flag a post include but are not limited to:<br><br><ul style='margin-left: 10px;'><li>swearing, religious oaths</li><li>bigotry, slurs</li><li>adult topics</li><li>violence, including as a joke</li><li>spam, nonsensical messages</li></ul>",
|
||||
"abuseFlagModalBody": "Möchtest Du diesen Beitrag wirklich melden? Du solltest AUSSCHLIESSLICH Beiträge melden, die unsere <%= firstLinkStart %>Community-Richtlinien<%= linkEnd %> und/oder unsere <%= secondLinkStart %>Nutzungsbedingungen<%= linkEnd %> verletzen. Das ungerechtfertigte Melden von Beiträgen stellt eine Verletzung der Community-Richtlinien dar und kann geahndet werden. Gute Gründe einen Beitrag zu melden sind unter anderem: <br><br><ul style='margin-left: 10px;'><li>Fluchen, Religiöse Schwüre</li><li>Intoleranz, herabwürdigende Bezeichnung jeglicher Ethnien</li><li>Nicht jugendfreie Themen</li><li>Gewalt, auch innerhalb eines Witzes</li><li>Spam, unsinnige Nachrichten</li></ul>.",
|
||||
"abuseFlagModalButton": "Verstoß melden",
|
||||
"abuseReported": "Danke, dass Du diesen Verstoß gemeldet hast. Die Moderatoren wurden benachrichtigt.",
|
||||
"abuseAlreadyReported": "Du hast diese Nachricht bereits gemeldet.",
|
||||
@@ -352,21 +352,21 @@
|
||||
"privateGuild": "Private Gilde",
|
||||
"charactersRemaining": "verbleibende Zeichen",
|
||||
"guildSummary": "Zusammenfassung",
|
||||
"guildSummaryPlaceholder": "Write a short description advertising your Guild to other Habiticans. What is the main purpose of your Guild and why should people join it? Try to include useful keywords in the summary so that Habiticans can easily find it when they search!",
|
||||
"guildSummaryPlaceholder": "Schreibe eine Kurzbeschreibung um Deine Gilde anderen Habiticanern bekannt zu machen. Was ist der Hauptzweck der Gilde und warum sollten Leute dem ihr beitreten? Verwende hilfreiche Schlüsselwörter in der Beschreibung, um die Suche für andere Habiticaner zu erleichtern!",
|
||||
"groupDescription": "Beschreibung",
|
||||
"guildDescriptionPlaceholder": "Use this section to go into more detail about everything that Guild members should know about your Guild. Useful tips, helpful links, and encouraging statements all go here!",
|
||||
"guildDescriptionPlaceholder": "Nutze diesen Abschnitt um alles, was Mitglieder der Gilde über Deine Gilde wissen sollten, ausführlicher darzustellen. Nützliche Tipps, hilfreiche Links und ermutigende Worte gehören hier hin!",
|
||||
"markdownFormattingHelp": "[Markdown formatting help](http://habitica.wikia.com/wiki/Markdown_Cheat_Sheet)",
|
||||
"partyDescriptionPlaceholder": "This is our party's description. It describes what we do in this party. If you want to learn more about what we do in this party, read the description. Party on.",
|
||||
"guildGemCostInfo": "A Gem cost promotes high quality Guilds and is transferred into your Guild's bank.",
|
||||
"noGuildsTitle": "Du bist nicht Mitglied einer Gilde.",
|
||||
"noGuildsParagraph1": "Guilds are social groups created by other players that can offer you support, accountability, and encouraging chat.",
|
||||
"noGuildsParagraph2": "Click the Discover tab to see recommended Guilds based on your interests, browse Habitica's public Guilds, or create your own Guild.",
|
||||
"privateDescription": "A private Guild will not be displayed in Habitica's Guild directory. New members can be added by invitation only.",
|
||||
"privateDescription": "Private Gilden werden nicht in Habiticas Gildenübersicht angezeigt. Neue Mitglieder können nur durch eine Einladung hinzugefügt werden.",
|
||||
"removeMember": "Mitglied Entfernen",
|
||||
"sendMessage": "Nachricht Senden",
|
||||
"removeManager2": "Manager entfernen",
|
||||
"promoteToLeader": "Zum Leiter Befördern",
|
||||
"inviteFriendsParty": "Inviting friends to your party will grant you an exclusive <br/> Quest Scroll to battle the Basi-List together!",
|
||||
"inviteFriendsParty": "Wenn Du Freunde in Deine Gruppe einlädst, erhältst Du eine exklusive <br/>Questschriftrolle, mit der Ihr gemeinsam den Basi-List bekämpfen könnt!",
|
||||
"upgradeParty": "Upgrade die Gruppe",
|
||||
"createParty": "Erstelle eine Gruppe",
|
||||
"inviteMembersNow": "Möchtest Du jetzt Mitglieder einladen?",
|
||||
@@ -379,7 +379,7 @@
|
||||
"wantToJoinPartyDescription": "Gib Deine User-ID einem Freund, der bereits eine Gruppe hat oder gehe zur Gilde \"Party wanted\", um potenzielle Verbündete zu finden. ",
|
||||
"copy": "Kopieren",
|
||||
"inviteToPartyOrQuest": "Gruppe zur Quest einladen",
|
||||
"inviteInformation": "Clicking \"Invite\" will send an invitation to your party members. When all members have accepted or denied, the Quest begins.",
|
||||
"inviteInformation": "Indem Du auf \"Einladen\" klickst, sendest Du eine Einladung an Deine Gruppenmitglieder. Sobald alle Mitglieder diese angenommen oder abgelehnt haben, beginnt das Quest.",
|
||||
"questOwnerRewards": "Belohnungen für Besitzer der Quest",
|
||||
"updateParty": "Gruppe Aktualisieren",
|
||||
"upgrade": "Upgrade",
|
||||
@@ -394,7 +394,7 @@
|
||||
"groupTaskBoard": "Aufgabenliste",
|
||||
"groupInformation": "Team Informationen",
|
||||
"groupBilling": "Team Abrechnung",
|
||||
"wouldYouParticipate": "Would you like to participate?",
|
||||
"managerAdded": "Manager added successfully",
|
||||
"managerRemoved": "Manager removed successfully"
|
||||
"wouldYouParticipate": "Möchtest du gern teilnehmen?",
|
||||
"managerAdded": "Manager erfolgreich hinzugefügt",
|
||||
"managerRemoved": "Manager erfolgreich entfernt"
|
||||
}
|
||||
@@ -108,10 +108,10 @@
|
||||
"summer2017WhirlpoolMageSet": "Whirlpool-Magier (Magier)",
|
||||
"summer2017SeashellSeahealerSet": "Muschel-Meeresheiler (Heiler)",
|
||||
"summer2017SeaDragonSet": "Seedrache (Schurke)",
|
||||
"fall2017HabitoweenSet": "Habitoween Krieger",
|
||||
"fall2017MasqueradeSet": "Maskerade Magier",
|
||||
"fall2017HauntedHouseSet": "Geisterhaus Heiler",
|
||||
"fall2017TrickOrTreatSet": "Süßes-oder-Saures Schurke",
|
||||
"fall2017HabitoweenSet": "Habitoween-Krieger (Krieger)",
|
||||
"fall2017MasqueradeSet": "Maskerade-Magier (Magier)",
|
||||
"fall2017HauntedHouseSet": "Geisterhaus-Heiler (Heiler)",
|
||||
"fall2017TrickOrTreatSet": "Süßes-oder-Saures-Schurke (Schurke)",
|
||||
"eventAvailability": "Zum Kauf verfügbar bis zum <%= date(locale) %>.",
|
||||
"dateEndApril": "19. April",
|
||||
"dateEndMay": "17. Mai",
|
||||
|
||||
@@ -57,5 +57,5 @@
|
||||
"messageUserOperationNotFound": "<%= operation %> Operation nicht gefunden",
|
||||
"messageNotificationNotFound": "Mitteilung nicht gefunden.",
|
||||
"notificationsRequired": "Mitteilungs-IDs werden benötigt.",
|
||||
"beginningOfConversation": "This is the beginning of your conversation with <%= userName %>. Remember to be kind, respectful, and follow the Community Guidelines!"
|
||||
"beginningOfConversation": "Dies ist der Anfang Deiner Unterhaltung mit<%= userName %>. Denke an einen freundlichen und respektvollen Umgang und halte Dich an die Community-Richtlinien!"
|
||||
}
|
||||
@@ -62,8 +62,8 @@
|
||||
"shops": "Märkte",
|
||||
"custom": "Eigene",
|
||||
"wishlist": "Wunschliste",
|
||||
"wrongItemType": "The item type \"<%= type %>\" is not valid.",
|
||||
"wrongItemPath": "The item path \"<%= path %>\" is not valid.",
|
||||
"wrongItemType": "Der Gegenstandstyp \"<%= type %>\" ist nicht gültig.",
|
||||
"wrongItemPath": "Der Gegenstandsweg \"<%= path %>\" ist nicht gültig.",
|
||||
"unpinnedItem": "Du hast <%= item %> von Deiner Pinnwand entfernt! Es wird nicht mehr in Deinen Belohnungen angezeigt werden.",
|
||||
"cannotUnpinArmoirPotion": "Der Heiltrank und der Verzauberte Schrank können nicht von von der Pinnwand entfernt werden",
|
||||
"purchasedItem": "Du hast <%= itemName %> gekauft",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"needTips": "Brauchst Du ein paar Tipps, wie man anfängt? Hier findest Du eine einfache Anleitung!",
|
||||
|
||||
"step1": "Schritt 1: Füge Aufgaben hinzu",
|
||||
"webStep1Text": "Habitica is nothing without real-world goals, so enter a few tasks. You can add more later as you think of them! All tasks can be added by clicking the green \"Create\" button.\n* **Set up [To-Dos](http://habitica.wikia.com/wiki/To-Dos):** Enter tasks you do once or rarely in the To-Dos column, one at a time. You can click on the tasks to edit them and add checklists, due dates, and more!\n* **Set up [Dailies](http://habitica.wikia.com/wiki/Dailies):** Enter activities you need to do daily or on a particular day of the week, month, or year in the Dailies column. Click task to edit when it will be due and/or set a start date. You can also make it due on a repeating basis, for example, every 3 days.\n* **Set up [Habits](http://habitica.wikia.com/wiki/Habits):** Enter habits you want to establish in the Habits column. You can edit the Habit to change it to just a good habit :heavy_plus_sign: or a bad habit :heavy_minus_sign:\n* **Set up [Rewards](http://habitica.wikia.com/wiki/Rewards):** In addition to the in-game Rewards offered, add activities or treats which you want to use as a motivation to the Rewards column. It's important to give yourself a break or allow some indulgence in moderation!\n* If you need inspiration for which tasks to add, you can look at the wiki's pages on [Sample Habits](http://habitica.wikia.com/wiki/Sample_Habits), [Sample Dailies](http://habitica.wikia.com/wiki/Sample_Dailies), [Sample To-Dos](http://habitica.wikia.com/wiki/Sample_To-Dos), and [Sample Rewards](http://habitica.wikia.com/wiki/Sample_Custom_Rewards).",
|
||||
"webStep1Text": "Habitica funktioniert nur mit Aufgaben und Zielen aus deinem realen Leben, also erstelle ein paar Aufgaben. Du kannst später weitere hinzufügen, wenn sie dir einfallen. Alle Aufgaben können hinzugefügt werden, indem du die grüne \"Aufgabe hinzufügen\" Schaltfläche auswählst.\n* **Set up [To-Dos](http://habitica.wikia.com/wiki/To-Dos):** Füge einmalige oder seltene Aufgaben einzeln in der Spalte \"To-Dos\" hinzu. Wenn du auf diese Aufgabe klickst, kannst du die Aufgabe anpassen und zum Beispiel ein Fälligkeitsdatum oder eine Checkliste hinzufügen.\n* **Set up [Dailies](http://habitica.wikia.com/wiki/Dailies):** Füge Aufgaben die täglich, oder an einem bestimmten Tag in der Woche, im Monat, oder im Jahr anfallen in der Spalte \"Tägliche Aufgaben\" hinzu. Klicke auf die Aufgabe um anzupassen an welchen Wochentagen sie fällig sind. Alternativ kannst du auch eine periodische Fälligkeit einstellen, z.B. alle 3 Tage. \n* **Set up [Habits](http://habitica.wikia.com/wiki/Habits):** Füge Gewohnheiten in der Spalte \"Gewohnheiten\" hinzu. Du kannst einstellen, ob es sich um eine gute Gewohnheit :heavy_plus_sign: oder eine schlechte Angewohnheit :heavy_minus_sign: handelt.\n* **Set up [Rewards](http://habitica.wikia.com/wiki/Rewards):** Zusätzlich zu den Belohnungen die das Spiel dir gibt, kannst du in der Spalte \"Belohnungen\" eigene Aktivitäten oder Vergnügen eintragen, die dich motivieren. Es ist wichtig, dass du dir auch hin und wieder eine Pause, oder etwas Luxus gönnst! \n*Falls du Anregungen brauchst welche Aufgaben du hinzufügen solltest, schau auf die Wiki-Seiten unter [Sample Habits](http://habitica.wikia.com/wiki/Sample_Habits), [Sample Dailies](http://habitica.wikia.com/wiki/Sample_Dailies), [Sample To-Dos](http://habitica.wikia.com/wiki/Sample_To-Dos), und [Sample Rewards](http://habitica.wikia.com/wiki/Sample_Custom_Rewards).",
|
||||
|
||||
"step2": "Schritt 2: Sammel Punkte indem du im wirklichen Leben Dinge erledigst",
|
||||
"webStep2Text": "Fange nun damit an, Ziele von Deiner Liste anzugehen! Indem Du Aufgaben erledigst und in Habitica abhakst, erhältst Du [Erfahrung](http://de.habitica.wikia.com/wiki/Erfahrungspunkte), die Dich Level aufsteigen lässt, und [Gold](http://de.habitica.wikia.com/wiki/Goldpunkte), das es Dir ermöglicht, Belohnungen zu erwerben. Wenn Du schlechten Gewohnheiten verfällst oder Tägliche Aufgaben verpasst, verlierst Du [Lebenspunkte](http://de.habitica.wikia.com/wiki/Lebenspunkte). Auf diese Weise dienen die Habitica Erfahrungs- und Lebenspunkt-Leiste als unterhaltsame Anzeige des Fortschritts hin zu Deinen Zielen. Dein echtes Leben wird sich sichtbar verbessern, während Dein Charakter im Spiel vorankommt.",
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
"phoenix": "Phönix",
|
||||
"magicalBee": "Magische Biene",
|
||||
"royalPurpleJackalope": "Königlicher purpurfarbener Wolpertinger",
|
||||
"invisibleAether": "Invisible Aether",
|
||||
"invisibleAether": "Unsichtbarer Äther",
|
||||
"rarePetPop1": "Klicke auf den goldenen Pfotenabdruck, um zu sehen, wie Du diese seltenen Haustiere erhalten kannst, indem Du bei Habitica mitwirkst!",
|
||||
"rarePetPop2": "Wie erhält man dieses Haustier?",
|
||||
"potion": "<%= potionType %> Elixier",
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"goldQuests": "Masterclasser Quest Lines",
|
||||
"questDetails": "Quest-Details",
|
||||
"questDetailsTitle": "Quest-Details",
|
||||
"questDescription": "Quests allow players to focus on long-term, in-game goals with the members of their party.",
|
||||
"questDescription": "Quests erlauben es Spielern, sich gemeinsam mit den Gruppenmitgliedern auf Langzeit-Ziele im Spiel zu konzentrieren. ",
|
||||
"invitations": "Einladungen",
|
||||
"completed": "abgeschlossen!",
|
||||
"rewardsAllParticipants": "Belohnungen für alle Questteilnehmer",
|
||||
@@ -21,15 +21,15 @@
|
||||
"dropQuestCongrats": "Gratulation zum Erwerb dieser Questschriftrolle! Du kannst nun Deine Gruppe dazu einladen die Quest zu starten oder Du kommst irgendwann darauf zurück unter Inventar > Quests.",
|
||||
"questSend": "Indem Du auf \"Einladen\" klickst sendest Du eine Einladung an Deine Gruppenmitglieder. Sobald alle Mitglieder diese angenommen oder abgelehnt haben beginnt die Quest. Der Status ist unter Soziales > Gruppe zu finden.",
|
||||
"questSendBroken": "Indem Du auf \"Einladen\" klickst, sendest Du eine Einladung an Deine Gruppenmitglieder ... Sobald alle Mitglieder diese angenommen oder abgelehnt haben beginnt die Quest ... Der Status ist unter Soziales > Gruppe zu finden ...",
|
||||
"inviteParty": "Lade Gruppe zur Quest ein",
|
||||
"inviteParty": "Lade Gruppe zum Quest ein",
|
||||
"questInvitation": "Quest-Einladung:",
|
||||
"questInvitationTitle": "Quest-Einladung",
|
||||
"questInvitationInfo": "Einladung zur Quest <%= quest %>",
|
||||
"questInvitationInfo": "Einladung zum Quest <%= quest %>",
|
||||
"askLater": "Später fragen",
|
||||
"questLater": "Quest später starten",
|
||||
"buyQuest": "Quest kaufen",
|
||||
"accepted": "Angenommen",
|
||||
"declined": "Declined",
|
||||
"declined": "Abgelehnt",
|
||||
"rejected": "Abgelehnt",
|
||||
"pending": "Ausstehend",
|
||||
"questStart": "Sobald alle Mitglieder die Einladung entweder angenommen oder abgelehnt haben, beginnt die Quest. Nur diejenigen, die die Einladung \"angenommen\" haben, können an der Quest teilnehmen und die Belohnungen kassieren. Wenn Mitglieder zu lange überlegen (inaktiv?), kannst Du die Quest ohne sie starten, indem Du auf \"Beginnen\" klickst. Der Quest-Besitzer kann die Quest auch abbrechen und die Questrolle zurückerhalten, indem er \"Abbrechen\" klickt.",
|
||||
@@ -77,7 +77,7 @@
|
||||
"mustLevel": "Du musst Level <%= level %> haben, um diese Quest zu starten.",
|
||||
"mustLvlQuest": "Du musst Level <%= level %> sein um dieses Quest zu erwerben!",
|
||||
"mustInviteFriend": "Um diese Quest freizuschalten musst Du einen Freund in Deine Gruppe einladen. Willst Du jetzt jemanden einladen?",
|
||||
"unlockByQuesting": "To unlock this quest, complete <%= title %>.",
|
||||
"unlockByQuesting": "Um dieses Quest freizuschalten musst Du erst <%= title %> abschließen.",
|
||||
"sureCancel": "Bist Du sicher, dass Du diese Quest abbrechen willst? Alle akzeptierten Einladungen werden verloren gehen. Der Quest-Besitzer wird die Questschriftrolle zurück bekommen.",
|
||||
"sureAbort": "Bist Du sicher, dass Du diese Mission abbrechen willst? Das wird sie für alle in Deiner Gruppe abbrechen und jeder Fortschritt wird verloren gehen. Die Questschriftrolle wird dem Quest-Besitzer zurückgegeben.",
|
||||
"doubleSureAbort": "Bist Du wirklich, wirklich sicher? Sei ganz sicher, dass sie Dich nicht für immer hassen werden!",
|
||||
@@ -112,11 +112,11 @@
|
||||
"questNotPending": "Es ist keine Quest zum Start vorhanden.",
|
||||
"questOrGroupLeaderOnlyStartQuest": "Nur der Quest- oder Gruppen-Leiter kann den Quest-Start erzwingen",
|
||||
"createAccountReward": "Account erstellen",
|
||||
"loginIncentiveQuest": "To unlock this quest, check in to Habitica on <%= count %> different days!",
|
||||
"loginIncentiveQuest": "Um dieses Quest freizuschalten, melde Dich an <%= count %> verschiedenen Tagen auf Habitica an.",
|
||||
"loginIncentiveQuestObtained": "Du hast diese Quest erhalten, indem Du Dich an <%= count %> unterschiedlichen Tagen angemeldet hast!",
|
||||
"loginReward": "<%= count %> Anmeldungen",
|
||||
"createAccountQuest": "Du hast diese Quest beim Beitreten zu Habitica erhalten! Wenn einer Deiner Freunde beitritt, erhält er ebenfalls eine.",
|
||||
"questBundles": "Reduzierte Quest-Pakete",
|
||||
"buyQuestBundle": "Quest-Paket kaufen",
|
||||
"noQuestToStart": "Can’t find a quest to start? Try checking out the Quest Shop in the Market for new releases!"
|
||||
"noQuestToStart": "Du findest kein Quest, dass Du starten möchtest? Dann guck mal im Quest-Markt auf dem Marktplatz vorbei um neue Quests zu entdecken!"
|
||||
}
|
||||
@@ -220,7 +220,7 @@
|
||||
"questWhaleCompletion": "Nach der ganzen harten Arbeit verstummt das donnernde Jammern des Wales. \"Scheint als wäre sie in der Flut schlechter Angewohnheiten fast ertrunken\", erklärt @zoebeagle, \"Dank Deiner ununterbrochenen Bemühungen konnten wir die Fluten abwenden!\" Als Du in das U-Boot steigen willst fallen Dir in der ruhigen See einige Eier auf.",
|
||||
"questWhaleDropWhaleEgg": "Wal (Ei)",
|
||||
"questWhaleUnlockText": "Ermöglicht den Kauf von Waleiern auf dem Marktplatz",
|
||||
"questGroupDilatoryDistress": "Notruf aus Dilatory",
|
||||
"questGroupDilatoryDistress": "Dilatory in Gefahr",
|
||||
"questDilatoryDistress1Text": "Dilatory in Gefahr, Teil 1: Flaschenpost",
|
||||
"questDilatoryDistress1Notes": "Eine Nachricht in einer Flasche aus der neu wieder aufgebauten Stadt Dilatory traf ein! Darin steht: \"Liebe Habiticaner, wir brauchen erneut eure Hilfe. Unsere Prinzessin ist verschwunden und die Stadt wird von einigen unbekannten Wasserdämonen belagert! Die Fangschreckenkrebse halten uns die Angreifer vom Leibe. Bitte helft uns!\" Um die weite Reise zur versunkenen Stadt zu durchstehen, muss man fähig sein unter Wasser zu atmen. Glücklicherweise können die Alchimisten @Benga und @hazel dies möglich machen! Du musst nur die richtigen Zutaten finden.",
|
||||
"questDilatoryDistress1Completion": "Du ziehst die Flossenrüstung an und schwimmst so schnell Du kannst nach Dilatory. Bisher haben das Meeresvolk und ihre verbündeten Fangschreckenkrebse es geschafft die Monster aus der Stadt fernzuhalten, aber sie sind drauf und dran zu verlieren. Kaum bist Du innerhalb der Schlossmauern, als die entsetzliche Belagerung durchbricht!",
|
||||
@@ -508,14 +508,14 @@
|
||||
"farmFriendsNotes": "Beinhaltet 'Die Muhtantische Kuh', 'Reite die Nacht-Mähre', und 'Der Donner-Bock'. Verfügbar bis zum 30. September.",
|
||||
"witchyFamiliarsText": "\"Hexenhafte Haustiere\" Quest-Paket",
|
||||
"witchyFamiliarsNotes": "Beinhaltet 'Der Rattenkönig', 'Die eisige Arachnoide', und 'Sumpf des Chaos-Froschs'. Verfügbar bis zum 31. Oktober.",
|
||||
"questGroupLostMasterclasser": "Mystery of the Masterclassers",
|
||||
"questUnlockLostMasterclasser": "To unlock this quest, complete the final quests of these quest chains: 'Dilatory Distress', 'Mayhem in Mistiflying', 'Stoïkalm Calamity', and 'Terror in the Taskwoods'.",
|
||||
"questLostMasterclasser1Text": "The Mystery of the Masterclassers, Part 1: Read Between the Lines",
|
||||
"questLostMasterclasser1Notes": "You’re unexpectedly summoned by @beffymaroo and @Lemoness to Habit Hall, where you’re astonished to find all four of Habitica’s Masterclassers awaiting you in the wan light of dawn. Even the Joyful Reaper looks somber.<br><br>“Oho, you’re here,” says the April Fool. “Now, we would not rouse you from your rest without a truly dire—”<br><br>“Help us investigate the recent bout of possessions,” interrupts Lady Glaciate. “All the victims blamed someone named Tzina.”<br><br>The April Fool is clearly affronted by the summary. “What about my speech?” he hisses to her. “With the fog and thunderstorm effects?”<br><br>“We’re in a hurry,” she mutters back. “And my mammoths are still soggy from your incessant practicing.”<br><br>“I’m afraid that the esteemed Master of Warriors is correct,” says King Manta. “Time is of the essence. Will you aid us?”<br><br>When you nod, he waves his hands to open a portal, revealing an underwater room. “Swim down with me to Dilatory, and we will scour my library for any references that might give us a clue.” At your look of confusion, he adds, “Don’t worry, the paper was enchanted long before Dilatory sank. None of the books are the slightest bit damp!” He winks.“Unlike Lady Glaciate’s mammoths.”<br><br>“I heard that, Manta.”<br><br>As you dive into the water after the Master of Mages, your legs magically fuse into fins. Though your body is buoyant, your heart sinks when you see the thousands of bookshelves. Better start reading…",
|
||||
"questGroupLostMasterclasser": "Geheimnis der Klassenmeister",
|
||||
"questUnlockLostMasterclasser": "Um diese Quest freizuschalten, musst Du die finalen Quests der Questreihen 'Dilatory in Gefahr', 'Chaos in Mistiflying', 'Stoïstilles Unglück' und 'Schrecken in den Aufgabenwäldern' abgeschlossen haben.",
|
||||
"questLostMasterclasser1Text": "Das Geheimnis der Klassenmeister, Teil 1: Lies zwischen den Zeilen",
|
||||
"questLostMasterclasser1Notes": "Du wurdest unerwartet von @beffymaroo und @Lemoness nach Habit Hall gerufen, wo Du erstaunt feststellst, dass im fahlen Licht der Dämmerung alle vier Klassenmeister von Habitica auf Dich warten. Sogar der Fröhliche Reaper sieht düster aus. <br><br>“Oho, Du bist hier”, sagt der April-Scherzkeks. “Nun, wir stören ungern Deine Nachtruhe ohne einen wirklich triftigen—” <br><br>“Hilf uns, den jüngsten Fall von Besessenheit aufzuklären”, unterbricht Lady Glaciate. “Alle Opfer beschuldigten jemanden namens Tzina.” <br><br>Der April-Scherzkeks ist sichtlich beleidigt von der Kurzfassung. “Was ist mit meiner Ansprache?” zischt er ihr zu. “Mit dem Nebel und den Gewitter-Effekten?” <br><br>“Wir sind in Eile”, murmelt sie zurück. “Und meine Mammuts sind immer noch klatschnass von Deinen pausenlosen Proben.” <br><br>“Ich fürchte, dass die verehrte Meisterin der Krieger Recht behält”, sagt König Manta. “Zeit ist von wesentlicher Bedeutung. Wirst Du uns helfen?” <br><br>Als Du nickst, winkt er mit seinen Händen, um ein Portal zu öffnen, das zu einem Unterwasser-Raum führt. “Schwimm mit mir hinab nach Dilatory, und wir durchkämmen meine Bibliothek nach jeglichen Belegen, die uns einen Hinweis geben könnten.” Als er Deine Verwirrung bemerkt, fügt er hinzu: “Keine Sorge, das Papier wurde bereits verzaubert, lange bevor Dilatory versank. Keines der Bücher ist auch nur im geringsten feucht!” Er zwinkert. “Im Gegensatz zu Lady Glaciate’s Mammuts.” <br><br>“Das habe ich gehört, Manta.” <br><br>Als Du hinter dem Meister der Magier in das Wasser tauchst, verschmelzen Deine Beine auf magische Weise zu einer Schwanzflosse. Und obwohl Dein Körper Auftrieb hat, sinkt Dein Herz beim Anblick tausender Bücherregale. Du fängst besser an zu lesen…",
|
||||
"questLostMasterclasser1Completion": "After hours of poring through volumes, you still haven’t found any useful information.<br><br>“It seems impossible that there isn’t even the tiniest reference to anything relevant,” says head librarian @Tuqjoi, and their assistant @stefalupagus nods in frustration.<br><br>King Manta’s eyes narrow. “Not impossible…” he says. “<em>Intentional</em>.” For a moment, the water glows around his hands, and several of the books shudder. “Something is obscuring information,” he says. “Not just a static spell, but something with a will of its own. Something… alive.” He swims up from the table. “The Joyful Reaper needs to hear about this. Let’s pack a meal for the road.”",
|
||||
"questLostMasterclasser1CollectAncientTomes": "Ancient Tomes",
|
||||
"questLostMasterclasser1CollectForbiddenTomes": "Forbidden Tomes",
|
||||
"questLostMasterclasser1CollectHiddenTomes": "Hidden Tomes",
|
||||
"questLostMasterclasser1CollectAncientTomes": "Alte Bücher",
|
||||
"questLostMasterclasser1CollectForbiddenTomes": "Verbotene Bücher",
|
||||
"questLostMasterclasser1CollectHiddenTomes": "Versteckte Bücher",
|
||||
"questLostMasterclasser2Text": "The Mystery of the Masterclassers, Part 2: Assembling the a'Voidant",
|
||||
"questLostMasterclasser2Notes": "The Joyful Reaper drums her bony fingers on some of the books that you brought. “Oh, dear,” the Master of Healers says. “There is a malevolent life essence at work. I might have guessed, considering the attacks by reanimated skulls during each incident.” Her assistant @tricksy.fox brings in a chest, and you are startled to see the contents that @beffymaroo unloads: the very same objects once used by this mysterious Tzina to possess people.<br><br>“I’m going to use resonant healing magic to try to make this creature manifest,” the Joyful Reaper says, reminding you that the skeleton is a somewhat unconventional Healer. “You’ll need to read the revealed information quickly, in case it breaks loose.”<br><br>As she concentrates, a twisting mist begins to siphon from the books and twine around the objects. Quickly, you flip through the pages, trying to read the new lines of text that are writhing into view. You catch only a few snippets: “Sands of the Timewastes” — “the Great Disaster” —“split into four”— “permanently corrupted”— before a single name catches your eye: Zinnya.<br><br>Abruptly, the pages wrench free from your fingers and shred themselves as a howling creature explodes into being, coalescing around the possessed objects.<br><br>“It’s an a’Voidant!” the Joyful Reaper shouts, throwing up a protection spell. “They’re ancient creatures of confusion and obscurity. If this Tzina can control one, she must have a frightening command over life magic. Quickly, attack it before it escapes back into the books!”<br><br>",
|
||||
"questLostMasterclasser2Completion": "The a’Voidant succumbs at last, and you share the snippets that you read.<br><br>“None of those references sound familiar, even for someone as old as I,” the Joyful Reaper says. “Except… the Timewastes are a distant desert at the most hostile edge of Habitica. Portals often fail nearby, but swift mounts could get you there in no time. Lady Glaciate will be glad to assist.” Her voice grows amused. “Which means that the enamored Master of Rogues will undoubtedly tag along.” She hands you the glimmering mask. “Perhaps you should try to track the lingering magic in these items to its source. I’ll go harvest some sustenance for your journey.”",
|
||||
@@ -536,7 +536,7 @@
|
||||
"questLostMasterclasser3DropZombiePotion": "Zombie Hatching Potion",
|
||||
"questLostMasterclasser4Text": "The Mystery of the Masterclassers, Part 4: The Lost Masterclasser",
|
||||
"questLostMasterclasser4Notes": "You surface from the portal, but you’re still suspended in a strange, shifting netherworld. “That was bold,” says a cold voice. “I have to admit, I hadn’t planned for a direct confrontation yet.” A woman rises from the churning whirlpool of darkness. “Welcome to the Realm of Void.”<br><br>You try to fight back your rising nausea. “Are you Zinnya?” you ask.<br><br>“That old name for a young idealist,” she says, mouth twisting, and the world writhes beneath you. “No. If anything, you should call me the Anti’zinnya now, given all that I have done and undone.”<br><br>Suddenly, the portal reopens behind you, and as the four Masterclassers burst out, bolting towards you, Anti’zinnya’s eyes flash with hatred. “I see that my pathetic replacements have managed to follow you.”<br><br>You stare. “Replacements?”<br><br>“As the Master Aethermancer, I was the first Masterclasser — the only Masterclasser. These four are a mockery, each possessing only a fragment of what I once had! I commanded every spell and learned every skill. I shaped your very world to my whim — until the traitorous aether itself collapsed under the weight of my talents and my perfectly reasonable expectations. I have been trapped for millennia in this resulting void, recuperating. Imagine my disgust when I learned how my legacy had been corrupted.” She lets out a low, echoing laugh. “My plan was to destroy their domains before destroying them, but I suppose the order is irrelevant.” With a burst of uncanny strength, she charges forward, and the Realm of Void explodes into chaos.",
|
||||
"questLostMasterclasser4Completion": "Under the onslaught of your final attack, the Lost Masterclasser screams in frustration, her body flickering into translucence. The thrashing void stills around her as she slumps forward, and for a moment, she seems to change, becoming younger, calmer, with an expression of peace upon her face… but then everything melts away with scarcely a whisper, and you’re kneeling once more in the desert sand.<br><br>“It seems that we have much to learn about our own history,” King Manta says, staring at the broken ruins. “After the Master Aethermancer grew overwhelmed and lost control of her abilities, the outpouring of void must have leached the life from the entire land. Everything probably became deserts like this.”<br><br>“No wonder the ancients who founded Habitica stressed a balance of productivity and wellness,” the Joyful Reaper murmurs. “Rebuilding their world would have been a daunting task requiring considerable hard work, but they would have wanted to prevent such a catastrophe from happening again.”<br><br>“Oho, look at those formerly possessed items!” says the April Fool. Sure enough, all of them shimmer with a pale, glimmering translucence from the final burst of aether released when you laid Anti’zinnya’s spirit to rest. “What a dazzling effect. I must take notes.”<br><br>“The concentrated remnants of aether in this area probably caused caused these animals to go invisible, too,” says Lady Glaciate, scratching a patch of emptiness behind the ears. You feel an unseen fluffy head nudge your hand, and suspect that you’ll have to do some explaining at the Stables back home. As you look at the ruins one last time, you spot all that remains of the first Masterclasser: her shimmering cloak. Lifting it onto your shoulders, you head back to Habit City, pondering everything that you have learned.<br><br>",
|
||||
"questLostMasterclasser4Completion": "Under the onslaught of your final attack, the Lost Masterclasser screams in frustration, her body flickering into translucence. The thrashing void stills around her as she slumps forward, and for a moment, she seems to change, becoming younger, calmer, with an expression of peace upon her face… but then everything melts away with scarcely a whisper, and you’re kneeling once more in the desert sand.<br><br>“It seems that we have much to learn about our own history,” King Manta says, staring at the broken ruins. “After the Master Aethermancer grew overwhelmed and lost control of her abilities, the outpouring of void must have leached the life from the entire land. Everything probably became deserts like this.”<br><br>“No wonder the ancients who founded Habitica stressed a balance of productivity and wellness,” the Joyful Reaper murmurs. “Rebuilding their world would have been a daunting task requiring considerable hard work, but they would have wanted to prevent such a catastrophe from happening again.”<br><br>“Oho, look at those formerly possessed items!” says the April Fool. Sure enough, all of them shimmer with a pale, glimmering translucence from the final burst of aether released when you laid Anti’zinnya’s spirit to rest. “What a dazzling effect. I must take notes.”<br><br>“The concentrated remnants of aether in this area probably caused these animals to go invisible, too,” says Lady Glaciate, scratching a patch of emptiness behind the ears. You feel an unseen fluffy head nudge your hand, and suspect that you’ll have to do some explaining at the Stables back home. As you look at the ruins one last time, you spot all that remains of the first Masterclasser: her shimmering cloak. Lifting it onto your shoulders, you head back to Habit City, pondering everything that you have learned.<br><br>",
|
||||
"questLostMasterclasser4Boss": "Anti'zinnya",
|
||||
"questLostMasterclasser4RageTitle": "Siphoning Void",
|
||||
"questLostMasterclasser4RageDescription": "Siphoning Void: This bar fills when you don't complete your Dailies. When it is full, Anti'zinnya will remove the party's Mana!",
|
||||
|
||||