Merge branch 'develop' into sabrecat/postfixes

This commit is contained in:
Sabe Jones
2024-06-28 21:28:39 -05:00
60 changed files with 1927 additions and 646 deletions

View File

@@ -3,10 +3,13 @@ FROM node:20
# Install global packages
RUN npm install -g gulp-cli mocha
# Copy package.json and package-lock.json into image, then install
# dependencies.
# Copy package.json and package-lock.json into image
WORKDIR /usr/src/habitica
COPY ["package.json", "package-lock.json", "./"]
# Copy the remaining source files in.
COPY . /usr/src/habitica
# Install dependencies
RUN npm install
RUN npm run postinstall
RUN npm run client:build
RUN gulp build:prod

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "habitica",
"version": "5.25.8",
"version": "5.26.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "habitica",
"version": "5.25.8",
"version": "5.26.0",
"hasInstallScript": true,
"dependencies": {
"@babel/core": "^7.22.10",

View File

@@ -1,7 +1,7 @@
{
"name": "habitica",
"description": "A habit tracker app which treats your goals like a Role Playing Game.",
"version": "5.25.8",
"version": "5.26.0",
"main": "./website/server/index.js",
"dependencies": {
"@babel/core": "^7.22.10",
@@ -107,7 +107,8 @@
"debug": "gulp nodemon --inspect",
"mongo:dev": "run-rs -v 5.0.23 -l ubuntu1804 --keep --dbpath mongodb-data --number 1 --quiet",
"postinstall": "git config --global url.\"https://\".insteadOf git:// && gulp build && cd website/client && npm install",
"apidoc": "gulp apidoc"
"apidoc": "gulp apidoc",
"heroku-postbuild": "npm run client:build"
},
"devDependencies": {
"axios": "^1.4.0",

View File

@@ -55,7 +55,7 @@ describe('contentLib', () => {
beforeEach(() => {
resSpy = generateRes();
if (fs.existsSync(contentLib.CONTENT_CACHE_PATH)) {
fs.rmdirSync(contentLib.CONTENT_CACHE_PATH, { recursive: true });
fs.rmSync(contentLib.CONTENT_CACHE_PATH, { recursive: true });
}
fs.mkdirSync(contentLib.CONTENT_CACHE_PATH);
});

View File

@@ -3,6 +3,7 @@ import armoireSet from '../../../website/common/script/content/gear/sets/armoire
describe('armoireSet items', () => {
it('checks if canOwn has the same id', () => {
Object.keys(armoireSet).forEach(type => {
if (type === 'all') return;
Object.keys(armoireSet[type]).forEach(itemKey => {
const ownedKey = `${type}_armoire_${itemKey}`;
expect(armoireSet[type][itemKey].canOwn({

View File

@@ -3,38 +3,26 @@ import forEach from 'lodash/forEach';
import {
expectValidTranslationString,
} from '../helpers/content.helper';
function makeArmoireIitemList () {
const armoire = require('../../website/common/script/content/gear/sets/armoire').default;
const items = [];
items.push(...Object.values(armoire.armor));
items.push(...Object.values(armoire.body));
items.push(...Object.values(armoire.eyewear));
items.push(...Object.values(armoire.head));
items.push(...Object.values(armoire.headAccessory));
items.push(...Object.values(armoire.shield));
items.push(...Object.values(armoire.weapon));
return items;
}
import armoire from '../../website/common/script/content/gear/sets/armoire';
describe('armoire', () => {
let clock;
beforeEach(() => {
delete require.cache[require.resolve('../../website/common/script/content/gear/sets/armoire')];
});
afterEach(() => {
clock.restore();
if (clock) {
clock.restore();
}
});
it('does not return unreleased gear', async () => {
clock = sinon.useFakeTimers(new Date('2024-01-02'));
const items = makeArmoireIitemList();
const items = armoire.all;
expect(items.length).to.equal(377);
expect(items.filter(item => item.set === 'pottersSet' || item.set === 'optimistSet' || item.set === 'schoolUniform')).to.be.an('array').that.is.empty;
});
it('released gear has all required properties', async () => {
clock = sinon.useFakeTimers(new Date('2024-05-08'));
const items = makeArmoireIitemList();
const items = armoire.all;
expect(items.length).to.equal(396);
forEach(items, item => {
if (item.set !== undefined) {
@@ -48,29 +36,30 @@ describe('armoire', () => {
it('releases gear when appropriate', async () => {
clock = sinon.useFakeTimers(new Date('2024-01-01T00:00:00.000Z'));
const items = makeArmoireIitemList();
const items = armoire.all;
expect(items.length).to.equal(377);
clock.restore();
delete require.cache[require.resolve('../../website/common/script/content/gear/sets/armoire')];
clock = sinon.useFakeTimers(new Date('2024-01-08'));
const januaryItems = makeArmoireIitemList();
const januaryItems = armoire.all;
expect(januaryItems.length).to.equal(381);
clock.restore();
delete require.cache[require.resolve('../../website/common/script/content/gear/sets/armoire')];
clock = sinon.useFakeTimers(new Date('2024-02-07'));
const januaryItems2 = makeArmoireIitemList();
const januaryItems2 = armoire.all;
expect(januaryItems2.length).to.equal(381);
clock.restore();
delete require.cache[require.resolve('../../website/common/script/content/gear/sets/armoire')];
clock = sinon.useFakeTimers(new Date('2024-02-07T16:00:00.000Z'));
const febuaryItems = makeArmoireIitemList();
clock = sinon.useFakeTimers(new Date('2024-02-07T09:00:00.000Z'));
const febuaryItems = armoire.all;
expect(febuaryItems.length).to.equal(384);
});
it('sets have at least 2 items', () => {
const armoire = makeArmoireIitemList();
const setMap = {};
forEach(armoire, item => {
forEach(armoire.all, item => {
// Gotta have one outlier
if (!item.set || item.set.startsWith('armoire-')) return;
if (setMap[item.set] === undefined) {
setMap[item.set] = 0;
}

View File

@@ -5,29 +5,51 @@ import {
expectValidTranslationString,
} from '../helpers/content.helper';
import * as eggs from '../../website/common/script/content/eggs';
import eggs from '../../website/common/script/content/eggs';
describe('eggs', () => {
describe('all', () => {
it('is a combination of drop and quest eggs', () => {
const dropNumber = Object.keys(eggs.drops).length;
const questNumber = Object.keys(eggs.quests).length;
const allNumber = Object.keys(eggs.all).length;
let clock;
expect(allNumber).to.be.greaterThan(0);
expect(allNumber).to.equal(dropNumber + questNumber);
});
afterEach(() => {
if (clock) {
clock.restore();
}
});
it('contains basic information about each egg', () => {
each(eggs.all, (egg, key) => {
expectValidTranslationString(egg.text);
expectValidTranslationString(egg.adjective);
expectValidTranslationString(egg.mountText);
expectValidTranslationString(egg.notes);
expect(egg.canBuy).to.be.a('function');
expect(egg.value).to.be.a('number');
expect(egg.key).to.equal(key);
const eggTypes = [
'drops',
'quests',
];
eggTypes.forEach(eggType => {
describe(eggType, () => {
it('contains basic information about each egg', () => {
each(eggs[eggType], (egg, key) => {
expectValidTranslationString(egg.text);
expectValidTranslationString(egg.adjective);
expectValidTranslationString(egg.mountText);
expectValidTranslationString(egg.notes);
expect(egg.canBuy).to.be.a('function');
expect(egg.value).to.be.a('number');
expect(egg.key).to.equal(key);
});
});
});
});
it('does not contain unreleased eggs', () => {
clock = sinon.useFakeTimers(new Date('2024-05-20'));
const questEggs = eggs.quests;
expect(questEggs.Giraffe).to.not.exist;
});
it('Releases eggs when appropriate without needing restarting', () => {
clock = sinon.useFakeTimers(new Date('2024-05-20'));
const mayEggs = eggs.quests;
clock.restore();
clock = sinon.useFakeTimers(new Date('2024-06-20'));
const juneEggs = eggs.quests;
expect(juneEggs.Giraffe).to.exist;
expect(Object.keys(mayEggs).length).to.equal(Object.keys(juneEggs).length - 1);
});
});

View File

@@ -5,7 +5,7 @@ import {
expectValidTranslationString,
} from '../helpers/content.helper';
import { all } from '../../website/common/script/content/hatching-potions';
import hatchingPotions from '../../website/common/script/content/hatching-potions';
describe('hatchingPotions', () => {
let clock;
@@ -25,7 +25,7 @@ describe('hatchingPotions', () => {
potionTypes.forEach(potionType => {
describe(potionType, () => {
it('contains basic information about each potion', () => {
each(all, (potion, key) => {
each(hatchingPotions.all, (potion, key) => {
expectValidTranslationString(potion.text);
expectValidTranslationString(potion.notes);
expect(potion.canBuy).to.be.a('function');
@@ -35,4 +35,20 @@ describe('hatchingPotions', () => {
});
});
});
it('does not contain unreleased potions', () => {
clock = sinon.useFakeTimers(new Date('2024-05-20'));
const premiumPotions = hatchingPotions.premium;
expect(premiumPotions.Koi).to.not.exist;
});
it('Releases potions when appropriate without needing restarting', () => {
clock = sinon.useFakeTimers(new Date('2024-05-20'));
const mayPotions = hatchingPotions.premium;
clock.restore();
clock = sinon.useFakeTimers(new Date('2024-06-20'));
const junePotions = hatchingPotions.premium;
expect(junePotions.Koi).to.exist;
expect(Object.keys(mayPotions).length).to.equal(Object.keys(junePotions).length - 1);
});
});

154
test/content/index.test.js Normal file
View File

@@ -0,0 +1,154 @@
import content from '../../website/common/script/content';
describe('content index', () => {
let clock;
afterEach(() => {
if (clock) {
clock.restore();
}
});
it('Releases eggs when appropriate without needing restarting', () => {
clock = sinon.useFakeTimers(new Date('2024-06-20'));
const mayEggs = content.eggs;
expect(mayEggs.Chameleon).to.not.exist;
clock.restore();
clock = sinon.useFakeTimers(new Date('2024-07-20'));
const juneEggs = content.eggs;
expect(juneEggs.Chameleon).to.exist;
expect(Object.keys(mayEggs).length, '').to.equal(Object.keys(juneEggs).length - 1);
});
it('Releases hatching potions when appropriate without needing restarting', () => {
clock = sinon.useFakeTimers(new Date('2024-05-20'));
const mayHatchingPotions = content.hatchingPotions;
expect(mayHatchingPotions.Koi).to.not.exist;
clock.restore();
clock = sinon.useFakeTimers(new Date('2024-06-20'));
const juneHatchingPotions = content.hatchingPotions;
expect(juneHatchingPotions.Koi).to.exist;
expect(Object.keys(mayHatchingPotions).length, '').to.equal(Object.keys(juneHatchingPotions).length - 1);
});
it('Releases armoire gear when appropriate without needing restarting', () => {
clock = sinon.useFakeTimers(new Date('2024-06-20'));
const juneGear = content.gear.flat;
expect(juneGear.armor_armoire_corsairsCoatAndCape).to.not.exist;
clock.restore();
clock = sinon.useFakeTimers(new Date('2024-07-10'));
const julyGear = content.gear.flat;
expect(julyGear.armor_armoire_corsairsCoatAndCape).to.exist;
expect(Object.keys(juneGear).length, '').to.equal(Object.keys(julyGear).length - 3);
});
it('Releases pets gear when appropriate without needing restarting', () => {
clock = sinon.useFakeTimers(new Date('2024-06-20'));
const junePets = content.petInfo;
expect(junePets['Chameleon-Base']).to.not.exist;
clock.restore();
clock = sinon.useFakeTimers(new Date('2024-07-10'));
const julyPets = content.petInfo;
expect(julyPets['Chameleon-Base']).to.exist;
expect(Object.keys(junePets).length, '').to.equal(Object.keys(julyPets).length - 10);
});
it('Releases mounts gear when appropriate without needing restarting', () => {
clock = sinon.useFakeTimers(new Date('2024-06-20'));
const juneMounts = content.mountInfo;
expect(juneMounts['Chameleon-Base']).to.not.exist;
clock.restore();
clock = sinon.useFakeTimers(new Date('2024-07-10'));
const julyMounts = content.mountInfo;
expect(julyMounts['Chameleon-Base']).to.exist;
expect(Object.keys(juneMounts).length, '').to.equal(Object.keys(julyMounts).length - 10);
});
it('marks regular food as buyable and droppable without any events', () => {
clock = sinon.useFakeTimers(new Date('2024-06-20'));
const { food } = content;
Object.keys(food).forEach(key => {
if (key === 'Saddle') {
expect(food[key].canBuy(), `${key} canBuy`).to.be.true;
expect(food[key].canDrop, `${key} canDrop`).to.be.false;
return;
}
let expected = true;
if (key.startsWith('Cake_')) {
expected = false;
} else if (key.startsWith('Candy_')) {
expected = false;
} else if (key.startsWith('Pie_')) {
expected = false;
}
expect(food[key].canBuy(), `${key} canBuy`).to.equal(expected);
expect(food[key].canDrop, `${key} canDrop`).to.equal(expected);
});
});
it('marks candy as buyable and droppable during habitoween', () => {
clock = sinon.useFakeTimers(new Date('2024-10-31'));
const { food } = content;
Object.keys(food).forEach(key => {
if (key === 'Saddle') {
expect(food[key].canBuy(), `${key} canBuy`).to.be.true;
expect(food[key].canDrop, `${key} canDrop`).to.be.false;
return;
}
let expected = false;
if (key.startsWith('Cake_')) {
expected = false;
} else if (key.startsWith('Candy_')) {
expected = true;
} else if (key.startsWith('Pie_')) {
expected = false;
}
expect(food[key].canBuy(), `${key} canBuy`).to.equal(expected);
expect(food[key].canDrop, `${key} canDrop`).to.equal(expected);
});
});
it('marks cake as buyable and droppable during birthday', () => {
clock = sinon.useFakeTimers(new Date('2024-01-31'));
const { food } = content;
Object.keys(food).forEach(key => {
if (key === 'Saddle') {
expect(food[key].canBuy(), `${key} canBuy`).to.be.true;
expect(food[key].canDrop, `${key} canDrop`).to.be.false;
return;
}
let expected = false;
if (key.startsWith('Cake_')) {
expected = true;
} else if (key.startsWith('Candy_')) {
expected = false;
} else if (key.startsWith('Pie_')) {
expected = false;
}
expect(food[key].canBuy(), `${key} canBuy`).to.equal(expected);
expect(food[key].canDrop, `${key} canDrop`).to.equal(expected);
});
});
it('marks pie as buyable and droppable during pi day', () => {
clock = sinon.useFakeTimers(new Date('2024-03-14'));
const { food } = content;
Object.keys(food).forEach(key => {
if (key === 'Saddle') {
expect(food[key].canBuy(), `${key} canBuy`).to.be.true;
expect(food[key].canDrop, `${key} canDrop`).to.be.false;
return;
}
let expected = false;
if (key.startsWith('Cake_')) {
expected = false;
} else if (key.startsWith('Candy_')) {
expected = false;
} else if (key.startsWith('Pie_')) {
expected = true;
}
expect(food[key].canBuy(), `${key} canBuy`).to.equal(expected);
expect(food[key].canDrop, `${key} canDrop`).to.equal(expected);
});
});
});

View File

@@ -0,0 +1,82 @@
import find from 'lodash/find';
import maxBy from 'lodash/maxBy';
import {
ARMOIRE_RELEASE_DATES,
EGGS_RELEASE_DATES,
HATCHING_POTIONS_RELEASE_DATES,
} from '../../website/common/script/content/constants/releaseDates';
import armoire from '../../website/common/script/content/gear/sets/armoire';
import eggs from '../../website/common/script/content/eggs';
import hatchingPotions from '../../website/common/script/content/hatching-potions';
describe('releaseDates', () => {
let clock;
afterEach(() => {
if (clock) {
clock.restore();
}
});
describe('armoire', () => {
it('should only contain valid armoire names', () => {
const lastReleaseDate = maxBy(Object.values(ARMOIRE_RELEASE_DATES), value => new Date(`${value.year}-${value.month + 1}-20`));
clock = sinon.useFakeTimers(new Date(`${lastReleaseDate.year}-${lastReleaseDate.month + 1}-20`));
Object.keys(ARMOIRE_RELEASE_DATES).forEach(key => {
expect(find(armoire.all, { set: key }), `${key} is not a valid armoire set`).to.exist;
});
});
it('should contain a valid year and month', () => {
Object.keys(ARMOIRE_RELEASE_DATES).forEach(key => {
const date = ARMOIRE_RELEASE_DATES[key];
expect(date.year, `${key} year is not a valid year`).to.be.a('number');
expect(date.year).to.be.at.least(2023);
expect(date.month, `${key} month is not a valid month`).to.be.a('number');
expect(date.month).to.be.within(1, 12);
expect(date.day).to.not.exist;
});
});
});
describe('eggs', () => {
it('should only contain valid egg names', () => {
const lastReleaseDate = maxBy(Object.values(EGGS_RELEASE_DATES), value => new Date(`${value.year}-${value.month + 1}-${value.day}`));
clock = sinon.useFakeTimers(new Date(`${lastReleaseDate.year}-${lastReleaseDate.month + 1}-${lastReleaseDate.day}`));
Object.keys(EGGS_RELEASE_DATES).forEach(key => {
expect(eggs.all[key], `${key} is not a valid egg name`).to.exist;
});
});
it('should contain a valid year, month and date', () => {
Object.keys(EGGS_RELEASE_DATES).forEach(key => {
const date = EGGS_RELEASE_DATES[key];
expect(date.year, `${key} year is not a valid year`).to.be.a('number');
expect(date.year).to.be.at.least(2024);
expect(date.month, `${key} month is not a valid month`).to.be.a('number');
expect(date.month).to.be.within(1, 12);
expect(date.day, `${key} day is not a valid day`).to.be.a('number');
});
});
});
describe('hatchingPotions', () => {
it('should only contain valid potion names', () => {
const lastReleaseDate = maxBy(Object.values(HATCHING_POTIONS_RELEASE_DATES), value => new Date(`${value.year}-${value.month + 1}-${value.day}`));
clock = sinon.useFakeTimers(new Date(`${lastReleaseDate.year}-${lastReleaseDate.month + 1}-${lastReleaseDate.day}`));
Object.keys(HATCHING_POTIONS_RELEASE_DATES).forEach(key => {
expect(hatchingPotions.all[key], `${key} is not a valid potion name`).to.exist;
});
});
it('should contain a valid year, month and date', () => {
Object.keys(HATCHING_POTIONS_RELEASE_DATES).forEach(key => {
const date = HATCHING_POTIONS_RELEASE_DATES[key];
expect(date.year, `${key} year is not a valid year`).to.be.a('number');
expect(date.year).to.be.at.least(2024);
expect(date.month, `${key} month is not a valid month`).to.be.a('number');
expect(date.month).to.be.within(1, 12);
expect(date.day, `${key} day is not a valid day`).to.be.a('number');
});
});
});
});

View File

@@ -7,7 +7,7 @@ import {
import QUEST_PETS from '../../website/common/script/content/quests/pets';
import QUEST_HATCHINGPOTIONS from '../../website/common/script/content/quests/potions';
import QUEST_BUNDLES from '../../website/common/script/content/bundles';
import { premium } from '../../website/common/script/content/hatching-potions';
import potions from '../../website/common/script/content/hatching-potions';
import SPELLS from '../../website/common/script/content/spells';
import QUEST_SEASONAL from '../../website/common/script/content/quests/seasonal';
@@ -167,7 +167,7 @@ describe('Content Schedule', () => {
});
it('premium hatching potions', () => {
const potionKeys = Object.keys(premium);
const potionKeys = Object.keys(potions.premium);
Object.keys(MONTHLY_SCHEDULE).forEach(key => {
const monthlyPotions = MONTHLY_SCHEDULE[key][21].find(item => item.type === 'premiumHatchingPotions');
for (const potion of monthlyPotions.items) {

View File

@@ -6,12 +6,21 @@ import {
} from '../helpers/content.helper';
import t from '../../website/common/script/content/translation';
import * as stable from '../../website/common/script/content/stable';
import * as eggs from '../../website/common/script/content/eggs';
import * as potions from '../../website/common/script/content/hatching-potions';
import stable from '../../website/common/script/content/stable';
import eggs from '../../website/common/script/content/eggs';
import potions from '../../website/common/script/content/hatching-potions';
describe('stable', () => {
describe('dropPets', () => {
let clock;
beforeEach(() => {
clock = sinon.useFakeTimers(new Date('2020-05-20'));
});
afterEach(() => {
clock.restore();
});
it('contains a pet for each drop potion * each drop egg', () => {
const numberOfDropPotions = Object.keys(potions.drops).length;
const numberOfDropEggs = Object.keys(eggs.drops).length;

View File

@@ -27,8 +27,15 @@
</head>
<body>
<div id="loading-screen">
<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M31.62 28.86c-.32-.706-1.057-1.048-1.538-.706-.48.341-1.147.393-1.78.24-.633-.153-.753-1.604-.616-3.278.136-1.673.363-2.318.506-2.925.162-.61.877-.562.962-.084.086.479.582.479 1.307-.391.724-.87.617-3.409-.218-5.474-.836-2.065.326-1.865.664-1.66.337.205.544-.102.462-1.28-.082-1.178-1.166-2.098-2.039-2.663-.873-.564-1.936-1.186-1.911-2.697.025-1.511 2.08-1.464 2.358-1.439.279.025.815-.093.506-1.663-.31-1.57-1.43-1.869-2.133-1.826-.703.042-1.177.428-2.17.053-.995-.376-1.655-.23-2.58-.023-.926.206-2.138.776-3.646 1.183-.795.219-1.064.274-1.93.288-.532.008-.755.653-.043 1.444.563.643 1.839.814 2.606.707.494-.07.608.258.563.74a8.013 8.013 0 0 0-.01 1.795c.08.6.18 1.62-.103 2.286-.14.326-.545.677-.98.653-.565-.034-1.022-.7-1.414-1.49-.825-1.662-1.793-2.014-5.404-3.535-3.248-1.367-5.007-3.5-6.096-4.874-.969-1.217-1.939-.756-1.85.342.07.852.592 3.604 1.912 5.257 1.623 2.525 4.128 3.67 7.013 3.895.755.06 1.226.208 1.29.553.095.735-.622 1.244-1.959 1.09-1.336-.157-1.907.087-1.641.848.85 1.79 2.809 1.869 3.623 1.942.275.05 1.246 0 1.764.143.605.166.735 1.005-.14 1.459-1.558.76-2.237 1.391-3.025 2.83-.595 1.13-1.108 3.022-.574 5.745.513 2.648-3.337 2.733-5 2.357-.716-.151-1.47-1.512.287-2.65 1.421-.922 1.708-1.49 1.645-2.657-.074-1.36-.824-1.458-.822-2.64v-2.82a.435.435 0 0 0-.435-.435H7.698a.435.435 0 0 1-.435-.434v-1.7a.435.435 0 0 0-.435-.435H5.501a.435.435 0 0 1-.435-.435v-1.524a.435.435 0 0 0-.435-.435H3.015a.435.435 0 0 1-.435-.435v-1.603a.435.435 0 0 0-.435-.434H.435a.435.435 0 0 0-.435.434v1.705c0 .24.195.435.435.435h1.62c.24 0 .435.195.435.435v6.076c0 .241.195.435.435.435h1.71c.241 0 .436.196.436.435v1.988c0 .24.195.434.435.434h2.402c.734-.052.862.934.854 1.286-.016.803-.923 1.06-1.352 1.395-1.145.884-2.031 1.783-1.513 3.512l.013.036c.945 2.007 3.542 1.8 5.183 1.8h10.326c.584 0 1.184.135 1.046-.545-.136-.68-.425-1.61-1.265-1.61-.84 0-.703.467-1.524.228-.821-.238-.822-1.348.411-3.279 1.276-1.649 3.46-1.524 4.781-.358 1.32 1.166.93 3.191.653 4.354-.158.82.218 1.224.669 1.213h5.242c.806-.014.647-.556.185-1.614h.003z" fill="#fff"/>
<svg width="80" height="80" viewBox="0 0 80 80" xmlns="http://www.w3.org/2000/svg">
<path
xmlns="http://www.w3.org/2000/svg"
fill-rule="evenodd"
clip-rule="evenodd"
d="M79.05 72.15c-.8-1.766-2.643-2.62-3.845-1.766-1.201.855-2.867.985-4.448.602-1.584-.385-1.885-4.01-1.543-8.195.342-4.184.909-5.795 1.267-7.314.404-1.524 2.191-1.404 2.405-.209.215 1.196 1.454 1.196 3.266-.979 1.811-2.175 1.543-8.52-.546-13.684-2.088-5.163.817-4.661 1.66-4.149.844.513 1.362-.255 1.156-3.2-.204-2.945-2.916-5.247-5.096-6.657-2.184-1.41-4.842-2.967-4.78-6.745.063-3.777 5.2-3.658 5.897-3.596.697.063 2.037-.233 1.264-4.157-.773-3.924-3.575-4.673-5.332-4.567-1.758.106-2.943 1.071-5.427.133-2.484-.938-4.136-.572-6.45-.057-2.313.515-5.343 1.94-9.112 2.959-1.989.545-2.661.683-4.828.718-1.33.02-1.885 1.633-.106 3.61 1.408 1.608 4.597 2.036 6.515 1.768 1.236-.174 1.521.645 1.407 1.85a20.023 20.023 0 0 0-.024 4.488c.198 1.5.45 4.051-.258 5.713-.35.817-1.361 1.693-2.449 1.633-1.413-.084-2.555-1.75-3.537-3.726-2.06-4.152-4.48-5.033-13.509-8.835-8.12-3.417-12.516-8.749-15.24-12.185-2.421-3.042-4.846-1.89-4.626.855.179 2.128 1.48 9.008 4.781 13.141 4.058 6.314 10.32 9.177 17.534 9.739 1.885.149 3.065.52 3.225 1.383.236 1.835-1.557 3.11-4.898 2.722-3.341-.39-4.768.22-4.103 2.121 2.123 4.477 7.021 4.672 9.058 4.857.686.122 3.114 0 4.41.355 1.51.418 1.836 2.514-.353 3.648-3.892 1.903-5.59 3.479-7.561 7.075-1.486 2.826-2.77 7.555-1.435 14.365 1.283 6.62-8.342 6.83-12.497 5.89-1.793-.377-3.675-3.778.716-6.625 3.553-2.305 4.269-3.724 4.111-6.642-.184-3.4-2.058-3.644-2.053-6.598v-7.05c0-.602-.488-1.088-1.087-1.088h-3.334a1.087 1.087 0 0 1-1.087-1.087v-4.25c0-.602-.488-1.087-1.088-1.087h-3.317a1.087 1.087 0 0 1-1.087-1.088v-3.81c0-.602-.489-1.087-1.088-1.087h-4.04a1.087 1.087 0 0 1-1.089-1.088V26.25c0-.602-.488-1.088-1.087-1.088H1.088C.485 25.161 0 25.65 0 26.25v4.26c0 .602.488 1.087 1.088 1.087h4.049c.602 0 1.087.489 1.087 1.088v15.192c0 .602.489 1.087 1.088 1.087h4.277c.602 0 1.088.489 1.088 1.088v4.968c0 .602.488 1.087 1.087 1.087h6.005c1.836-.13 2.156 2.335 2.137 3.214-.04 2.007-2.308 2.652-3.382 3.487-2.861 2.21-5.077 4.459-3.78 8.781l.032.09c2.362 5.017 8.855 4.499 12.956 4.499h25.817c1.459 0 2.959.339 2.614-1.362-.342-1.7-1.063-4.024-3.162-4.024-2.1 0-1.758 1.166-3.81.57-2.054-.597-2.057-3.371 1.027-8.198 3.19-4.122 8.652-3.81 11.952-.895 3.301 2.915 2.325 7.978 1.633 10.885-.396 2.048.545 3.06 1.67 3.032H78.58c2.015-.035 1.62-1.391.464-4.035h.008z"
fill="#fff"
>
</path>
</svg>
</div>

View File

@@ -320,7 +320,7 @@
<script>
import each from 'lodash/each';
import * as quests from '@/../../common/script/content/quests';
import { mountInfo, petInfo } from '@/../../common/script/content/stable';
import stable from '@/../../common/script/content/stable';
import content from '@/../../common/script/content';
import gear from '@/../../common/script/content/gear';
import styleHelper from '@/mixins/styleHelper';
@@ -330,6 +330,8 @@ import userLink from '../userLink';
import PurchaseHistoryTable from '../ui/purchaseHistoryTable.vue';
import { userStateMixin } from '../../mixins/userState';
const { mountInfo, petInfo } = stable;
export default {
components: {
userLink,

View File

@@ -16,10 +16,13 @@
class="brand"
aria-label="Habitica"
>
<div
<router-link to="/">
<div
class="logo svg-icon svg color gryphon"
v-html="icons.melior"
></div>
></div>
<div class="svg-icon"></div>
</router-link>
<div class="svg-icon"></div>
</b-navbar-brand>
<b-navbar-toggle

View File

@@ -80,7 +80,7 @@
</style>
<script>
import { mountInfo } from '@/../../common/script/content/stable';
import stable from '@/../../common/script/content/stable';
import markdownDirective from '@/directives/markdown';
export default {
@@ -105,7 +105,7 @@ export default {
},
methods: {
openDialog (mountKey) {
this.mount = mountInfo[mountKey];
this.mount = stable.mountInfo[mountKey];
this.$root.$emit('bv::show::modal', 'mount-raised-modal');
},
close () {

View File

@@ -586,8 +586,8 @@ import reduce from 'lodash/reduce';
import moment from 'moment';
import planGemLimits from '@/../../common/script/libs/planGemLimits';
import { drops as dropEggs } from '@/../../common/script/content/eggs';
import { drops as dropPotions } from '@/../../common/script/content/hatching-potions';
import eggs from '@/../../common/script/content/eggs';
import hatchingPotions from '@/../../common/script/content/hatching-potions';
import { avatarEditorUtilities } from '@/mixins/avatarEditUtilities';
import numberInvalid from '@/mixins/numberInvalid';
import spellsMixin from '@/mixins/spells';
@@ -617,6 +617,9 @@ import EquipmentAttributesGrid from '../inventory/equipment/attributesGrid.vue';
import Item from '@/components/inventory/item';
import Avatar from '@/components/avatar';
const dropEggs = eggs.drops;
const dropPotions = hatchingPotions.drops;
const dropEggKeys = keys(dropEggs);
const amountOfDropEggs = size(dropEggs);

View File

@@ -2885,5 +2885,7 @@
"armorSpecialSummer2023MageNotes": "Fühl dich beschützt und bequem in diesen fließenden Roben, perfekt koloriert für Unterwasser-Abenteuer. Erhöht Intelligenz um <%= int %>. Limitierte Ausgabe 2023 Sommerausrüstung.",
"armorSpecialSummer2023HealerNotes": "Halte an deinen Zielen und Überzeugungen fest, in diesem eleganten grünen Kleid. Erhöht Ausdauer um <%= con %>. Limitierte Ausgabe 2023 Sommerausrüstung.",
"armorSpecialFall2023RogueText": "Verfluchter Hexenkessel",
"armorSpecialFall2023RogueNotes": "Du wurdest mit dem Versprechen einer schönen, heissen Trinkerei gelockt... der Spaß geht auf deine Kosten! Erhöht Wahrnehmung um <%= per %>. Limitierte Ausgabe 2023 Herbstausrüstung."
"armorSpecialFall2023RogueNotes": "Du wurdest mit dem Versprechen einer schönen, heissen Trinkerei gelockt... der Spaß geht auf deine Kosten! Erhöht Wahrnehmung um <%= per %>. Limitierte Ausgabe 2023 Herbstausrüstung.",
"armorSpecialFall2023WarriorText": "Videorekorder Rüstung",
"armorSpecialFall2023WarriorNotes": "Spielt sie DVDs ab? VHS?? Was für Kabel benötigt dieses Ding, um es mit dem TV zu verbinden?! Wie sich herausstellt, ist dies der beängstigendste Aspekt an der Sache. Erhöht Ausdauer um <%= con %>. Limitierte Ausgabe 2023 Sommerausrüstung."
}

View File

@@ -983,6 +983,10 @@
"backgroundShellGateText": "Shell Gate",
"backgroundShellGateNotes": "March through the decorated coral of a Shell Gate.",
"backgrounds072024": "SET 122: Released July 2024",
"backgroundRiverBottomText": "River Bottom",
"backgroundRiverBottomNotes": "Explore a River Bottom.",
"timeTravelBackgrounds": "Steampunk Backgrounds",
"backgroundAirshipText": "Airship",
"backgroundAirshipNotes": "Become a sky sailor on board your very own Airship.",

View File

@@ -255,6 +255,10 @@
"questEggGiraffeMountText": "Giraffe",
"questEggGiraffeAdjective": "a towering",
"questEggChameleonText": "Chameleon",
"questEggChameleonMountText": "Chameleon",
"questEggChameleonAdjective": "a chaotic",
"eggNotes": "Find a hatching potion to pour on this egg, and it will hatch into <%= eggAdjective(locale) %> <%= eggText(locale) %>.",
"hatchingPotionBase": "Base",

View File

@@ -770,6 +770,8 @@
"weaponArmoirePottersWheelNotes": "Throw some clay on this wheel and make a bowl or a mug or a vase or a slightly different bowl. If you're lucky, a ghost might visit while you create! Increases Perception by <%= per %>. Enchanted Armoire: Potter Set (Item 4 of 4).",
"weaponArmoireShadyBeachUmbrellaText": "Beach Umbrella",
"weaponArmoireShadyBeachUmbrellaNotes": "The shade of this rainbow-colored umbrella conceals you briefly from the day star and any unwanted bothers. Increases Perception by <%= per %>. Enchanted Armoire: Beachside Set (Item 3 of 4).",
"weaponArmoireCorsairsBladeText": "Corsairs Blade",
"weaponArmoireCorsairsBladeNotes": "Whether you wield it to plunder or to protect, you can be glad you brought this fierce blade to sea with you. Just be sure to stow it safely when not in use. Increases Strength by <%= str %>. Enchanted Armoire: Corsair Set (Item 3 of 3)",
"armor": "armor",
"armorCapitalized": "Armor",
@@ -1400,6 +1402,8 @@
"armorMystery202401Notes": "These robes appear as delicate as crystal snowflakes, but will keep you plenty warm as you work your wintry magic. Confers no benefit. January 2024 Subscriber Item.",
"armorMystery202406Text": "Phantom Buccaneers Attire",
"armorMystery202406Notes": "Haunt your enemies with style and flair! Confers no benefit. June 2024 Subscriber Item.",
"armorMystery202407Text": "Amiable Axolotl Suit",
"armorMystery202407Notes": "Glide through lakes and canals with your sweeping pink tail! Confers no benefit. July 2024 Subscriber Item.",
"armorMystery301404Text": "Steampunk Suit",
"armorMystery301404Notes": "Dapper and dashing, wot! Confers no benefit. February 3015 Subscriber Item.",
@@ -1616,6 +1620,8 @@
"armorArmoireYellowStripedSwimsuitNotes": "What could be more delightful than battling sea monsters on the beach? Increases Constitution by <%= con %>. Enchanted Armoire: Beachside Set (Item 1 of 4).",
"armorArmoireBlueStripedSwimsuitText": "Blue Striped Swimsuit",
"armorArmoireBlueStripedSwimsuitNotes": "What could be more exciting than battling sea monsters on the beach? Increases Constitution by <%= con %>. Enchanted Armoire: Beachside Set (Item 2 of 4).",
"armorArmoireCorsairsCoatAndCapeText": "Corsairs Coat and Cape",
"armorArmoireCorsairsCoatAndCapeNotes": "Whether youre biding your time on the docks or watching for danger on the open seas, these will surely keep you feeling dry and looking dramatic. Just keep your balance on deck. Increases Constitution by <%= con %>. Enchanted Armoire: Corsair Set (Item 1 of 3)",
"headgear": "helm",
"headgearCapitalized": "Headgear",
@@ -2279,6 +2285,8 @@
"headMystery202404Notes": "This hat will connect you with the earth and allow you to hear secret wishes from many creatures. Confers no benefit. April 2024 Subscriber Item.",
"headMystery202406Text": "Phantom Buccaneers Hat",
"headMystery202406Notes": "The ghostly feathers that adorn this hat glow faintly, like the waves of a spectral sea. Confers no benefit. June 2024 Subscriber Item.",
"headMystery202407Text": "Amiable Axolotl Hood",
"headMystery202407Notes": "These magical gills will let you breathe underwater! Confers no benefit. July 2024 Subscriber Item.",
"headMystery301404Text": "Fancy Top Hat",
"headMystery301404Notes": "A fancy top hat for the finest of gentlefolk! January 3015 Subscriber Item. Confers no benefit.",
@@ -2475,6 +2483,8 @@
"headArmoireHattersTopHatNotes": "Our hats are off to you, and yours is on! Whats hidden in your hat is anybodys guess (but were hoping its a bunny). Increases Perception by <%= per %>. Enchanted Armoire: Hatter Set (Item 1 of 4).",
"headArmoirePottersBandanaText": "Bandana",
"headArmoirePottersBandanaNotes": "Look the part and keep your hair out of your face while you work. Its a win-win! Increases Intelligence by <%= int %>. Enchanted Armoire: Potter Set (Item 2 of 4).",
"headArmoireCorsairsBandanaText": "Corsairs Bandana",
"headArmoireCorsairsBandanaNotes": "Whether youre keeping your head covered in case a seagull flies overhead or making sure your foes never see you sweat, this bandana is essential. Just add a decorative bead for every adventure you complete. Increases Intelligence by <%= int %>. Enchanted Armoire: Corsair Set (Item 2 of 3)",
"offhand": "off-hand item",
"offHandCapitalized": "Off-Hand Item",

View File

@@ -895,7 +895,13 @@
"questGiraffeBoss": "Gear-affe",
"questGiraffeDropGiraffeEgg": "Giraffe (Egg)",
"QuestGiraffeUnlockText": "Unlocks Giraffe Eggs for purchase in the Market.",
"questPinkMarbleUnlockText": "Unlocks Pink Marble Hatching Potions for purchase in the Market.",
"questChameleonText": "The Chaotic Chameleon",
"questChameleonNotes": "Its a beautiful day in a warm, rainy corner of the Taskwoods. Youre on the hunt for new additions to your leaf collection when a branch in front of you changes color without warning! Then it moves!<br><br>Stumbling backwards, you realize this is not a branch at all, but a huge chameleon! Each part of his body keeps changing colors as his eyes dart in different directions.<br><br>“Are you all right?” you ask the chameleon.<br><br>“Ahhh, well,” he says, looking a little flustered. “Ive been trying to blend in… but its so overwhelming… the colors keep coming and going! Its hard to focus on just one....”<br><br>“Aha,” you say, “I think I can help. Well sharpen your focus with a little challenge! Get your colors ready!”<br><br>“Youre on!” replied the chameleon.",
"questChameleonCompletion": "After a few lively turns the Chameleon went through every color of the rainbow, perfectly matching each color you requested.<br><br>“Wow,” he says, “working together and making it into a game really helped me concentrate! Please take these as a reward, youre earned them! Teach these little guys how to change all the colors of the rainbow when they hatch.”",
"questChameleonBoss": "Chaotic Chameleon",
"questChameleonDropChameleonEgg": "Chameleon (Egg)",
"QuestChameleonUnlockText": "Unlocks Chameleon Eggs for purchase in the Market",
"questFungiText": "The Moody Mushroom",
"questFungiNotes": "Its been a rainy spring in Habitica and the ground around the stables is spongy and damp. You notice quite a few mushrooms have appeared along the wooden stable walls and fences. Theres a fog hanging about, not quite letting the sun peek through, and its a bit dispiriting.<br><br>Out of the mist you see the outline of the April Fool, not at all his usual bouncy self.<br><br>”Id hoped to bring you all some delightful Fungi Magic Hatching Potions so that you can keep your mushroom friends from my special day forever,” he says, his expression alarmingly unsmiling. “But this cold fog is really getting to me, its making me feel too tired and dismal to work my usual magic.”<br><br>“Oh no, sorry to hear that,” you say, noticing your own increasingly somber mood. “This fog is really making the day gloomy. I wonder where it came from…”<br><br>A low rumble sounds across the fields, and you see an outline emerging from the mist. Youre alarmed to see a gigantic and unhappy looking mushroom creature, and the mist appears to be emanating from it.<br><br>“Aha,” says the Fool, “I think this fungal fellow may be the source of our blues. Lets see if we can summon a little cheer for our friend here and ourselves.”",

View File

@@ -163,6 +163,7 @@
"mysterySet202404": "Mycelial Magus Set",
"mysterySet202405": "Gilded Dragon Set",
"mysterySet202406": "Phantom Buccaneer Set",
"mysterySet202407": "Amiable Axolotl Set",
"mysterySet301404": "Steampunk Standard Set",
"mysterySet301405": "Steampunk Accessories Set",
"mysterySet301703": "Peacock Steampunk Set",

View File

@@ -150,5 +150,20 @@
"achievementDinosaurDynastyModalText": "You collected all the bird and dinosaur pets!",
"achievementPolarProText": "Has hatched all standard colours of Polar pets: Bear, Fox, Penguin, Whale, and Wolf!",
"achievementPlantParentText": "Has hatched all standard colours of Plant pets: Cactus and Treeling!",
"achievementDinosaurDynastyText": "Has hatched all standard colours of bird and dinosaur pets: Falcon, Owl, Parrot, Peacock, Penguin, Rooster, Pterodactyl, T-Rex, Triceratops, and Velociraptor!"
"achievementDinosaurDynastyText": "Has hatched all standard colours of bird and dinosaur pets: Falcon, Owl, Parrot, Peacock, Penguin, Rooster, Pterodactyl, T-Rex, Triceratops, and Velociraptor!",
"achievementDuneBuddyModalText": "You collected all the desert dwelling pets!",
"achievementRoughRiderModalText": "You collected all the basic colors of the uncomfortable pets and mounts!",
"achievementRodentRuler": "Rodent Ruler",
"achievementRodentRulerText": "Has hatched all standard colors of rodent pets: Guinea Pig, Rat, and Squirrel!",
"achievementRodentRulerModalText": "You collected all the rodent pets!",
"achievementRoughRider": "Rough Rider",
"achievementRoughRiderText": "Has hatched all basic colours of the uncomfortable pets and mounts: Cactus, Hedgehog, and Rock!",
"achievementCats": "Cat Herder",
"achievementCatsText": "Has hatched all the standard colors of cat pets: Cheetah, Lion, Sabretooth, and Tiger!",
"achievementCatsModalText": "You collected all the cat pets!",
"achievementBonelessBoss": "Boneless Boss",
"achievementBonelessBossText": "Has hatched all standard colors of invertebrate pets: Beetle, Butterfly, Cuttlefish, Nudibranch, Octopus, Snail, and Spider!",
"achievementBonelessBossModalText": "You collected all the invertebrate pets!",
"achievementDuneBuddy": "Dune Buddy",
"achievementDuneBuddyText": "Has hatched all standard colours of desert dwelling pets: Armadillo, Cactus, Fox, Frog, Snake, and Spider!"
}

View File

@@ -441,8 +441,8 @@
"backgroundPotionShopText": "Potion Shop",
"backgroundFlyingInAThunderstormNotes": "Chase a Tumultuous Thunderstorm as closely as you dare.",
"backgroundFlyingInAThunderstormText": "Tumultuous Thunderstorm",
"backgroundFarmersMarketNotes": "Shop for the freshest of foods at a Farmer's Market.",
"backgroundFarmersMarketText": "Farmer's Market",
"backgroundFarmersMarketNotes": "Shop for the freshest of foods at the Farmers' Market.",
"backgroundFarmersMarketText": "Farmers' Market",
"backgrounds112019": "SET 66: Released November 2019",
"backgroundMonsterMakersWorkshopNotes": "Experiment with discredited sciences in a Monster Maker's Workshop.",
"backgroundMonsterMakersWorkshopText": "Monster Maker's Workshop",
@@ -602,5 +602,270 @@
"backgroundAmongCattailsNotes": "Admire wetland wildlife Among Cattails.",
"backgroundAmongCattailsText": "Among Cattails",
"backgrounds042021": "SET 83: Released April 2021",
"hideLockedBackgrounds": "Hide locked backgrounds"
"hideLockedBackgrounds": "Hide locked backgrounds",
"backgroundGhostShipNotes": "Prove tales and legends true when you step aboard a Ghost Ship.",
"backgroundForestedLakeshoreNotes": "Be the envy of your Party with your choice spot on the Forested Lakeshore.",
"backgroundDragonsLairText": "Dragon's Lair",
"backgroundWaterMillNotes": "Watch the wheel of the Water Mill go round and round.",
"backgroundWindmillsNotes": "Saddle up and go tilting at Windmills.",
"backgroundGhostShipText": "Ghost Ship",
"backgrounds062021": "SET 85: Released June 2021",
"backgroundRopeBridgeNotes": "Demonstrate to doubters that this Rope Bridge is perfectly safe.",
"backgrounds022022": "SET 93: Released February 2022",
"backgroundWinterWaterfallText": "Winter Waterfall",
"backgroundWinterWaterfallNotes": "Marvel at a Winter Waterfall.",
"backgroundOrangeGroveText": "Orange Grove",
"backgroundOrangeGroveNotes": "Wander through a fragrant Orange Grove.",
"backgroundIridescentCloudsText": "Iridescent Clouds",
"backgroundIridescentCloudsNotes": "Float in Iridescent Clouds.",
"backgroundAutumnLakeshoreNotes": "Pause at an Autumn Lakeshore to appreciate the reflection of woods on water.",
"backgroundStoneTowerNotes": "Gaze from the parapets of one Stone Tower to another.",
"backgroundElegantGardenText": "Elegant Garden",
"backgrounds032022": "SET 94: Released March 2022",
"backgroundAnimalsDenText": "Woodland Critter's Den",
"backgroundAnimalsDenNotes": "Cozy up in a Woodland Critter's Den.",
"backgroundBrickWallWithIvyText": "Brick Wall with Ivy",
"backgroundBrickWallWithIvyNotes": "Admire a Brick Wall with Ivy.",
"backgroundFloweringPrairieText": "Flowering Prairie",
"backgroundFloweringPrairieNotes": "Frolic through a Flowering Prairie.",
"backgrounds052022": "SET 96: Released May 2022",
"backgroundOnACastleWallText": "On A Castle Wall",
"backgroundWindmillsText": "Windmills",
"backgroundAutumnPoplarsText": "Autumn Poplar Forest",
"backgroundRagingRiverText": "Raging River",
"backgroundRagingRiverNotes": "Stand amid the mighty current of a Raging River.",
"backgrounds092021": "SET 88: Released September 2021",
"backgroundAutumnPoplarsNotes": "Delight in the brilliant shades of brown and gold in an Autumn Poplar Forest.",
"backgroundAfternoonPicnicNotes": "Enjoy an Afternoon Picnic alone or with your pet.",
"backgroundDaytimeMistyForestText": "Misty Forest",
"backgroundClotheslineText": "Clothesline",
"backgroundUnderwaterAmongKoiNotes": "Dazzle and be dazzled by glittering carp, Underwater Among Koi.",
"backgroundVineyardText": "Vineyard",
"backgrounds052021": "SET 84: Released May 2021",
"backgrounds072021": "SET 86: Released July 2021",
"backgroundAutumnLakeshoreText": "Autumn Lakeshore",
"backgroundCottageConstructionNotes": "Help out with, or at least supervise, a Cottage Under Construction.",
"backgroundClotheslineNotes": "Hang out with the clothes drying on a Clothesline.",
"backgroundDaytimeMistyForestNotes": "Bathe in the glow of daylight streaming through a Misty Forest.",
"backgrounds122021": "SET 91: Released December 2021",
"backgroundFrozenPolarWatersText": "Frozen Polar Waters",
"backgroundFrozenPolarWatersNotes": "Explore Frozen Polar Waters.",
"backgroundWinterCanyonText": "Winter Canyon",
"backgroundWinterCanyonNotes": "Adventure in a Winter Canyon!",
"backgroundIcePalaceText": "Ice Palace",
"backgroundIcePalaceNotes": "Reign in the Ice Palace.",
"backgrounds012022": "SET 92: Released January 2022",
"backgrounds082021": "SET 87: Released August 2021",
"backgroundUnderwaterAmongKoiText": "Underwater Among Koi",
"backgroundDragonsLairNotes": "Try not to disturb the occupant of the Dragon's Lair.",
"backgroundForestedLakeshoreText": "Forested Lakeshore",
"backgroundAfternoonPicnicText": "Afternoon Picnic",
"backgroundVineyardNotes": "Explore the sprawl of a fruitful Vineyard.",
"backgroundStoneTowerText": "Stone Tower",
"backgroundWaterMillText": "Water Mill",
"backgroundRopeBridgeText": "Rope Bridge",
"backgrounds112021": "SET 90: Released November 2021",
"backgroundFortuneTellersShopText": "Fortune Teller's Shop",
"backgroundFortuneTellersShopNotes": "Seek tantalizing hints of your future in a Fortune Teller's Shop.",
"backgroundInsideAPotionBottleText": "Inside a Potion Bottle",
"backgroundInsideAPotionBottleNotes": "Peer through the glass while hoping for rescue from Inside a Potion Bottle.",
"backgroundSpiralStaircaseText": "Spiral Staircase",
"backgroundSpiralStaircaseNotes": "Climb up, down, round and round a Spiral Staircase.",
"backgrounds042022": "SET 95: Released April 2022",
"backgroundBlossomingTreesText": "Blossoming Trees",
"backgroundBlossomingTreesNotes": "Dally beneath Blossoming Trees.",
"backgroundFlowerShopText": "Flower Shop",
"backgroundFlowerShopNotes": "Enjoy the sweet scent of a Flower Shop.",
"backgroundSpringtimeLakeText": "Springtime Lake",
"backgroundSpringtimeLakeNotes": "Take in the sights along the shores of a Springtime Lake.",
"backgrounds102021": "SET 89: Released October 2021",
"backgroundCrypticCandlesText": "Cryptic Candles",
"backgroundCrypticCandlesNotes": "Summon arcane forces among Cryptic Candles.",
"backgroundHauntedPhotoText": "Haunted Photo",
"backgroundHauntedPhotoNotes": "Find yourself trapped in the monochrome world of a Haunted Photo.",
"backgroundUndeadHandsText": "Undead Hands",
"backgroundUndeadHandsNotes": "Try to escape from the clutches of Undead Hands.",
"backgroundElegantGardenNotes": "Walk the well-manicured paths of an Elegant Garden.",
"backgroundMeteorShowerText": "Meteor Shower",
"backgroundMeteorShowerNotes": "Observe the dazzling nighttime display of a Meteor Shower.",
"backgroundPalmTreeWithFairyLightsText": "Palm Tree with Fairy Lights",
"backgroundPalmTreeWithFairyLightsNotes": "Pose by a Palm Tree bedecked with Fairy Lights.",
"backgroundSnowyFarmText": "Snowy Farm",
"backgroundSnowyFarmNotes": "Check that everyone is well and warm on your Snowy Farm.",
"backgrounds032023": "SET 106: Released March 2023",
"backgroundOldTimeyBasketballCourtText": "Old Timey Basketball Court",
"backgroundOldTimeyBasketballCourtNotes": "Shoot hoops on an Old Timey BasketBall Court.",
"backgroundJungleWateringHoleText": "Jungle Watering Hole",
"backgroundJungleWateringHoleNotes": "Stop for a sip at a Jungle Watering Hole.",
"backgroundMangroveForestText": "Mangrove Forest",
"backgroundMangroveForestNotes": "Explore the edge of the Mangrove Forest.",
"backgrounds032024": "SET 118: Released March 2024",
"backgroundFloweringForestText": "Flowering Forest",
"backgroundFloweringForestNotes": "Breathe in the perfume of a Flowering Forest.",
"backgroundRainyRainforestText": "Rainy Rainforest",
"backgroundRainyRainforestNotes": "Enjoy a refreshing downpour in the Rainy Ranforest.",
"backgroundDogParkText": "Dog Park",
"backgroundDogParkNotes": "Frolic at the Dog Park.",
"backgrounds022024": "SET 117: Released February 2024",
"backgroundColorfulStreetText": "Colorful Street",
"backgroundColorfulStreetNotes": "Viewing a Colorful Street.",
"backgroundSwanBoatText": "Swan Boat",
"backgroundSwanBoatNotes": "Take a ride in a Swan Boat.",
"backgroundHeartTreeTunnelText": "Heart Tree Tunnel",
"backgroundHeartTreeTunnelNotes": "Drift through the Heart Tree Tunnel.",
"backgrounds052023": "SET 108: Released May 2023",
"backgroundInAPaintingText": "In A Painting",
"backgroundInAPaintingNotes": "Enjoy creative pursuits Inside a Painting.",
"backgroundFlyingOverHedgeMazeText": "Flying Over Hedge Maze",
"backgroundFlyingOverHedgeMazeNotes": "Marvel while Flying over a Hedge Maze.",
"backgroundCretaceousForestText": "Cretaceous Forest",
"backgroundCretaceousForestNotes": "Take in the ancient greenery of a Cretaceous Forest.",
"backgrounds112023": "SET 114: Released November 2023",
"backgroundGiantCatText": "Giant Cat",
"backgroundGiantCatNotes": "Take a nap with a Giant Cat.",
"backgroundBarrelCellarText": "Barrel Cellar",
"backgroundBarrelCellarNotes": "Look for culinary delights in a Barrel Cellar.",
"backgroundAutumnTreeTunnelText": "Autumn Tree Tunnel",
"backgroundAutumnTreeTunnelNotes": "Take in the beauty of an Autumn Tree Tunnel.",
"backgrounds042023": "SET 107: Released April 2023",
"backgroundLeafyTreeTunnelText": "Leafy Tree Tunnel",
"backgroundLeafyTreeTunnelNotes": "Wander through a Leafy Tree Tunnel.",
"backgroundSpringtimeShowerText": "Springtime Shower",
"backgroundSpringtimeShowerNotes": "See a Flowery Springtime Shower.",
"backgroundUnderWisteriaText": "Under Wisteria",
"backgroundUnderWisteriaNotes": "Relax Under Wisteria.",
"backgroundForestSunsetText": "Forest Sunset",
"backgroundForestSunsetNotes": "Bask in the glow of a Forest Sunset.",
"backgroundWallFloweringVinesText": "Wall with Flowering Vines",
"backgroundContainerGardenText": "Container Garden",
"backgroundContainerGardenNotes": "Get your hands dirty wth the Container Garden.",
"backgrounds022023": "SET 105: Released February 2023",
"backgroundInFrontOfFountainText": "In Front of a Fountain",
"backgroundInFrontOfFountainNotes": "Stroll In Front of a Fountain.",
"backgroundGoldenBirdcageText": "Golden Birdcage",
"backgroundGoldenBirdcageNotes": "Hide out in a Golden Birdcage.",
"backgroundFancyBedroomText": "Fancy Bedroom",
"backgroundFancyBedroomNotes": "Luxuriate in a Fancy Bedroom.",
"backgrounds072022": "SET 98: Released July 2022",
"backgroundBioluminescentWavesText": "Bioluminescent Waves",
"backgroundBioluminescentWavesNotes": "Admire the glow of Bioluminescent Waves.",
"backgroundUnderwaterCaveText": "Underwater Cave",
"backgroundUnderwaterCaveNotes": "Explore an Underwater Cave.",
"backgroundUnderwaterStatuesText": "Underwater Statue Garden",
"backgroundUnderwaterStatuesNotes": "Try not to blink in an Underwater Statue Garden.",
"backgrounds082023": "SET 111: Released August 2023",
"backgroundBonsaiCollectionText": "Bonsai Collection",
"backgroundBonsaiCollectionNotes": "Admire a gorgeous Bonsai Collection.",
"backgroundDreamyIslandText": "Dreamy Island",
"backgroundDreamyIslandNotes": "Enjoy the scenery on a Dreamy Island.",
"backgroundRockGardenText": "Rock Garden",
"backgroundRockGardenNotes": "Relax in a Rock Garden.",
"backgrounds122023": "SET 115: Released December 2023",
"backgroundHolidayTreeForestText": "Holiday Tree Forest",
"backgroundHolidayTreeForestNotes": "Decorate a Holiday Tree in a Forest.",
"backgroundIceSculptureFestivalText": "Ice Sculpture Festival",
"backgroundIceSculptureFestivalNotes": "Tour an Ice Sculpture Festival.",
"backgroundWinterFullMoonText": "WinterFullMoon",
"backgroundWinterFullMoonNotes": "Gaze at the Winter Full Moon.",
"backgrounds042024": "SET 119: Released April 2024",
"backgroundWallFloweringVinesNotes": "Hang out by a wall of Flowering Vines.",
"backgrounds012024": "SET 116: Released January 2024",
"backgroundWinterMountainRangeText": "Winter Mountain Range",
"backgroundWinterMountainRangeNotes": "Climb a Winter Mountain Range.",
"backgroundFrozenBluePondText": "Frozen Blue Pond",
"backgroundFrozenBluePondNotes": "Chill out by the Frozen Blue Pond.",
"backgroundIceBubbleLakeText": "Ice Bubble Lake",
"backgroundIceBubbleLakeNotes": "Stand carefully on the Ice Bubble Lake.",
"backgrounds052024": "SET 120: Released May 2024",
"backgroundDragonsBackText": "Dragon's Back",
"backgroundDragonsBackNotes": "Sail the sky on a Dragon's Back.",
"backgroundMaypoleText": "Maypole",
"backgroundMaypoleNotes": "Dance around a merry Maypole.",
"backgroundPottersStudioText": "Potter's Studio",
"backgroundPottersStudioNotes": "Create art in the Potter's Studio.",
"backgroundBirthdayBashText": "Birthday Bash",
"backgroundBirthdayBashNotes": "Habitica's having a birthday party, and everyone's invited!",
"backgrounds082022": "SET 99: Released August 2022",
"backgroundRainbowEucalyptusText": "Rainbow Eucalyptus",
"backgroundRainbowEucalyptusNotes": "Admire a Rainbow Eucalyptus grove.",
"backgroundMessyRoomText": "Messy Room",
"backgroundMessyRoomNotes": "Tidy up a Messy Room.",
"backgroundByACampfireText": "By A Campfire",
"backgroundByACampfireNotes": "Bask in the glow By a Campfire.",
"backgroundOnACastleWallNotes": "Look out from On a Castle Wall.",
"backgroundCastleGateText": "Castle Gate",
"backgroundCastleGateNotes": "Stand guard at the Castle Gate.",
"backgroundEnchantedMusicRoomText": "Enchanted Music Room",
"backgroundEnchantedMusicRoomNotes": "Play in an Enchanted Music Room.",
"backgrounds092022": "SET 100: Released September 2022",
"backgroundTheatreStageText": "Theatre Stage",
"backgroundTheatreStageNotes": "Perform on a Theatre Stage.",
"backgroundAutumnPicnicText": "Autumn Picnic",
"backgroundAutumnPicnicNotes": "Enjoy an Autumn Picnic.",
"backgroundOldPhotoText": "Old Photo",
"backgroundOldPhotoNotes": "Strike a pose in an Old Photo.",
"backgrounds012023": "SET 104: Released January 2023",
"backgroundRimeIceText": "Rime Ice",
"backgroundRimeIceNotes": "Admire sparkly Rime Ice.",
"backgroundSnowyTempleText": "Snowy Temple",
"backgroundSnowyTempleNotes": "View a serene Snowy Temple.",
"backgroundWinterLakeWithSwansText": "Winter Lake With Swans",
"backgroundWinterLakeWithSwansNotes": "Enjoy nature at a Winter Lake With Swans.",
"backgroundMistyAutumnForestNotes": "Wander through a Misty Autumn Forest.",
"backgrounds112022": "SET 102: Released November 2022",
"backgroundAmongGiantMushroomsText": "Among Giant Mushrooms",
"backgroundAmongGiantMushroomsNotes": "Marvel at Giant Mushrooms.",
"backgroundMistyAutumnForestText": "Misty Autumn Forest",
"backgroundAutumnBridgeText": "Bridge in Autumn",
"backgroundAutumnBridgeNotes": "Admire the beauty of a Bridge in Autumn.",
"backgrounds102022": "SET 101: Released October 2022",
"backgroundSpookyRuinsText": "Spooky Ruins",
"backgroundSpookyRuinsNotes": "Explore some Spooky Ruins.",
"backgroundMaskMakersWorkshopText": "Mask Maker's Workshop",
"backgroundMaskMakersWorkshopNotes": "Try on a new face at the Mask Maker's Workshop.",
"backgroundCemeteryGateText": "Cemetery Gate",
"backgroundCemeteryGateNotes": "Haunt a Cemetery Gate.",
"backgrounds062022": "SET 97: Released June 2022",
"backgroundBeachWithDunesText": "Beach With Dunes",
"backgroundBeachWithDunesNotes": "Explore a beach with dunes.",
"backgroundMountainWaterfallText": "Mountain Waterfall",
"backgroundMountainWaterfallNotes": "Admire a mountain waterfall.",
"backgroundSailboatAtSunsetText": "Sailboat At Sunset",
"backgroundSailboatAtSunsetNotes": "Enjoy the beauty of a sailboat at sunset.",
"backgrounds122022": "SET 103: Released December 2022",
"backgroundBranchesOfAHolidayTreeText": "Branches of a Holiday Tree",
"backgroundSnowyVillageText": "Snowy Village",
"backgroundBranchesOfAHolidayTreeNotes": "Frolic on the Branches of a Holiday Tree.",
"backgroundInsideACrystalText": "Inside A Crystal",
"backgroundInsideACrystalNotes": "Peer out from Inside A Crystal.",
"backgroundSnowyVillageNotes": "Admire a Snowy Village.",
"backgrounds092023": "SET 112: Released September 2023",
"backgroundMovingDayText": "Moving Day",
"backgroundMovingDayNotes": "Pack up for Moving Day.",
"backgroundCoveredBridgeInAutumnText": "Covered Bridge in Autumn",
"backgroundCoveredBridgeInAutumnNotes": "Traverse a Covered Bridge in Autumn.",
"backgroundBaobabForestText": "Baobab Forest",
"backgroundBaobabForestNotes": "Gaze in wonder at the Baobab Forest.",
"backgrounds062023": "SET 109: Released June 2023",
"backgroundInAnAquariumText": "In an Aquarium",
"backgroundInAnAquariumNotes": "Take a peaceful swim with the fish In an Aquarium.",
"backgroundInsideAdventurersHideoutText": "Inside an Adventurer's Hideout",
"backgroundInsideAdventurersHideoutNotes": "Plan a journey inside an Adventurer's Hideout.",
"backgroundCraterLakeText": "Crater Lake",
"backgroundCraterLakeNotes": "Admire a lovely Crater Lake.",
"eventBackgrounds": "Event Backgrounds",
"backgrounds072023": "SET 110: Released July 2023",
"backgroundOnAPaddlewheelBoatText": "On a Paddlewheel Boat",
"backgroundOnAPaddlewheelBoatNotes": "Ride on a Paddlewheel Boat.",
"backgroundColorfulCoralText": "Colorful Coral",
"backgroundColorfulCoralNotes": "Dive among Colorful Coral.",
"backgroundBoardwalkIntoSunsetText": "Boardwalk into the Sunset",
"backgroundBoardwalkIntoSunsetNotes": "Stroll on a Boardwalk into the Sunset.",
"backgrounds102023": "SET 113: Released October 2023",
"backgroundSpectralCandleRoomText": "Room of Spectral Candles",
"backgroundSpectralCandleRoomNotes": "Commune with spirits in a Room of Spectral Candles.",
"backgroundMonstrousCaveText": "Monstrous Cave",
"backgroundMonstrousCaveNotes": "Gaze into the maw of the Monstrous Cave.",
"backgroundJackOLanternStacksText": "Jack O'Lantern Stacks",
"backgroundJackOLanternStacksNotes": "Admire a field of Jack OLantern Stacks."
}

View File

@@ -94,15 +94,27 @@
"summaryRequired": "Summary is required",
"summaryTooLong": "Summary is too long",
"descriptionRequired": "Description is required",
"locationRequired": "Location of challenge is required ('Add to')",
"locationRequired": "Location of Challenge is required ('Add to')",
"categoiresRequired": "One or more categories must be selected",
"viewProgressOf": "View Progress Of",
"viewProgress": "View Progress",
"selectMember": "Select Member",
"confirmKeepChallengeTasks": "Do you want to keep challenge tasks?",
"confirmKeepChallengeTasks": "Do you want to keep Challenge tasks?",
"selectParticipant": "Select a Participant",
"filters": "Filters",
"wonChallengeDesc": "<%= challengeName %> selected you as the winner! Your win has been recorded in your Achievements.",
"yourReward": "Your Reward",
"removeTasks": "Remove Tasks"
"removeTasks": "Remove Tasks",
"messageChallengeFlagOfficial": "Official Challenges can not be reported.",
"resetFlagCount": "Reset Flag Count",
"whyReportingChallenge": "Why are you reporting this Challenge?",
"whyReportingChallengePlaceholder": "Reason for report",
"flaggedAndHidden": "Challenge flagged and hidden",
"messageChallengeFlagAlreadyReported": "You have already reported this Challenge.",
"flaggedNotHidden": "Challenge flagged once, not hidden",
"cannotClone": "This Challenge cannot be cloned because one or more players have reported it as inappropriate. A staff member will contact you shortly with instructions. If over 48 hours have passed and you have not heard from them, please email admin@habitica.com for assistance.",
"resetFlags": "Reset Flags",
"cannotClose": "This Challenge cannot be closed because one or more players have reported it as inappropriate. A staff members will contact you shortly with instructions. If over 48 hours have passed and you have not heard from them, please email admin@habitica.com for assistance.",
"abuseFlagModalBodyChallenge": "You should only report a Challenge that violates the <%= firstLinkStart %>Community Guidelines<%= linkEnd %> and/or <%= secondLinkStart %>Terms of Service<%= linkEnd %>. Submitting a false report is a violation of Habitica's Community Guidelines.",
"cannotMakeChallenge": "You are unable to create public Challenges as your account currently does not have chat privileges. Please contact admin@habitica.com for more information."
}

View File

@@ -85,7 +85,7 @@
"allocatePerPop": "Add a Point to Perception",
"allocateInt": "Points allocated to Intelligence:",
"allocateIntPop": "Add a Point to Intelligence",
"noMoreAllocate": "Now that you've hit level 100, you won't gain any more Stat Points. You can continue levelling up, or start a new adventure at level 1 by using the <a href='http://habitica.fandom.com/wiki/Orb_of_Rebirth' target='_blank'>Orb of Rebirth</a>!",
"noMoreAllocate": "Now that you've hit level 100, you won't gain any more Stat Points. You can continue levelling up, or start a new adventure at level 1 by using the <a href='https://habitica.fandom.com/wiki/Orb_of_Rebirth' target='_blank'>Orb of Rebirth</a>!",
"stats": "Stats",
"achievs": "Achievements",
"strength": "Strength",
@@ -170,8 +170,8 @@
"photo": "Photo",
"info": "Info",
"joined": "Joined",
"totalLogins": "Total Check Ins",
"latestCheckin": "Latest Check In",
"totalLogins": "Total Log Ins",
"latestCheckin": "Latest Log In",
"editProfile": "Edit Profile",
"challengesWon": "Challenges Won",
"questsCompleted": "Quests Completed",
@@ -185,5 +185,9 @@
"chatCastSpellUser": "<%= username %> casts <%= spell %> on <%= target %>.",
"chatCastSpellParty": "<%= username %> casts <%= spell %> for the party.",
"purchasePetItemConfirm": "This purchase would exceed the number of items you need to hatch all possible <%= itemText %> pets. Are you sure?",
"purchaseForGold": "Purchase for <%= cost %> Gold?"
"purchaseForGold": "Purchase for <%= cost %> Gold?",
"notEnoughGold": "Not enough gold.",
"chatCastSpellPartyTimes": "<%= username %> casts <%= spell %> for the party <%= times %> times.",
"chatCastSpellUserTimes": "<%= username %> casts <%= spell %> on <%= target %> <%= times %> times.",
"nextReward": "Next Log In Reward"
}

View File

@@ -37,35 +37,35 @@
"commGuidePara038": "<strong>All Tavern Challenges and Public Guild Challenges must comply with these rules as well</strong>.",
"commGuideHeadingInfractionsEtc": "Infractions, Consequences, and Restoration",
"commGuideHeadingInfractions": "Infractions",
"commGuidePara050": "Overwhelmingly, Habiticans assist each other, are respectful, and work to make the whole community fun and friendly. However, once in a blue moon, something that a Habitican does may violate one of the above guidelines. When this happens, the Mods will take whatever actions they deem necessary to keep Habitica safe and comfortable for everyone.",
"commGuidePara051": "<strong>There are a variety of infractions, and they are dealt with depending on their severity</strong>. These are not comprehensive lists, and the Mods can make decisions on topics not covered here at their own discretion. The Mods will take context into account when evaluating infractions.",
"commGuidePara050": "Overwhelmingly, Habiticans assist each other, are respectful, and work to make the atmosphere here fun and friendly. However, once in a blue moon, something that a Habitican does may violate one of the above Guidelines. When this happens, the Staff will take whatever actions they deem necessary to keep Habitica safe and comfortable for everyone.",
"commGuidePara051": "<strong>There are a variety of infractions, and they are dealt with depending on their severity</strong>. These are not comprehensive lists, and the Staff can make decisions on topics not covered here at their own discretion. The Staff will take context into account when evaluating infractions.",
"commGuideHeadingSevereInfractions": "Severe Infractions",
"commGuidePara052": "Severe infractions greatly harm the safety of Habitica's community and users, and therefore have severe consequences as a result.",
"commGuidePara053": "The following are examples of some severe infractions. This is not a comprehensive list.",
"commGuideList05A": "Violation of Terms and Conditions",
"commGuideList05A": "Other breaches of the Terms and Conditions not specified here",
"commGuideList05B": "Hate Speech/Images, Harassment/Stalking, Cyber-Bullying, Flaming, and Trolling",
"commGuideList05C": "Violation of Probation",
"commGuideList05D": "Impersonation of Staff or Moderators",
"commGuideList05D": "Impersonation of Staff - this includes claiming player-created spaces not affiliated with Habitica are official and/or moderated by Habitica or its Staff",
"commGuideList05E": "Repeated Moderate Infractions",
"commGuideList05F": "Creation of a duplicate account to avoid consequences (for example, making a new account to chat after having chat privileges revoked)",
"commGuideList05G": "Intentional deception of Staff or Moderators in order to avoid consequences or to get another user in trouble",
"commGuideList05F": "Creation of a duplicate account to avoid consequences",
"commGuideList05G": "Intentional deception of Staff in order to avoid consequences or to get another user in trouble",
"commGuideHeadingModerateInfractions": "Moderate Infractions",
"commGuidePara054": "Moderate infractions do not make our community unsafe, but they do make it unpleasant. These infractions will have moderate consequences. When in conjunction with multiple infractions, the consequences may grow more severe.",
"commGuidePara054": "These infractions will have moderate consequences. When in conjunction with multiple infractions, the consequences may grow more severe.",
"commGuidePara055": "The following are some examples of Moderate Infractions. This is not a comprehensive list.",
"commGuideList06A": "Ignoring, disrespecting or arguing with a Mod. This includes publicly complaining about moderators or other users, publicly glorifying or defending banned users, or debating whether or not a moderator action was appropriate. If you are concerned about one of the rules or the behaviour of the Mods, please contact the staff via email (<a href='mailto:admin@habitica.com' target='_blank'>admin@habitica.com</a>).",
"commGuideList06A": "Ignoring, disrespecting or arguing with Staff. If you are concerned about one of the rules or the behavior of the staff, please contact us at <a href='mailto:admin@habitica.com' target='_blank'>admin@habitica.com</a>.",
"commGuideList06B": "Backseat Modding. To quickly clarify a relevant point: A friendly mention of the rules is fine. Backseat modding consists of telling, demanding, and/or strongly implying that someone must take an action that you describe to correct a mistake. You can alert someone to the fact that they have committed a transgression, but please do not demand an action -- for example, saying, \"Just so you know, profanity is discouraged in the Tavern, so you may want to delete that,\" would be better than saying, \"I'm going to have to ask you to delete that post.\"",
"commGuideList06C": "Intentionally flagging innocent posts.",
"commGuideList06C": "Intentionally flagging innocent Challenges, profiles, or messages.",
"commGuideList06D": "Repeatedly Violating Public Space Guidelines",
"commGuideList06E": "Repeatedly Committing Minor Infractions",
"commGuideHeadingMinorInfractions": "Minor Infractions",
"commGuidePara056": "Minor Infractions, while discouraged, still have minor consequences. If they continue to occur, they can lead to more severe consequences over time.",
"commGuidePara056": "Minor Infractions, while discouraged, still have minor consequences. If they continue to occur, they can lead to more severe consequences over time. Minor infractions are typically first time violations of these Guidelines but may include other circumstances.",
"commGuidePara057": "The following are some examples of Minor Infractions. This is not a comprehensive list.",
"commGuideList07A": "First-time violation of Public Space Guidelines",
"commGuideList07B": "Any statements or actions that trigger a \"Please Don't\". When a Mod has to say \"Please don't do this\" to a user, it can count as a very minor infraction for that user. An example might be \"Please don't keep arguing in favour of this feature idea after we've told you several times that it isn't feasible.\" In many cases, the Please Don't will be the minor consequence as well, but if Mods have to say \"Please Don't\" to the same user enough times, the triggering Minor Infractions will start to count as Moderate Infractions.",
"commGuideList07B": "Any statements or actions that trigger a \"Please Don't\" from a Staff member. When you are asked not to do something publicly, this in itself can be a consequence. If Staff have to issue many of these corrections to the same person, it may count as a larger infraction",
"commGuidePara057A": "Some posts may be hidden because they contain sensitive information or might give people the wrong idea. Typically this does not count as an infraction, particularly not the first time it happens!",
"commGuideHeadingConsequences": "Consequences",
"commGuidePara058": "In Habitica -- as in real life -- every action has a consequence, whether it is getting fit because you've been running, getting cavities because you've been eating too much sugar, or passing a class because you've been studying.",
"commGuidePara059": "<strong>Similarly, all infractions have direct consequences.</strong> Some sample consequences are outlined below.",
"commGuidePara059": "<strong>Community infractions have direct consequences.</strong> Some sample consequences are outlined below.",
"commGuidePara060": "<strong>If your infraction has a moderate or severe consequence, there will be a post from a staff member or moderator in the forum in which the infraction occurred explaining</strong>:",
"commGuideList08A": "what your infraction was",
"commGuideList08B": "what the consequence is",
@@ -73,28 +73,28 @@
"commGuidePara060A": "If the situation calls for it, you may receive a PM or email as well as a post in the forum in which the infraction occurred. In some cases you may not be reprimanded in public at all.",
"commGuidePara060B": "If your account is banned (a severe consequence), you will not be able to log into Habitica and will receive an error message upon attempting to log in. <strong>If you wish to apologise or make a plea for reinstatement, please email the staff at <a href='mailto:admin@habitica.com' target='_blank'>admin@habitica.com</a> with your UUID</strong> (which will be given in the error message). It is <strong>your</strong> responsibility to reach out if you desire reconsideration or reinstatement.",
"commGuideHeadingSevereConsequences": "Examples of Severe Consequences",
"commGuideList09A": "Account bans (see above)",
"commGuideList09C": "Permanently disabling (\"freezing\") progression through Contributor Tiers",
"commGuideList09A": "Account bans",
"commGuideList09C": "Permanently stopping progression through Contributor Tiers",
"commGuideHeadingModerateConsequences": "Examples of Moderate Consequences",
"commGuideList10A": "Restricted public and/or private chat privileges",
"commGuideList10A1": "If your actions result in revocation of your chat privileges, a Moderator or Staff member will PM you and/or post in the forum in which you were muted to notify you of the reason for your muting and the length of time for which you will be muted. At the end of that period, you will receive your chat privileges back, provided you are willing to correct the behavior for which you were muted and comply with the Community Guidelines.",
"commGuideList10C": "Restricted Guild/Challenge creation privileges",
"commGuideList10D": "Temporarily disabling (\"freezing\") progression through Contributor Tiers",
"commGuideList10D": "Temporarily pausing progression through Contributor Tiers",
"commGuideList10E": "Demotion of Contributor Tiers",
"commGuideList10F": "Putting users on \"Probation\"",
"commGuideHeadingMinorConsequences": "Examples of Minor Consequences",
"commGuideList11A": "Reminders of Public Space Guidelines",
"commGuideList11A": "Reminders of Guidelines",
"commGuideList11B": "Warnings",
"commGuideList11C": "Requests",
"commGuideList11D": "Deletions (Mods/Staff may delete problematic content)",
"commGuideList11E": "Edits (Mods/Staff may edit problematic content)",
"commGuideList11D": "Deletion of problematic content by Staff",
"commGuideList11E": "Edits of problematic content by Staff",
"commGuideHeadingRestoration": "Restoration",
"commGuidePara061": "Habitica is a land devoted to self-improvement, and we believe in second chances. <strong>If you commit an infraction and receive a consequence, view it as a chance to evaluate your actions and strive to be a better member of the community</strong>.",
"commGuidePara062": "The announcement, message, and/or email that you receive explaining the consequences of your actions is a good source of information. Cooperate with any restrictions which have been imposed, and endeavour to meet the requirements to have any penalties lifted.",
"commGuidePara063": "If you do not understand your consequences, or the nature of your infraction, ask the Staff/Moderators for help so you can avoid committing infractions in the future. If you feel a particular decision was unfair, you can contact the staff to discuss it at <a href='mailto:admin@habitica.com' target='_blank'>admin@habitica.com</a>.",
"commGuideHeadingMeet": "Meet the Staff and Mods!",
"commGuidePara061": "Habitica is devoted to self-improvement, and we believe in second chances. <strong>If you commit an infraction and receive a consequence, view it as a chance to evaluate your actions and strive to be a better member of the community</strong>.",
"commGuidePara062": "<strong>If you wish to ask questions about your infraction or consequences, apologize, or make a plea for reinstatement, please contact us at <a href='mailto:admin@habitica.com' target='_blank'>admin@habitica.com</a> with your User ID or @username</strong>. It is <strong>your</strong> responsibility to reach out.",
"commGuidePara063": "If you do not understand your consequences or the nature of your infraction, or if you have other questions related to the matter, you can contact the staff to discuss it at <a href='mailto:admin@habitica.com' target='_blank'>admin@habitica.com</a>. Cooperate with any restrictions which have been imposed, and endeavor to meet the requirements to have any penalties lifted.",
"commGuideHeadingMeet": "Meet the Staff",
"commGuidePara006": "Habitica has some tireless knights-errant who join forces with the staff members to keep the community calm, contented, and free of trolls. Each has a specific domain, but will sometimes be called to serve in other social spheres.",
"commGuidePara007": "Staff have purple tags marked with crowns. Their title is \"Heroic\".",
"commGuidePara007": "The Habitica Staff keep the app and sites running and can act as chat moderators. They have purple tags marked with crowns. Their title is \"Heroic\".",
"commGuidePara008": "Mods have dark blue tags marked with stars. Their title is \"Guardian\". The only exception is Bailey, who, as an NPC, has a black and green tag marked with a star.",
"commGuidePara009": "The current Staff Members are (from left to right):",
"commGuideAKA": "<%= habitName %> aka <%= realName %>",
@@ -102,19 +102,19 @@
"commGuideOnGitHub": "<%= gitHubName %> on GitHub",
"commGuidePara010": "There are also several Moderators who assist the staff members. They were selected carefully, so please give them your respect and listen to their suggestions.",
"commGuidePara011": "The current Moderators are (from left to right):",
"commGuidePara011b": "on GitHub/Wikia",
"commGuidePara011c": "on Wikia",
"commGuidePara011b": "on GitHub/Fandom",
"commGuidePara011c": "on the Wiki",
"commGuidePara011d": "on GitHub",
"commGuidePara012": "If you have an issue or concern about a particular Mod, please send an email to our Staff (<a href='mailto:admin@habitica.com' target='_blank'>admin@habitica.com</a>).",
"commGuidePara013": "In a community as big as Habitica, users come and go, and sometimes a staff member or moderator needs to lay down their noble mantle and relax. The following are Staff and Moderators Emeritus. They no longer act with the power of a Staff member or Moderator, but we would still like to honour their work!",
"commGuidePara013": "In a community as big as Habitica, players come and go, and sometimes a Staff member or moderator needs to lay down their noble mantle and relax. The following are Staff and Moderators Emeritus. They no longer act with the power of a Staff member or Moderator, but we would still like to honor their work!",
"commGuidePara014": "Staff and Moderators Emeritus:",
"commGuideHeadingFinal": "The Final Section",
"commGuidePara067": "So there you have it, brave Habitican -- the Community Guidelines! Wipe that sweat off of your brow and give yourself some XP for reading it all. If you have any questions or concerns about these Community Guidelines, please reach out to us via the <a href='https://contact.habitica.com/' target='_blank'>Moderator Contact Form</a> and we will be happy to help clarify things.",
"commGuidePara067": "So there you have it, brave Habitican -- the Community Guidelines! Wipe that sweat off of your brow and give yourself some EXP for reading it all. If you have any questions or concerns about these Community Guidelines, please reach out to us via <a href='mailto:admin@habitica.com' target='_blank'>admin@habitica.com</a> and we will be happy to help clarify things.",
"commGuidePara068": "Now go forth, brave adventurer, and slay some Dailies!",
"commGuideHeadingLinks": "Useful Links",
"commGuideLink01": "<a href='/groups/guild/5481ccf3-5d2d-48a9-a871-70a7380cee5a' target='_blank'>Habitica Help: Ask a Question</a>: a Guild for users to ask questions!",
"commGuideLink02": "<a href='http://habitica.fandom.com/wiki/Habitica_Wiki' target='_blank'>The Wiki</a>: the biggest collection of information about Habitica.",
"commGuideLink03": "<a href='https://github.com/HabitRPG/habitica' target='_blank'>GitHub</a>: for bug reports or helping with code!",
"commGuideLink02": "<a href='https://habitica.fandom.com/wiki/Habitica_Wiki' target='_blank'>The Wiki</a>: the biggest collection of information about Habitica. Note that this space is unofficial, being hosted by Fandom and maintained by players.",
"commGuideLink03": "<a href='https://github.com/HabitRPG/habitica' target='_blank'>GitHub</a>: for helping with code!",
"commGuideLink04": "<a href='https://docs.google.com/forms/d/e/1FAIpQLScPhrwq_7P1C6PTrI3lbvTsvqGyTNnGzp1ugi1Ml0PFee_p5g/viewform?usp=sf_link' target='_blank'>The Feedback Form</a>: for site and app feature requests.",
"commGuideLink05": "<a href='https://trello.com/b/mXK3Eavg/' target='_blank'>The Mobile Trello</a>: for mobile feature requests.",
"commGuideLink06": "<a href='https://trello.com/b/vwuE9fbO/' target='_blank'>The Art Trello</a>: for submitting pixel art.",
@@ -128,5 +128,9 @@
"commGuideList02P": "<strong>We discourage the sending of unsolicited private messages</strong>. If you receive an unwanted message that makes you uncomfortable or that breaks these Guidelines or the Terms of Service, please block the sender and report it to bring it to Staff attention.",
"commGuideList02N": "<strong>Report anything you see that breaks these Guidelines or our Terms of Service</strong>. You can report a message directly or notify staff via <a href='mailto:admin@habitica.com' target='_blank'>admin@habitica.com</a> for violations in profiles or Challenges. We will handle them as quickly as possible. You may contact us in your native language if that is easier for you: we may have to use Google Translate, but we want you to feel comfortable about contacting us if you have a problem.",
"commGuideList02Q": "<strong>Do not try to get around a block</strong>. If someone has blocked you from sending them private messages, do not contact them elsewhere to ask them to unblock you.",
"commGuideList02M": "<strong>Do not ask or beg for Gems, subscriptions, or membership in Group Plans</strong>. If you see or receive unwanted messages asking for paid items, please report them. Repeated Gem or subscription begging, especially after a warning, may result in an account ban."
"commGuideList02M": "<strong>Do not ask or beg for Gems, subscriptions, or membership in Group Plans</strong>. If you see or receive unwanted messages asking for paid items, please report them. Repeated Gem or subscription begging, especially after a warning, may result in an account ban.",
"commGuideList09D": "Removal or demotion of Contributor Tiers",
"commGuideList09E": "Permanent removal of ability to send private messages or appear in Party member search",
"commGuideList10G": "Temporary disabling of ability to send private messages or appear in Party member search",
"commGuideList05H": "Severe or repeated attempts to defraud or pressure other players for real-money items"
}

View File

@@ -370,5 +370,11 @@
"hatchingPotionMossyStone": "Mossy Stone",
"hatchingPotionSolarSystem": "Solar System",
"hatchingPotionMoonglow": "Moonglow",
"hatchingPotionOnyx": "Onyx"
"hatchingPotionOnyx": "Onyx",
"hatchingPotionRoseGold": "Rose Gold",
"hatchingPotionFungi": "Fungi",
"hatchingPotionPorcelain": "Porcelain",
"hatchingPotionVirtualPet": "Virtual Pet",
"hatchingPotionPinkMarble": "Pink Marble",
"hatchingPotionTeaShop": "Tea Shop"
}

View File

@@ -49,9 +49,10 @@
"balance": "Balance",
"playerTiers": "Player Tiers",
"tier": "Tier",
"conRewardsURL": "http://habitica.fandom.com/wiki/Contributor_Rewards",
"conRewardsURL": "https://habitica.fandom.com/wiki/Contributor_Rewards",
"surveysSingle": "Helped Habitica grow, either by filling out a survey or helping with a major testing effort. Thank you!",
"surveysMultiple": "Helped Habitica grow on <%= count %> occasions, either by filling out a survey or helping with a major testing effort. Thank you!",
"blurbHallPatrons": "This is the Hall of Patrons, where we honour the noble adventurers who backed Habitica's original Kickstarter. We thank them for helping us bring Habitica to life!",
"blurbHallContributors": "This is the Hall of Contributors, where open-source contributors to Habitica are honored. Whether through code, art, music, writing, or even just helpfulness, they have earned <a href='http://habitica.fandom.com/wiki/Contributor_Rewards' target='_blank'> gems, exclusive equipment</a>, and <a href='http://habitica.fandom.com/wiki/Contributor_Titles' target='_blank'>prestigious titles</a>. You can contribute to Habitica, too! <a href='http://habitica.fandom.com/wiki/Contributing_to_Habitica' target='_blank'> Find out more here. </a>"
"blurbHallContributors": "This is the Hall of Contributors, where open-source contributors to Habitica are honored. Whether through code, art, music, writing, or even just helpfulness, they have earned <a href='https://habitica.fandom.com/wiki/Contributor_Rewards' target='_blank'> gems, exclusive equipment</a>, and <a href='https://habitica.fandom.com/wiki/Contributor_Titles' target='_blank'>prestigious titles</a>. You can contribute to Habitica, too! <a href='https://habitica.fandom.com/wiki/Contributing_to_Habitica' target='_blank'> Find out more here. </a>",
"noPrivAccess": "You don't have the required privileges."
}

View File

@@ -34,7 +34,7 @@
"marketing1Lead2": "Improve your habits to build up your avatar. Show off the sweet gear you've earned!",
"marketing1Lead3Title": "Find Random Prizes",
"marketing1Lead3": "For some, it's the gamble that motivates them: a system called \"stochastic rewards.\" Habitica accommodates all reinforcement and punishment styles: positive, negative, predictable, and random.",
"marketing2Header": "Compete With Friends, Join Interest Groups",
"marketing2Header": "Compete with Friends",
"marketing2Lead1Title": "Social Productivity",
"marketing2Lead1": "While you can play Habitica solo, the lights really turn on when you start collaborating, competing, and holding each other accountable. The most effective part of any self-improvement program is social accountability, and what better an environment for accountability and competition than a video game?",
"marketing2Lead2Title": "Fight Monsters",
@@ -44,7 +44,7 @@
"marketing3Header": "Apps and Extensions",
"marketing3Lead1": "The **iPhone & Android** apps let you take care of business on the go. We realise that logging into the website to click buttons can be a drag.",
"marketing3Lead2Title": "Integrations",
"marketing3Lead2": "Other **3rd Party Tools** tie Habitica into various aspects of your life. Our API provides easy integration for things like the [Chrome Extension](https://chrome.google.com/webstore/detail/habitica/pidkmpibnnnhneohdgjclfdjpijggmjj?hl=en-US), for which you lose points when browsing unproductive websites, and gain points when on productive ones. [See more here](http://habitica.fandom.com/wiki/Extensions,_Add-Ons,_and_Customizations).",
"marketing3Lead2": "Other **3rd Party Tools** tie Habitica into various aspects of your life. Our API provides easy integration for things like the [Chrome Extension](https://chrome.google.com/webstore/detail/habitica/pidkmpibnnnhneohdgjclfdjpijggmjj?hl=en-US), for which you lose points when browsing unproductive websites, and gain points when on productive ones. [See more here](https://habitica.fandom.com/wiki/Extensions,_Add-Ons,_and_Customizations).",
"marketing4Header": "Organisational Use",
"marketing4Lead1": "Education is one of the best sectors for gamification. We all know how glued to phones and games students are these days; harness that power! Pit your students against each other in friendly competition. Reward good behavior with rare prizes. Watch their grades and behavior soar.",
"marketing4Lead1Title": "Gamification In Education",
@@ -53,8 +53,8 @@
"marketing4Lead3-1": "Want to gamify your life?",
"marketing4Lead3-2": "Interested in running a group in education, wellness, and more?",
"marketing4Lead3Title": "Gamify Everything",
"mobileAndroid": "Android",
"mobileIOS": "iOS",
"mobileAndroid": "Android App",
"mobileIOS": "iOS App",
"oldNews": "News",
"newsArchive": "News archive on Wikia (multilingual)",
"setNewPass": "Set New Password",
@@ -66,9 +66,9 @@
"pkQuestion1": "What inspired Habitica? How did it start?",
"pkAnswer1": "If youve ever invested time in leveling up a character in a game, its hard not to wonder how great your life would be if you put all of that effort into improving your real-life self instead of your avatar. We starting building Habitica to address that question. <br /> Habitica officially launched with a Kickstarter in 2013, and the idea really took off. Since then, its grown into a huge project, supported by our awesome open-source volunteers and our generous users.",
"pkQuestion2": "Why does Habitica work?",
"pkAnswer2": "Forming a new habit is hard because people really need that obvious, instant reward. For example, its tough to start flossing, because even though our dentist tells us that it's healthier in the long run, in the immediate moment it just makes your gums hurt. <br /> Habitica's gamification adds a sense of instant gratification to everyday objectives by rewarding a tough task with experience, gold… and maybe even a random prize, like a dragon egg! This helps keep people motivated even when the task itself doesn't have an intrinsic reward, and we've seen people turn their lives around as a result. You can check out success stories here: https://habitversary.tumblr.com",
"pkAnswer2": "Forming a new habit is hard because people really need that obvious, instant reward. For example, its tough to start flossing, because even though our dentist tells us that it's healthier in the long run, in the immediate moment it just makes your gums hurt. <br /> Habitica's gamification adds a sense of instant gratification to everyday objectives by rewarding a tough task with experience, gold… and maybe even a random prize, like a dragon egg! This helps keep people motivated even when the task itself doesn't have an intrinsic reward, and we've seen people turn their lives around as a result.",
"pkQuestion3": "Why did you add social features?",
"pkAnswer3": "Social pressure is a huge motivating factor for a lot of people, so we knew that we wanted to have a strong community that would hold each other accountable for their goals and cheer for their successes. Luckily, one of the things that multiplayer video games do best is foster a sense of community among their users! Habiticas community structure borrows from these types of games; you can form a small Party of close friends, but you can also join a larger, shared-interest groups known as a Guild. Although some users choose to play solo, most decide to form a support network that encourages social accountability through features such as Quests, where Party members pool their productivity to battle monsters together.",
"pkAnswer3": "Social pressure is a huge motivating factor for a lot of people, so we knew that we wanted to have a strong community that would hold each other accountable for their goals and cheer for their successes. Luckily, one of the things that multiplayer video games do best is foster a sense of community among their users! Habiticas community structure borrows from these types of games. Although some users choose to play solo, most decide to form a support network in a small Party of close friends that encourages social accountability through features such as Quests, where Party members pool their productivity to battle monsters together.",
"pkQuestion4": "Why does skipping tasks remove your avatars health?",
"pkAnswer4": "If you skip one of your daily goals, your avatar will lose health the following day. This serves as an important motivating factor to encourage people to follow through with their goals because people really hate hurting their little avatar! Plus, the social accountability is critical for a lot of people: if youre fighting a monster with your friends, skipping your tasks hurts their avatars, too.",
"pkQuestion5": "What distinguishes Habitica from other gamification programs?",
@@ -117,19 +117,19 @@
"missingPassword": "Missing password.",
"missingNewPassword": "Missing new password.",
"invalidEmailDomain": "You cannot register with emails with the following domains: <%= domains %>",
"wrongPassword": "Wrong password.",
"wrongPassword": "Password is incorrect. If you forgot your password, click \"Forgot Password.\"",
"incorrectDeletePhrase": "Please type <%= magicWord %> in all capital letters to delete your account.",
"notAnEmail": "Invalid email address.",
"emailTaken": "Email address is already used in an account.",
"newEmailRequired": "Missing new email address.",
"usernameTime": "It's time to set your username!",
"usernameInfo": "Login names are now unique usernames that will be visible beside your display name and used for invitations, chat @mentions, and messaging.<br><br>If you'd like to learn more about this change, <a href='http://habitica.fandom.com/wiki/Player_Names' target='_blank'>visit our wiki</a>.",
"usernameInfo": "Login names are now unique usernames that will be visible beside your display name and used for invitations, chat @mentions, and messaging.<br><br>If you'd like to learn more about this change, <a href='https://habitica.fandom.com/wiki/Player_Names' target='_blank'>visit our wiki</a>.",
"usernameTOSRequirements": "Usernames must conform to our <a href='/static/terms' target='_blank'>Terms of Service</a> and <a href='/static/community-guidelines' target='_blank'>Community Guidelines</a>. If you didnt previously set a login name, your username was auto-generated.",
"usernameTaken": "Username already taken.",
"passwordConfirmationMatch": "Password confirmation doesn't match password.",
"invalidLoginCredentials": "Incorrect username and/or email and/or password.",
"passwordResetPage": "Reset Password",
"passwordReset": "If we have your email on file, instructions for setting a new password have been sent to your email.",
"passwordReset": "If we have your email or username on file, instructions for setting a new password have been sent to your email.",
"passwordResetEmailSubject": "Password Reset for Habitica",
"passwordResetEmailText": "If you requested a password reset for <%= username %> on Habitica, head to <%= passwordResetLink %> to set a new one. The link will expire after 24 hours. If you haven't requested a password reset, please ignore this email.",
"passwordResetEmailHtml": "If you requested a password reset for <strong><%= username %></strong> on Habitica, <a href=\"<%= passwordResetLink %>\">click here</a> to set a new one. The link will expire after 24 hours.<br/><br>If you haven't requested a password reset, please ignore this email.",
@@ -150,7 +150,7 @@
"confirmPassword": "Confirm Password",
"usernameLimitations": "Username must be 1 to 20 characters, containing only letters a to z, numbers 0 to 9, hyphens, or underscores, and cannot include any inappropriate terms.",
"usernamePlaceholder": "e.g., HabitRabbit",
"emailPlaceholder": "e.g., rabbit@example.com",
"emailPlaceholder": "e.g., gryphon@example.com",
"passwordPlaceholder": "e.g., ******************",
"confirmPasswordPlaceholder": "Make sure it's the same password!",
"joinHabitica": "Join Habitica",
@@ -180,10 +180,15 @@
"joinMany": "Join over <%= userCountInMillions %> million people having fun while accomplishing their goals!",
"joinToday": "Join Habitica Today",
"signup": "Sign Up",
"getStarted": "Get Started!",
"getStarted": "Get Started",
"mobileApps": "Mobile Apps",
"learnMore": "Learn More",
"communityInstagram": "Instagram",
"minPasswordLength": "Password must be 8 characters or more.",
"footerProduct": "Product"
"footerProduct": "Product",
"socialAlreadyExists": "This social login is already linked to an existing Habitica account.",
"emailUsernamePlaceholder": "e.g., habitrabbit or gryphon@example.com",
"incorrectResetPhrase": "Please type <%= magicWord %> in all capital letters to reset your account.",
"enterHabitica": "Enter Habitica",
"translateHabitica": "Translate Habitica"
}

View File

@@ -194,12 +194,49 @@
"userSentMessage": "<span class=\"notification-bold\"><%- user %></span> sent you a message",
"letsgo": "Let's Go!",
"selected": "Selected",
"howManyToBuy": "How many would you like to buy?",
"howManyToBuy": "How many would you like to purchase?",
"contactForm": "Contact the Moderation Team",
"options": "Options",
"loadEarlierMessages": "Load Earlier Messages",
"demo": "Demo",
"congratulations": "Congratulations!",
"onboardingAchievs": "Onboarding Achievements",
"finish": "Finish"
"finish": "Finish",
"leaveHabitica": "You are about to leave Habitica.com",
"leaveHabiticaText": "Habitica is not responsible for the content of any linked website that is not owned or operated by HabitRPG.<br>Please note that these websites' practices may differ from Habiticas community guidelines.",
"allNotifications": "All Notifications",
"reportEmailPlaceholder": "Your email address",
"reportDescriptionText": "Include screenshots or Javascript console errors if helpful.",
"reportSent": "Thank you for your submission!",
"reportSentDescription": "Well get back to you once our team has a chance to review.",
"askQuestionHeaderDescribe": "New to Habitica and don't know what you're doing? Veteran but just can't figure out how to use one of the features? Fill out this form and our team will get back to you.",
"questionEmailText": "This will only be used to contact you regarding your question.",
"question": "Question",
"questionDescriptionText": "It's okay to ask your questions in your primary language if you aren't comfortable speaking in English.",
"questionPlaceholder": "Ask your question here",
"submitQuestion": "Submit Question",
"reportBugHeaderDescribe": "Please describe the bug youre experiencing and our team will get back to you.",
"reportEmailText": "This will only be used to contact you regarding the bug report.",
"refreshList": "Refresh List",
"skipExternalLinkModal": "Hold CTRL (Windows) or Command (Mac) when clicking a link to skip this modal.",
"general": "General",
"reportEmailError": "Please provide a valid email address",
"reportDescription": "Description",
"reportDescriptionPlaceholder": "Describe the bug in detail here",
"submitBugReport": "Submit Bug Report",
"askQuestion": "Ask a Question",
"emptyReportBugMessage": "Report Bug Message missing",
"reportPlayer": "Report Player",
"blockPlayer": "Block Player",
"unblockPlayer": "Unblock Player",
"adminTools": "Admin Tools",
"viewAdminPanel": "View Admin Panel",
"shadowMute": "Shadow Mute",
"mutePlayer": "Mute",
"banPlayer": "Ban Player",
"unbanPlayer": "Unban Player",
"bannedPlayer": "This player is banned.",
"whyReportingPlayer": "Why are you reporting this player?",
"whyReportingPlayerPlaceholder": "Reason for report",
"playerReportModalBody": "You should only report a player who violates the <%= firstLinkStart %>Community Guidelines<%= linkEnd %> and/or <%= secondLinkStart %>Terms of Service<%= linkEnd %>. Submitting a false report is a violation of Habiticas Community Guidelines."
}

View File

@@ -20,7 +20,7 @@
"dataTool": "Data Display Tool",
"resources": "Resources",
"communityGuidelines": "Community Guidelines",
"bannedWordUsed": "Oops! Looks like this post contains a swearword or reference to an addictive substance or adult topic (<%= swearWordsUsed %>). Habitica keeps our chat very clean. Feel free to edit your message so you can post it! You must remove the word, not just censor it.",
"bannedWordUsed": "Oops! Looks like this post contains a swear word or reference to an addictive substance or adult topic (<%= swearWordsUsed %>). Habitica keeps our chat very clean. Feel free to edit your message so you can post it! You must remove the word, not just censor it.",
"bannedSlurUsed": "Your post contained inappropriate language, and your chat privileges have been revoked.",
"party": "Party",
"usernameCopied": "Username copied to clipboard.",
@@ -30,8 +30,8 @@
"invite": "Invite",
"leave": "Leave",
"invitedToParty": "You were invited to join the Party <span class=\"notification-bold\"><%- party %></span>",
"invitedToPrivateGuild": "You were invited to join the private Guild <span class=\"notification-bold\"><%- guild %></span>",
"invitedToPublicGuild": "You were invited to join the Guild <span class=\"notification-bold-blue\"><%- guild %></span>",
"invitedToPrivateGuild": "You were invited to join the private Group <span class=\"notification-bold\"><%- guild %></span>",
"invitedToPublicGuild": "You were invited to join the Group <span class=\"notification-bold-blue\"><%- guild %></span>",
"invitationAcceptedHeader": "Your Invitation has been Accepted",
"invitationAcceptedBody": "<%= username %> accepted your invitation to <%= groupName %>!",
"systemMessage": "System Message",
@@ -57,7 +57,7 @@
"createGuild2": "Create",
"guild": "Guild",
"guilds": "Guilds",
"sureKick": "Do you really want to remove this member from the Party/Guild?",
"sureKick": "Do you really want to remove this member from the Party or Group?",
"optionalMessage": "Optional message",
"yesRemove": "Yes, remove them",
"sortBackground": "Sort by Background",
@@ -85,9 +85,9 @@
"PMDisabledOptPopoverText": "Private Messages are disabled. Enable this option to allow users to contact you via your profile.",
"PMDisabledCaptionTitle": "Private Messages are disabled",
"PMDisabledCaptionText": "You can still send messages, but no one can send them to you.",
"block": "Block",
"unblock": "Un-block",
"blockWarning": "Block - This will have no effect if the player is a moderator now or becomes a moderator in future.",
"block": "Block Player",
"unblock": "Unblock Player",
"blockWarning": "This will have no effect if the player is an admin.",
"inbox": "Inbox",
"messageRequired": "A message is required.",
"toUserIDRequired": "A User ID is required",
@@ -98,10 +98,10 @@
"badAmountOfGemsToSend": "Amount must be within 1 and your current number of gems.",
"report": "Report",
"abuseFlagModalHeading": "Report a Violation",
"abuseFlagModalBody": "Are you sure you want to report this post? You should <strong>only</strong> 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.",
"abuseFlagModalBody": "You should only report a post that violates the <%= firstLinkStart %>Community Guidelines<%= linkEnd %> and/or <%= secondLinkStart %>Terms of Service<%= linkEnd %>. Submitting a false report is a violation of Habitica's Community Guidelines.",
"abuseReported": "Thank you for reporting this violation. The moderators have been notified.",
"whyReportingPost": "Why are you reporting this post?",
"whyReportingPostPlaceholder": "Please help our moderators by letting us know why you are reporting this post for a violation, e.g., spam, swearing, religious oaths, bigotry, slurs, adult topics, violence.",
"whyReportingPostPlaceholder": "Reason for report",
"optional": "Optional",
"needsTextPlaceholder": "Type your message here.",
"copyMessageAsToDo": "Copy message as To Do",
@@ -123,10 +123,10 @@
"sendGiftCost": "Total: $<%= cost %> USD",
"sendGiftFromBalance": "From Balance",
"sendGiftPurchase": "Purchase",
"sendGiftMessagePlaceholder": "Personal message (optional)",
"sendGiftMessagePlaceholder": "Add a gift message",
"sendGiftSubscription": "<%= months %> Month(s): $<%= price %> USD",
"gemGiftsAreOptional": "Please note that Habitica will never require you to gift gems to other players. Begging people for gems is a <strong>violation of the Community Guidelines</strong>, and all such instances should be reported to <%= hrefTechAssistanceEmail %>.",
"battleWithFriends": "Battle Monsters With Friends",
"battleWithFriends": "Play Habitica with Others",
"startAParty": "Start a Party",
"partyUpName": "Party Up",
"partyOnName": "Party On",
@@ -162,11 +162,11 @@
"onlyCreatorOrAdminCanDeleteChat": "Not authorised to delete this message!",
"onlyGroupLeaderCanEditTasks": "Not authorised to manage tasks!",
"onlyGroupTasksCanBeAssigned": "Only group tasks can be assigned",
"assignedTo": "Assign To",
"assignedToUser": "Assigned to <strong><%- userName %></strong>",
"assignedToMembers": "Assigned to <strong><%= userCount %> members</strong>",
"assignedToYouAndMembers": "Assigned to you and <strong><%= userCount %> members</strong>",
"youAreAssigned": "Assigned to you",
"assignedTo": "Assigned to",
"assignedToUser": "Assigned: <strong>@<%- userName %></strong>",
"assignedToMembers": "<%= userCount %> users",
"assignedToYouAndMembers": "<strong>You</strong>, <%= userCount %> users",
"youAreAssigned": "Assigned: <strong>you</strong>",
"taskIsUnassigned": "This task is unassigned",
"confirmUnClaim": "Are you sure you want to unclaim this task?",
"confirmNeedsWork": "Are you sure you want to mark this task as needing work?",
@@ -183,7 +183,7 @@
"removeClaim": "Remove Claim",
"onlyGroupLeaderCanManageSubscription": "Only the group leader can manage the group's subscription",
"yourTaskHasBeenApproved": "Your task <span class=\"notification-green notification-bold\"><%- taskText %></span> has been approved.",
"taskNeedsWork": "<span class=\"notification-bold\"><%- managerName %></span> marked <span class=\"notification-bold\"><%- taskText %></span> as needing additional work.",
"taskNeedsWork": "<span class=\"notification-bold\"><%- taskText %></span> was unchecked by <span class=\"notification-bold\">@<%- managerName %></span>. Your rewards for completing the task were reverted.",
"userHasRequestedTaskApproval": "<span class=\"notification-bold\"><%- user %></span> requests approval for <span class=\"notification-bold\"><%- taskName %></span>",
"approve": "Approve",
"approveTask": "Approve Task",
@@ -197,7 +197,7 @@
"userIsClamingTask": "`<%= username %> has claimed:` <%= task %>",
"approvalRequested": "Approval Requested",
"cantDeleteAssignedGroupTasks": "Can't delete group tasks that are assigned to you.",
"groupPlanUpgraded": "<strong><%- groupName %></strong> was upgraded to a Group Plan!",
"groupPlanUpgraded": "<strong><%- groupName %></strong> was successfully upgraded to a Group Plan!",
"groupPlanCreated": "<strong><%- groupName %></strong> was created!",
"onlyGroupLeaderCanInviteToGroupPlan": "Only the group leader can invite users to a group with a subscription.",
"paymentDetails": "Payment Details",
@@ -221,43 +221,43 @@
"badAmountOfGemsToPurchase": "Amount must be at least 1.",
"groupPolicyCannotGetGems": "The policy of one group you're part of prevents its members from obtaining gems.",
"viewParty": "View Party",
"newGuildPlaceholder": "Enter your guild's name.",
"guildBank": "Guild Bank",
"chatPlaceholder": "Type your message to Guild members here",
"newGuildPlaceholder": "Enter your Group's name.",
"guildBank": "Bank",
"chatPlaceholder": "Type your message to Group members here",
"partyChatPlaceholder": "Type your message to Party members here",
"fetchRecentMessages": "Fetch Recent Messages",
"like": "Like",
"liked": "Liked",
"inviteToGuild": "Invite to Guild",
"inviteToGuild": "Invite to Group",
"inviteToParty": "Invite to Party",
"inviteEmailUsername": "Invite via Email or Username",
"inviteEmailUsernameInfo": "Invite users via a valid email or username. If an email isn't registered yet, we'll invite them to join.",
"emailOrUsernameInvite": "Email address or username",
"messageGuildLeader": "Message Guild Leader",
"messageGuildLeader": "Message Group Leader",
"donateGems": "Donate Gems",
"updateGuild": "Update Guild",
"updateGuild": "Update Group",
"viewMembers": "View Members",
"memberCount": "Member Count",
"recentActivity": "Recent Activity",
"myGuilds": "My Guilds",
"guildsDiscovery": "Discover Guilds",
"role": "Role",
"guildLeader": "Guild Leader",
"guildLeader": "Group Leader",
"member": "Member",
"guildSize": "Guild Size",
"guildSize": "Group Size",
"goldTier": "Gold Tier",
"silverTier": "Silver Tier",
"bronzeTier": "Bronze Tier",
"privacySettings": "Privacy Settings",
"onlyLeaderCreatesChallenges": "Only the Leader can create Challenges",
"onlyLeaderCreatesChallengesDetail": "With this option selected, ordinary group members cannot create Challenges for the group.",
"privateGuild": "Private Guild",
"onlyLeaderCreatesChallengesDetail": "With this option selected, ordinary group members cannot create Challenges for the Group.",
"privateGuild": "Private Group",
"charactersRemaining": "<%= characters %> characters remaining",
"guildSummary": "Summary",
"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": "Write a short explanation of your Group. What is the main purpose of the Group and what will its members do?",
"groupDescription": "Description",
"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!",
"markdownFormattingHelp": "[Markdown formatting help](http://habitica.fandom.com/wiki/Markdown_Cheat_Sheet)",
"guildDescriptionPlaceholder": "Use this section to go into more detail about everything that members should know about your Group. Useful tips, helpful links, and encouraging statements all go here!",
"markdownFormattingHelp": "[Markdown formatting help](https://habitica.fandom.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": "You aren't a member of any Guilds.",
@@ -265,16 +265,16 @@
"noGuildsParagraph2": "Click the Discover tab to see recommended Guilds based on your interests, browse Habitica's public Guilds, or create your own Guild.",
"noGuildsMatchFilters": "We couldn't find any matching Guilds.",
"privateDescription": "A private Guild will not be displayed in Habitica's Guild directory. New members can be added by invitation only.",
"removeInvite": "Remove Invitation",
"removeInvite": "Cancel Invite",
"removeMember": "Remove Member",
"sendMessage": "Send Message",
"promoteToLeader": "Transfer Ownership",
"inviteFriendsParty": "Inviting friends to your Party will grant you an exclusive <br/> Quest Scroll to battle the Basi-List together!",
"inviteFriendsParty": "Invite another player to your Party<br/> and receive the exclusive Basi-List Quest Scroll.",
"createParty": "Create a Party",
"inviteMembersNow": "Would you like to invite members now?",
"playInPartyTitle": "Play Habitica in a Party!",
"playInPartyDescription": "Take on amazing quests with friends or on your own. Battle monsters, create Challenges, and help yourself stay accountable through Parties.",
"wantToJoinPartyTitle": "Want to join a Party?",
"playInPartyDescription": "Take on amazing Quests with friends or on your own. Battle monsters, create Challenges, and help yourself stay accountable through Parties.",
"wantToJoinPartyTitle": "Looking for a Party?",
"wantToJoinPartyDescription": "Give your username to a friend who already has a Party, or head to the <a href='/groups/guild/f2db2a7f-13c5-454d-b3ee-ea1f5089e601'>Party Wanted Guild</a> to meet potential comrades!",
"copy": "Copy",
"inviteToPartyOrQuest": "Invite Party to Quest",
@@ -289,7 +289,7 @@
"details": "Details",
"participantDesc": "Once all members have either accepted or declined, the Quest begins. Only those who clicked 'accept' will be able to participate in the Quest and receive the rewards.",
"groupGems": "Group Gems",
"groupGemsDesc": "Guild Gems can be spent to make Challenges! In the future, you will be able to add more Guild Gems.",
"groupGemsDesc": "Group Gems can be spent to make Challenges! In the future, you will be able to add more Group Gems.",
"groupTaskBoard": "Task Board",
"groupInformation": "Group Information",
"groupBilling": "Group Billing",
@@ -353,15 +353,15 @@
"PMUnblockUserToSendMessages": "Unblock this user to continue sending and receiving messages.",
"PMUserDoesNotReceiveMessages": "This user is no longer receiving private messages",
"PMCanNotReply": "You can not reply to this conversation",
"newPartyPlaceholder": "Enter your party's name.",
"newPartyPlaceholder": "Enter your Party's name.",
"claimRewards": "Claim Rewards",
"assignedDateAndUser": "Assigned by <strong>@<%- username %></strong> on <strong><%= date %></strong>",
"assignedDateAndUser": "Assigned by @<%- username %> on <%= date %>",
"assignedDateOnly": "Assigned on <strong><%= date %></strong>",
"managerNotes": "Manager's Notes",
"thisTaskApproved": "This task was approved",
"chooseTeamMember": "Choose a team member",
"chooseTeamMember": "Search for a team member",
"unassigned": "Unassigned",
"bannedWordsAllowedDetail": "With this option selected, the use of banned words in this guild will be allowed.",
"bannedWordsAllowedDetail": "With this option selected, the use of banned words in this Group will be allowed.",
"bannedWordsAllowed": "Allow banned words",
"languageSettings": "Language Settings",
"onlyPrivateGuildsCanUpgrade": "Only private guilds can be upgraded to a group plan.",
@@ -369,5 +369,77 @@
"features": "Features",
"giftMessageTooLong": "The maximum length for gift messages is <%= maxGiftMessageLength %>.",
"selectSubscription": "Select Subscription",
"blockYourself": "You cannot block yourself"
"blockYourself": "You cannot block yourself",
"invitedToPartyBy": "<a href=\"/profile/<%- userId %>\" target=\"_blank\">@<%- userName %></a> has invited you to join the Party <span class=\"notification-bold\"><%- party %></span>",
"challengeBannedSlurs": "Your Challenge contains a slur which violates Habiticas community guidelines and your chat and Challenge creation privileges have been revoked. Contact admin@habitica.com for more information.",
"challengeBannedWords": "Your Challenge contains one or more swear words or references to an adult topic. Please edit your Challenge so you can save it. You must remove the word, not just censor it.",
"challengeBannedSlursPrivate": "Your Challenge contains a slur which violates Habitica's community guidelines. Please remove it in order to save your Challenge.",
"editParty": "Edit Party",
"leaveGuild": "Leave Group",
"groupUseDefault": "Choose an answer",
"groupParentChildren": "Parent(s) setting up tasks for children",
"groupCouple": "Couple sharing tasks",
"viewStatus": "Status",
"chatTemporarilyUnavailable": "Chat is temporarily unavailable. Please try again later.",
"newGroupsBullet01": "Interact with tasks directly from the shared task board",
"sendTotal": "Total:",
"partyExceedsInvitesLimit": "A Party may only have up to <%= maxInvites %> pending invitations.",
"dayStart": "<strong>Day start</strong>: <%= startTime %>",
"youEmphasized": "<strong>You</strong>",
"joinParty": "Join Party",
"messagePartyLeader": "Message Party Leader",
"lookForParty": "Look for a Party",
"currentlyLookingForParty": "Youre looking for a Party!",
"partyFinderDescription": "Want to join a Party with others but dont know any other players? Let Party leaders know youre looking for an invite!",
"upgradeToGroup": "Upgrade to Group",
"viewDetails": "View Details",
"invitedToThisQuest": "You were invited to this Quest!",
"createGroup": "Create a Group",
"groupFriends": "Friends sharing tasks",
"groupCoworkers": "Coworkers sharing tasks",
"groupManager": "Manager setting up tasks for employees",
"groupTeacher": "Teacher setting up tasks for students",
"nameStar": "Name*",
"newGroupsBullet05": "Shared tasks will degrade in color if left incomplete to help track progress",
"newGroupsBullet06": "The task status view allows you to quickly see which assignee has completed a task",
"newGroupsBullet07": "Toggle the ability to display the shared tasks on your personal task board",
"newGroupsBullet02": "Anyone can complete an unassigned task",
"newGroupsBullet03": "Shared tasks reset at the same time for everyone for easier collaboration",
"newGroupsBullet04": "Shared Dailies will not cause damage when missed or appear in the Record Yesterdays Activity prompt",
"newGroupsBullet08": "The group leader and managers can quickly add tasks from the top of the task columns",
"newGroupsBullet09": "A shared task can be unchecked to show it still needs work",
"newGroupsBullet10": "Assignment status determines completion condition:",
"newGroupsBullet10a": "<strong>Leave a task unassigned</strong> if any member can complete it",
"newGroupsBullet10b": "<strong>Assign a task to one member</strong> so only they can complete it",
"newGroupsBullet10c": "<strong>Assign a task to multiple members</strong> if they all need to complete it",
"newGroupsVisitFAQ": "Visit the <a href='/static/faq#group-plans' target='_blank'>FAQ</a> from the Help dropdown for more guidance.",
"newGroupsEnjoy": "We hope you enjoy the new Group Plans experience!",
"checkinsLabel": "Check-ins:",
"classLabel": "Class:",
"lookingForPartyTitle": "Find Members",
"findMorePartyMembers": "Find More Members",
"findPartyMembers": "Find Party Members",
"noOneLooking": "Theres no one looking for a Party right now.<br>You can check back later!",
"tavernDiscontinuedDetail": "Due to a number of factors, including changes in how our player base interacts with Habitica, the resources necessary to maintain these spaces became disproportionate to the number of people participating in them and unsustainable over the long term.",
"tavernDiscontinuedLinks": "Read more about the <a href='/static/faq/tavern-and-guilds'>Tavern and Guild Service Discontinuation</a> or head back to the <a href='/'>homepage</a>.",
"chatSunsetWarning": "⚠️ <strong>Habitica Guilds and Tavern chat will be discontinued on 8/8/2023.</strong> <a href='/static/faq/tavern-and-guilds'>Click here</a> to read more about this change.",
"sendGiftLabel": "Would you like to send a gift message?",
"assignTo": "Assign To",
"groupUse": "Which best describes the use of your Group?*",
"nameStarText": "Add a title",
"descriptionOptional": "Description",
"descriptionOptionalText": "Add a description",
"nextPaymentMethod": "Next: Payment Method",
"questWithOthers": "Take on Quests with Others",
"startPartyDetail": "Start your own Party or join an existing one <br/>to take on Quests and boost your motivation!",
"languageLabel": "Language:",
"invitedToYourParty": "<strong>Invited to Your Party!</strong>&nbsp;&nbsp;Click to Undo",
"editGuild": "Edit Group",
"joinGuild": "Join Group",
"blockedUser": "<strong>You blocked this player.</strong>&nbsp;They cannot send you Private Messages but you will still see their posts.",
"bannedUser": "<strong>This player has been banned.</strong>",
"lastCompleted": "Last completed",
"newGroupsWelcome": "Welcome to the New Shared Task Board!",
"newGroupsWhatsNew": "Check Out What's New:",
"tavernDiscontinued": "The Tavern and Guilds have been discontinued"
}

View File

@@ -27,10 +27,10 @@
"seasonalShopClosedTitle": "<%= linkStart %>Leslie<%= linkEnd %>",
"seasonalShopTitle": "<%= linkStart %>Seasonal Sorceress<%= linkEnd %>",
"seasonalShopClosedText": "The Seasonal Shop is currently closed!! Its only open during Habiticas four Grand Galas.",
"seasonalShopSummerText": "Happy Summer Splash!! Would you like to buy some rare items? Theyll only be available until July 31st!",
"seasonalShopFallText": "Happy Fall Festival!! Would you like to buy some rare items? Theyll only be available until October 31st!",
"seasonalShopWinterText": "Happy Winter Wonderland!! Would you like to buy some rare items? Theyll only be available until January 31st!",
"seasonalShopSpringText": "Happy Spring Fling!! Would you like to buy some rare items? Theyll only be available until April 30th!",
"seasonalShopSummerText": "Happy Summer Splash!! Would you like to buy some rare items? Be sure to get them before the Gala ends!",
"seasonalShopFallText": "Happy Fall Festival!! Would you like to buy some rare items? Be sure to get them before the Gala ends!",
"seasonalShopWinterText": "Happy Winter Wonderland!! Would you like to buy some rare items? Be sure to get them before the Gala ends!",
"seasonalShopSpringText": "Happy Spring Fling!! Would you like to buy some rare items? Be sure to get them before the Gala ends!",
"seasonalShopFallTextBroken": "Oh.... Welcome to the Seasonal Shop... We're stocking autumn Seasonal Edition goodies, or something... Everything here will be available to purchase during the Fall Festival event each year, but we're only open until 31 October... I guess you should to stock up now, or you'll have to wait... and wait... and wait... <strong>*sigh*</strong>",
"seasonalShopBrokenText": "My pavilion!!!!!!! My decorations!!!! Oh, the Dysheartener's destroyed everything :( Please help defeat it in the Tavern so I can rebuild!",
"seasonalShopRebirth": "If you bought any of this equipment in the past but don't currently own it, you can repurchase it in the Rewards Column. Initially, you'll only be able to purchase the items for your current class (Warrior by default), but fear not, the other class-specific items will become available if you switch to that class.",
@@ -130,7 +130,7 @@
"winter2019PyrotechnicSet": "Pyrotechnic (Mage)",
"winter2019WinterStarSet": "Winter Star (Healer)",
"winter2019PoinsettiaSet": "Poinsettia (Rogue)",
"winterPromoGiftHeader": "GIFT A SUBSCRIPTION, GET ONE FREE!",
"winterPromoGiftHeader": "GIFT A SUBSCRIPTION, GET ONE FREE!",
"winterPromoGiftDetails1": "Until January 6th only, when you gift somebody a subscription, you get the same subscription for yourself for free!",
"winterPromoGiftDetails2": "Please note that if you or your gift recipient already have a recurring subscription, the gifted subscription will only start after that subscription is cancelled or has expired. Thanks so much for your support! <3",
"discountBundle": "bundle",
@@ -168,7 +168,7 @@
"fall2020ThirdEyeMageSet": "Third Eye (Mage)",
"fall2020DeathsHeadMothHealerSet": "Death's Head Moth (Healer)",
"royalPurpleJackolantern": "Royal Purple Jack-O-Lantern",
"g1g1Limitations": "This is a limited time event that starts on December 17th at 8:00 AM ET (13:00 UTC) and will end January 7th at 8:00 PM ET (1:00 UTC). This promotion only applies when you gift to another Habitican. If you or your gift recipient already have a subscription, the gifted subscription will add months of credit that will only be used after the current subscription is canceled or expires.",
"g1g1Limitations": "This is a limited time event that starts on <%= promoStartMonth %> <%= promoStartOrdinal %> at <%= promoStartTime %> and will end <%= promoEndMonth %> <%= promoEndOrdinal %> at <%= promoEndTime %>. This promotion only applies when you gift to another Habitican. If you or your gift recipient already have a subscription, the gifted subscription will add months of credit that will only be used after the current subscription is cancelled or expires.",
"limitations": "Limitations",
"howItWorks": "How it Works",
"g1g1Returning": "In honor of the season, were bringing back a very special promotion. Now when you gift a subscription, youll receive the same in return!",
@@ -178,5 +178,95 @@
"winter2021ArcticExplorerHealerSet": "Arctic Explorer (Healer)",
"winter2021WinterMoonMageSet": "Winter Moon (Mage)",
"winter2021IceFishingWarriorSet": "Ice Fisher (Warrior)",
"g1g1HowItWorks": "Type in the username of the account youd like to gift to. From there, pick the sub length you would like to gift and check out. Your account will automatically be rewarded with the same level of subscription you just gifted."
"g1g1HowItWorks": "Type in the username of the account youd like to gift to. From there, pick the sub length you would like to gift and check out. Your account will automatically be rewarded with the same level of subscription you just gifted.",
"spring2024FluoriteWarriorSet": "Fluorite Set (Warrior)",
"spring2024HibiscusMageSet": "Hibiscus Set (Mage)",
"spring2024BluebirdHealerSet": "Bluebird Set (Healer)",
"spring2024MeltingSnowRogueSet": "Melting Snow Set (Rogue)",
"wantToPayWithMoneyText": "Want to pay with Stripe, Paypal, or Amazon?",
"ownJubilantGryphatrice": "<strong>You own the Jubilant Gryphatrice!</strong> Visit Pets and Mounts to equip!",
"jubilantSuccess": "You've successfully purchased the <strong>Jubilant Gryphatrice!</strong>",
"stableVisit": "Visit Pets and Mounts to equip!",
"gemSaleHow": "Between <%= eventStartMonth %> <%= eventStartOrdinal %> and <%= eventEndOrdinal %>, simply purchase any Gem bundle like usual and your account will be credited with the promotional amount of Gems. More Gems to spend, share, or save for any future releases!",
"wantToPayWithGemsText": "Want to pay with Gems?",
"takeMeToStable": "Take me to Pets and Mounts",
"anniversaryLimitations": "This is a limited time event that starts on January 30th at 8:00 AM ET (13:00 UTC) and will end February 8th at 11:59 PM ET (04:59 UTC). The Limited Edition Jubilant Gryphatrice and ten Magic Hatching Potions will be available to buy during this time. The other Gifts listed in the Four for Free section will be automatically delivered to all accounts that were active in the 30 days prior to day the gift is sent. Accounts created after the gifts are sent will not be able to claim them.",
"winter2024SnowyOwlRogueSet": "Snowy Owl (Rogue)",
"winter2024FrozenHealerSet": "Frozen (Healer)",
"winter2024PeppermintBarkWarriorSet": "Peppermint Bark Set (Warrior)",
"winter2024NarwhalWizardMageSet": "Narwhal Wizard Set (Mage)",
"buyNowMoneyButton": "Buy Now for $9.99",
"winter2023WalrusWarriorSet": "Walrus (Warrior)",
"winter2023FairyLightsMageSet": "Fairy Lights (Mage)",
"winter2023CardinalHealerSet": "Cardinal (Healer)",
"spring2023MoonstoneMageSet": "Moonstone (Mage)",
"spring2023LilyHealerSet": "Lily (Healer)",
"spring2023CaterpillarRogueSet": "Caterpillar (Rogue)",
"spring2023HummingbirdWarriorSet": "Hummingbird (Warrior)",
"jubilantGryphatricePromo": "Animated Jubilant Gryphatrice Pet",
"limitedEdition": "Limited Edition",
"anniversaryGryphatriceText": "The rare Jubilant Gryphatrice joins the birthday celebrations! Don't miss your chance to own this exclusive animated Pet.",
"gemSaleLimitations": "This promotion only applies during the limited time event. This event starts on <%= eventStartMonth %> <%= eventStartOrdinal %> at 8:00 AM EDT (12:00 UTC) and will end <%= eventEndMonth %> <%= eventEndOrdinal %> at 8:00 PM EDT (00:00 UTC). The promo offer is only available when buying Gems for yourself.",
"plentyOfPotions": "Plenty of Potions",
"plentyOfPotionsText": "We're bringing back 10 of the community's favorite Magic Hatching potions. Head over to The Market to fill out your collection!",
"visitTheMarketButton": "Visit the Market",
"fourForFree": "Four for Free",
"summer2021ClownfishRogueSet": "Clownfish (Rogue)",
"summer2021FlyingFishWarriorSet": "Flying Fish (Warrior)",
"spring2021SunstoneWarriorSet": "Sunstone (Warrior)",
"spring2021SwanMageSet": "Swan (Mage)",
"summer2021ParrotHealerSet": "Parrot (Healer)",
"spring2021TwinFlowerRogueSet": "Twin Flower (Rogue)",
"spring2021WillowHealerSet": "Willow (Healer)",
"summer2021NautilusMageSet": "Nautilus (Mage)",
"dateStartFebruary": "February 8",
"aprilYYYY": "April <%= year %>",
"anniversaryLimitedDates": "January 30th to February 8th",
"limitedEvent": "Limited Event",
"celebrateAnniversary": "Celebrate Habitica's 10th Birthday with gifts and exclusive items below!",
"celebrateBirthday": "Celebrate Habitica's 10th Birthday with gifts and exclusive items!",
"fourForFreeText": "To keep the party going, we'll be giving away Party Robes, 20 Gems, and a limited edition birthday Background and item set that includes a Cape, Pauldrons, and an Eyemask.",
"dayOne": "Day 1",
"dayFive": "Day 5",
"dayTen": "Day 10",
"partyRobes": "Party Robes",
"twentyGems": "20 Gems",
"birthdaySet": "Birthday Set",
"dateEndDecember": "December 31",
"summer2022CrabRogueSet": "Crab (Rogue)",
"februaryYYYY": "February <%= year %>",
"summer2022WaterspoutWarriorSet": "Waterspout (Warrior)",
"summer2022MantaRayMageSet": "Manta Ray (Mage)",
"summer2022AngelfishHealerSet": "Angelfish (Healer)",
"fall2022KappaRogueSet": "Kappa (Rogue)",
"fall2022OrcWarriorSet": "Orc (Warrior)",
"fall2022HarpyMageSet": "Harpy (Mage)",
"fall2022WatcherHealerSet": "Peeker (Healer)",
"julyYYYY": "July <%= year %>",
"octoberYYYY": "October <%= year %>",
"spring2022MagpieRogueSet": "Magpie (Rogue)",
"spring2022RainstormWarriorSet": "Rainstorm (Warrior)",
"spring2022ForsythiaMageSet": "Forsythia (Mage)",
"spring2022PeridotHealerSet": "Peridot (Healer)",
"noLongerAvailable": "This item is no longer available.",
"fall2021OozeRogueSet": "Ooze (Rogue)",
"fall2021HeadlessWarriorSet": "Headless (Warrior)",
"fall2021BrainEaterMageSet": "Brain Eater (Mage)",
"fall2021FlameSummonerHealerSet": "Flame Summoner (Healer)",
"winter2022FireworksRogueSet": "Fireworks (Rogue)",
"winter2022StockingWarriorSet": "Stocking (Warrior)",
"winter2022PomegranateMageSet": "Pomegranate (Mage)",
"winter2022IceCrystalHealerSet": "Ice Crystal (Healer)",
"januaryYYYY": "January <%= year %>",
"winter2023RibbonRogueSet": "Ribbon (Rogue)",
"summer2023GoldfishWarriorSet": "Goldfish (Warrior)",
"summer2023GuppyRogueSet": "Guppy (Rogue)",
"summer2023KelpHealerSet": "Kelp (Healer)",
"summer2023CoralMageSet": "Coral (Mage)",
"buyNowGemsButton": "Buy Now for 60 Gems",
"fall2023ScaryMovieWarriorSet": "Scary Movie (Warrior)",
"fall2023ScarletWarlockMageSet": "Scarlet Warlock (Mage)",
"fall2023WitchsBrewRogueSet": "Witch's Brew (Rogue)",
"fall2023BogCreatureHealerSet": "Bog Creature (Healer)",
"anniversaryGryphatricePrice": "Own it today for <strong>$9.99</strong> or <strong>60 gems</strong>"
}

View File

@@ -15,7 +15,7 @@
"messageMissingEggPotion": "You're missing either that egg or that potion",
"messageInvalidEggPotionCombo": "You can't hatch Quest Pet Eggs with Magic Hatching Potions! Try a different egg.",
"messageAlreadyPet": "You already have that pet. Try hatching a different combination!",
"messageHatched": "Your egg hatched! Visit your stable to equip your pet.",
"messageHatched": "Your egg hatched! Visit Pets and Mounts to equip your pet.",
"messageNotEnoughGold": "Not Enough Gold",
"messageTwoHandedEquip": "Wielding <%= twoHandedText %> takes two hands, so <%= offHandedText %> has been unequipped.",
"messageTwoHandedUnequip": "Wielding <%= twoHandedText %> takes two hands, so it was unequipped when you armed yourself with <%= offHandedText %>.",
@@ -59,5 +59,6 @@
"messageBackgroundUnEquipped": "Background unequipped.",
"messagePetMountUnEquipped": "Pet and Mount unequipped.",
"messageCostumeUnEquipped": "Costume unequipped.",
"messageBattleGearUnEquipped": "Battle Gear unequipped."
"messageBattleGearUnEquipped": "Battle Gear unequipped.",
"featureRetired": "This feature is no longer supported."
}

View File

@@ -14,7 +14,7 @@
"next": "Next",
"randomize": "Randomise",
"mattBoch": "Matt Boch",
"mattBochText1": "Welcome to the Stable! Im Matt, the beastmaster. Every time you complete a task, you'll have a random chance at receiving an Egg or a Hatching Potion to hatch Pets. When you hatch a Pet, it will appear here! Click a Pet's image to add it to your Avatar. Feed them with the Pet Food you find, and they'll grow into hardy Mounts.",
"mattBochText1": "Welcome to the stable! Im Matt, the beastmaster. Every time you complete a task, you'll have a random chance at receiving an Egg or a Hatching Potion to hatch Pets. When you hatch a Pet, it will appear here! Click a Pet's image to add it to your Avatar. Feed them with the Pet Food you find, and they'll grow into hardy Mounts.",
"welcomeToTavern": "Welcome to The Tavern!",
"sleepDescription": "Need a break? Pause Damage (located in Settings) to pause some of Habitica's more difficult game mechanics:",
"sleepBullet1": "Your missed Dailies won't damage you (bosses will still do damage caused by other Party member's missed Dailies)",
@@ -81,13 +81,13 @@
"newBaileyUpdate": "New Bailey Update!",
"tellMeLater": "Tell Me Later",
"dismissAlert": "Dismiss This Alert",
"donateText3": "Habitica is an open source project that depends on our users for support. The money you spend on gems helps us keep the servers running, maintain a small staff, develop new features, and provide incentives for our volunteer programmers. Thank you for your generosity!",
"donateText3": "Habitica is an open source project that depends on our users for support. The money you spend on gems helps us keep the servers running, maintain a small staff, develop new features, and provide incentives for our volunteers",
"card": "Credit Card",
"paymentMethods": "Purchase using",
"paymentSuccessful": "Your payment was successful!",
"paymentYouReceived": "You received:",
"paymentYouSentGems": "You sent <strong><%- name %></strong>:",
"paymentYouSentSubscription": "You sent <strong><%- name %></strong> a <%= months %>-months Habitica subscription.",
"paymentYouSentSubscription": "You sent <strong><%- name %></strong><br> a <%= months %> month(s) Habitica subscription.",
"paymentSubBilling": "Your subscription will be billed <strong>$<%= amount %></strong> every <strong><%= months %> months</strong>.",
"success": "Success!",
"classGear": "Class Gear",
@@ -98,12 +98,12 @@
"toDo": "To Do",
"tourStatsPage": "This is your Stats page! Earn achievements by completing the listed tasks.",
"tourTavernPage": "Welcome to the Tavern, an all-ages chat room! You can keep your Dailies from hurting you in case of illness or travel by clicking \"Pause Damage\". Come say hi!",
"tourPartyPage": "Your Party will help you stay accountable. Invite friends to unlock a Quest Scroll!",
"tourPartyPage": "Welcome to your new Party! You can invite other players to your Party by username, email, or from a list of players looking for a Party to earn the exclusive Basi-List Quest Scroll.<br/><br/>Select <a href='/static/faq#parties'>FAQ</a> from the Help dropdown to learn more about how Parties work.",
"tourGuildsPage": "Guilds are common-interest chat groups created by the players, for the players. Browse through the list and join the Guilds that interest you. Be sure to check out the popular Habitica Help: Ask a Question guild, where anyone can ask questions about Habitica!",
"tourChallengesPage": "Challenges are themed task lists created by users! Joining a Challenge will add its tasks to your account. Compete against other users to win Gem prizes!",
"tourMarketPage": "Every time you complete a task, you'll have a random chance at receiving an Egg, a Hatching Potion, or a piece of Pet Food. You can also buy these items here.",
"tourHallPage": "Welcome to the Hall of Heroes, where open-source contributors to Habitica are honoured. Whether through code, art, music, writing, or even just helpfulness, they have earned Gems, exclusive equipment, and prestigious titles. You can contribute to Habitica, too!",
"tourPetsPage": "Welcome to the Stable! Every time you complete a task, you'll have a random chance at receiving an Egg or a Hatching Potion to hatch Pets. When you hatch a Pet, it will appear here! Click a Pet's image to add it to your Avatar. Feed them with the Pet Food you find and they'll grow into hardy Mounts.",
"tourPetsPage": "Welcome to the stable! Every time you complete a task, you'll have a random chance at receiving an Egg or a Hatching Potion to hatch Pets. When you hatch a Pet, it will appear here! Click a Pet's image to add it to your Avatar. Feed them with the Pet Food you find and they'll grow into hardy Mounts.",
"tourMountsPage": "Once you've fed a pet enough food to turn it into a mount, it will appear here. Click a mount to saddle up!",
"tourEquipmentPage": "This is where your Equipment is stored! Your Battle Gear affects your Stats. If you want to show different Equipment on your avatar without changing your Stats, click \"Enable Costume.\"",
"equipmentAlreadyOwned": "You already own that piece of equipment",
@@ -126,5 +126,13 @@
"invalidUnlockSet": "This set of items is invalid and cannot be unlocked.",
"nMonthsSubscriptionGift": "<%= nMonths %> Month(s) Subscription (Gift)",
"nGemsGift": "<%= nGems %> Gems (Gift)",
"nGems": "<%= nGems %> Gems"
"nGems": "<%= nGems %> Gems",
"groupsPaymentSubBilling": "Your next billing date is <strong><%= renewalDate %></strong>.",
"groupsPaymentAutoRenew": "This subscription will auto-renew until it is cancelled. If you need to cancel, you can do so from the Group Billing tab.",
"helpSupportHabitica": "Help Support Habitica",
"limitedAvailabilityMinutes": "Available for <%= minutes %>m <%= seconds %>s",
"amountExp": "<%= amount %> Exp",
"limitedAvailabilityDays": "Available for <%= days %>d <%= hours %>h <%= minutes %>m",
"limitedAvailabilityHours": "Available for <%= hours %>h <%= minutes %>m",
"sellItems": "Sell Items"
}

View File

@@ -1,5 +1,5 @@
{
"stable": "Stable",
"stable": "Pets and Mounts",
"pets": "Pets",
"activePet": "Active Pet",
"noActivePet": "No Active Pet",
@@ -44,8 +44,8 @@
"noFoodAvailable": "You don't have any Pet Food.",
"noSaddlesAvailable": "You don't have any Saddles.",
"noFood": "You don't have any food or saddles.",
"dropsExplanation": "Get these items faster with Gems if you don't want to wait for them to drop when completing a task. <a href=\"http://habitica.fandom.com/wiki/Drops\">Learn more about the drop system.</a>",
"dropsExplanationEggs": "Spend Gems to get eggs more quickly, if you don't want to wait for standard eggs to drop, or to repeat Quests to earn Quest eggs. <a href=\"http://habitica.fandom.com/wiki/Drops\">Learn more about the drop system.</a>",
"dropsExplanation": "Get these items faster with Gems if you don't want to wait for them to drop when completing a task. <a href=\"https://habitica.fandom.com/wiki/Drops\">Learn more about the drop system.</a>",
"dropsExplanationEggs": "Spend Gems to get eggs more quickly, if you don't want to wait for standard eggs to drop, or to repeat Quests to earn Quest eggs. <a href=\"https://habitica.fandom.com/wiki/Drops\">Learn more about the drop system.</a>",
"premiumPotionNoDropExplanation": "Magic Hatching Potions cannot be used on eggs received from Quests. The only way to get Magic Hatching Potions is by buying them below, not from random drops.",
"beastMasterProgress": "Beast Master Progress",
"beastAchievement": "You have earned the \"Beast Master\" Achievement for collecting all the pets!",
@@ -59,13 +59,13 @@
"mountMasterText2": " and has released all 90 of their mounts a total of <%= count %> time(s)",
"triadBingoName": "Triad Bingo",
"triadBingoText": "Has found all 90 pets, all 90 mounts, and found all 90 pets AGAIN (HOW DID YOU DO THAT!)",
"triadBingoText2": " and has released a full stable a total of <%= count %> time(s)",
"triadBingoText2": " and has released all their Pets and Mounts a total of <%= count %> time(s)",
"triadBingoAchievement": "You have earned the \"Triad Bingo\" achievement for finding all the pets, taming all the mounts, and finding all the pets again!",
"dropsEnabled": "Drops Enabled!",
"firstDrop": "You've unlocked the Drop System! Now, when you complete tasks you have a small chance of finding an item, including eggs, potions, and food! You just found a <strong><%= eggText %> Egg</strong>! <%= eggNotes %>",
"hatchedPet": "You hatched a new <%= potion %> <%= egg %>!",
"hatchedPetGeneric": "You hatched a new pet!",
"hatchedPetHowToUse": "Visit the [Stable](<%= stableUrl %>) to feed and equip your newest pet!",
"hatchedPetHowToUse": "Visit [Pets and Mounts](<%= stableUrl %>) to feed and equip your newest pet!",
"petNotOwned": "You do not own this pet.",
"mountNotOwned": "You do not own this mount.",
"feedPet": "Feed <%= text %> to your <%= name %>?",
@@ -87,10 +87,10 @@
"petsReleased": "Pets released.",
"mountsAndPetsReleased": "Mounts and pets released",
"mountsReleased": "Mounts released",
"welcomeStable": "Welcome to the Stable!",
"welcomeStableText": "Welcome to the Stable! Im Matt, the beastmaster. Every time you complete a task, you'll have a random chance at receiving an Egg or a Hatching Potion to hatch Pets. When you hatch a Pet, it will appear here! Click a Pet's image to add it to your Avatar. Feed them with the Pet Food you find and they'll grow into hardy Mounts.",
"welcomeStable": "Welcome to your Pets and Mounts!",
"welcomeStableText": "Welcome to the stable! Im Matt, the beastmaster. Every time you complete a task, you'll have a random chance at receiving an Egg or a Hatching Potion to hatch Pets. When you hatch a Pet, it will appear here! Click a Pet's image to add it to your Avatar. Feed them with the Pet Food you find and they'll grow into hardy Mounts.",
"petLikeToEat": "What does my pet like to eat?",
"petLikeToEatText": "Pets will grow no matter what you feed them, but they'll grow faster if you feed them the one Pet Food that they like best. Experiment to find out the pattern, or see the answers here: <br/> <a href=\"http://habitica.fandom.com/wiki/Food_Preferences\" target=\"_blank\">http://habitica.fandom.com/wiki/Food_Preferences</a>",
"petLikeToEatText": "Pets will grow no matter what you feed them, but they'll grow faster if you feed them the one Pet Food that they like best. Experiment to find out the pattern, or see the answers here: <br/> <a href=\"https://habitica.fandom.com/wiki/Food_Preferences\" target=\"_blank\">https://habitica.fandom.com/wiki/Food_Preferences</a>",
"filterByStandard": "Standard",
"filterByMagicPotion": "Magic Potion",
"filterByQuest": "Quest",
@@ -114,5 +114,6 @@
"invalidAmount": "Invalid amount of food, must be a positive integer",
"tooMuchFood": "You're trying to feed too much food to your pet, action cancelled",
"notEnoughFood": "You don't have enough food",
"veteranDragon": "Veteran Dragon"
"veteranDragon": "Veteran Dragon",
"jubilantGryphatrice": "Jubilant Gryphatrice"
}

View File

@@ -31,13 +31,13 @@
"collected": "Collected",
"abort": "Abort",
"leaveQuest": "Leave Quest",
"sureLeave": "Are you sure you want to leave the active quest? All your quest progress will be lost.",
"sureLeave": "Are you sure you want to leave the Quest? All your progress will be lost.",
"mustComplete": "You must first complete <%= quest %>.",
"mustLvlQuest": "You must be level <%= level %> to buy this quest!",
"unlockByQuesting": "To unlock this quest, complete <%= title %>.",
"questConfirm": "Are you sure? Only <%= questmembers %> of your <%= totalmembers %> party members have joined this quest! Quests start automatically when all players have joined or rejected the invitation.",
"sureCancel": "Are you sure you want to cancel this quest? All invitation acceptances will be lost. The quest owner will retain possession of the quest scroll.",
"sureAbort": "Are you sure you want to abort this mission? It will abort it for everyone in your party and all progress will be lost. The quest scroll will be returned to the quest owner.",
"questConfirm": "Are you sure you want to start this Quest? Not all Party members have accepted the Quest invite. Quests start automatically after all members respond to the invite.",
"sureCancel": "Are you sure you want to cancel this Quest? Canceling the Quest will cancel all accepted and pending invitations. The Quest will be returned to the owner's inventory.",
"sureAbort": "Are you sure you want to cancel this Quest? All progress will be lost. The Quest will be returned to the owner's inventory.",
"doubleSureAbort": "Are you double sure? Make sure they won't hate you forever!",
"bossRageTitle": "Rage",
"bossRageDescription": "When this bar fills, the boss will unleash a special attack!",
@@ -65,7 +65,7 @@
"loginIncentiveQuest": "To unlock this quest, check in to Habitica on <%= count %> different days!",
"loginReward": "<%= count %> Check-ins",
"questBundles": "Discounted Quest Bundles",
"noQuestToStart": "Cant find a quest to start? Try checking out the Quest Shop in the Market for new releases!",
"noQuestToStart": "Try checking out the <a href=\"<%= questShop %>\">Quest Shop</a> for new releases!",
"pendingDamage": "<%= damage %> pending damage",
"pendingDamageLabel": "pending damage",
"bossHealth": "<%= currentHealth %> / <%= maxHealth %> Health",
@@ -86,5 +86,17 @@
"questAlreadyStartedFriendly": "The quest has already started, but you can always catch the next one!",
"questAlreadyStarted": "The quest has already started.",
"bossDamage": "You damaged the boss!",
"questItemsPending": "<%= amount %> Items pending"
"questItemsPending": "<%= amount %> Items pending",
"ownerOnly": "Owner only",
"membersParticipating": "<%= accepted %> / <%= invited %> Members participating",
"noQuestToStartTitle": "Cant find a Quest to start?",
"yourPartyIsNotOnQuest": "Your Party is not on a Quest",
"selectQuest": "Select Quest",
"yourQuests": "Your Quests",
"questOwner": "Quest Owner",
"cancelQuest": "Cancel Quest",
"sureLeaveInactive": "Are you sure you want to leave the Quest? You won't be able to participate.",
"selectQuestModal": "Select a Quest",
"newItem": "New Item",
"backToSelection": "Back to Quest selection"
}

View File

@@ -1,7 +1,7 @@
{
"questEvilSantaText": "Trapper Santa",
"questEvilSantaNotes": "You hear agonised roars deep in the icefields. You follow the growls - punctuated by the sound of cackling - to a clearing in the woods, where you see a fully-grown polar bear. She's caged and shackled, fighting for her life. Dancing atop the cage is a malicious little imp wearing a castaway costume. Vanquish Trapper Santa, and save the beast!<br><br><strong>Note</strong>: “Trapper Santa” awards a stackable quest achievement but gives a rare mount that can only be added to your stable once.",
"questEvilSantaCompletion": "Trapper Santa squeals in anger, and bounces off into the night. The grateful she-bear, through roars and growls, tries to tell you something. You take her back to the stables, where Matt Boch the Beast Master listens to her tale with a gasp of horror. She has a cub! He ran off into the ice-fields when mama bear was captured.",
"questEvilSantaCompletion": "Trapper Santa squeals in anger, and bounces off into the night. The grateful she-bear, through roars and growls, tries to tell you something. You take her back to the stables, where Matt Boch, the Beast Master, listens to her tale with a gasp of horror. She has a cub! He ran off into the icefields when mama bear was captured.",
"questEvilSantaBoss": "Trapper Santa",
"questEvilSantaDropBearCubPolarMount": "Polar Bear (Mount)",
"questEvilSanta2Text": "Find the Cub",
@@ -60,7 +60,7 @@
"questSpiderUnlockText": "Unlocks Spider Eggs for purchase in the Market",
"questGroupVice": "Vice the Shadow Wyrm",
"questVice1Text": "Vice, Part 1: Free Yourself of the Dragon's Influence",
"questVice1Notes": "<p>They say there lies a terrible evil in the caverns of Mt. Habitica. A monster whose presence twists the wills of the strong heroes of the land, turning them towards bad habits and laziness! The beast is a grand dragon of immense power and comprised of the shadows themselves: Vice, the treacherous Shadow Wyrm. Brave Habiteers, stand up and defeat this foul beast once and for all, but only if you believe you can stand against its immense power. </p><h3>Vice Part 1: </h3><p>How can you expect to fight the beast if it already has control over you? Don't fall victim to laziness and vice! Work hard to fight against the dragon's dark influence and dispel its hold on you!</p>",
"questVice1Notes": "They say there lies a terrible evil in the caverns of Mt. Habitica. A monster whose presence twists the wills of the strong heroes of the land, turning them towards bad habits and laziness! The beast is a grand dragon of immense power and comprised of the shadows themselves: Vice, the treacherous Shadow Wyrm. Brave Habiteers, stand up and defeat this foul beast once and for all, but only if you believe you can stand against its immense power.<br><br>How can you expect to fight the beast if it already has control over you? Don't fall victim to laziness and vice! Work hard to fight against the dragon's dark influence and dispel his hold on you!",
"questVice1Boss": "Vice's Shade",
"questVice1Completion": "With Vice's influence over you dispelled, you feel a surge of strength you didn't know you had return to you. Congratulations! But a more frightening foe awaits...",
"questVice1DropVice2Quest": "Vice Part 2 (Scroll)",
@@ -173,7 +173,7 @@
"questStressbeastBossRageDescription": "When this gauge fills, the Abominable Stressbeast will unleash its Stress Strike on Habitica!",
"questStressbeastDropMammothPet": "Mammoth (Pet)",
"questStressbeastDropMammothMount": "Mammoth (Mount)",
"questStressbeastBossRageStables": "`Abominable Stressbeast uses STRESS STRIKE!`\n\nThe surge of stress heals Abominable Stressbeast!\n\nOh no! Despite our best efforts, we've let some Dailies get away from us, and their dark-red colour has infuriated the Abominable Stressbeast and caused it to regain some of its health! The horrible creature lunges for the Stables, but Matt the Beast Master heroically leaps into the fray to protect the pets and mounts. The Stressbeast has seized Matt in its vicious grip, but at least it's distracted for the moment. Hurry! Let's keep our Dailies in check and defeat this monster before it attacks again!",
"questStressbeastBossRageStables": "`Abominable Stressbeast uses STRESS STRIKE!`\n\nThe surge of stress heals Abominable Stressbeast!\n\nOh no! Despite our best efforts, we've let some Dailies get away from us, and their dark-red color has infuriated the Abominable Stressbeast and caused it to regain some of its health! The horrible creature lunges for the stables, but Matt the Beast Master heroically leaps into the fray to protect the pets and mounts. The Stressbeast has seized Matt in its vicious grip, but at least it's distracted for the moment. Hurry! Let's keep our Dailies in check and defeat this monster before it attacks again!",
"questStressbeastBossRageBailey": "`Abominable Stressbeast uses STRESS STRIKE!`\n\nThe surge of stress heals Abominable Stressbeast!\n\nAhh!!! Our incomplete Dailies caused the Abominable Stressbeast to become madder than ever and regain some of its health! Bailey the Town Crier was shouting for citizens to get to safety, and now it has seized her in its other hand! Look at her, valiantly reporting on the news as the Stressbeast swings her around viciously... Let's be worthy of her bravery by being as productive as we can to save our NPCs!",
"questStressbeastBossRageGuide": "`Abominable Stressbeast uses STRESS STRIKE!`\n\nThe surge of stress heals Abominable Stressbeast!\n\nLook out! Justin the Guide is trying to distract the Stressbeast by running around its ankles, yelling productivity tips! The Abominable Stressbeast is stomping madly, but it seems like we're really wearing this beast down. I doubt it has enough energy for another strike. Don't give up... we're so close to finishing it off!",
"questStressbeastDesperation": "`Abominable Stressbeast reaches 500K health! Abominable Stressbeast uses Desperate Defence!`\n\nWe're almost there, Habiticans! With diligence and Dailies, we've whittled the Stressbeast's health down to only 500K! The creature roars and flails in desperation, rage building faster than ever. Bailey and Matt yell in terror as it begins to swing them around at a terrifying pace, raising a blinding snowstorm that makes it harder to hit.\n\nWe'll have to redouble our efforts, but take heart - this is a sign that the Stressbeast knows it is about to be defeated. Don't give up now!",
@@ -313,7 +313,7 @@
"questSnailDropSnailEgg": "Snail (Egg)",
"questSnailUnlockText": "Unlocks Snail Eggs for purchase in the Market",
"questBewilderText": "The Be-Wilder",
"questBewilderNotes": "The party begins like any other.<br><br>The appetisers are excellent, the music is swinging, and even the dancing elephants have become routine. Habiticans laugh and frolic amid the overflowing floral centrepieces, happy to have a distraction from their least-favourite tasks, and the April Fool whirls among them, eagerly providing an amusing trick here and a witty twist there.<br><br>As the Mistiflying clock tower strikes midnight, the April Fool leaps onto the stage to give a speech.<br><br>“Friends! Enemies! Tolerant acquaintances! Lend me your ears.” The crowd chuckles as animal ears sprout from their heads, and they pose with their new accessories.<br><br>“As you know,” the Fool continues, “my confusing illusions usually only last a single day. But Im pleased to announce that Ive discovered a shortcut that will guarantee us non-stop fun, without having to deal with the pesky weight of our responsibilities. Charming Habiticans, meet my magical new friend... the Be-Wilder!”<br><br>Lemoness pales suddenly, dropping her hors d'oeuvres. “Wait! Dont trust--”<br><br>But suddenly mists are pouring into the room, glittering and thick, and they swirl around the April Fool, coalescing into cloudy feathers and a stretching neck. The crowd is speechless as an monstrous bird unfolds before them, its wings shimmering with illusions. It lets out a horrible screeching laugh.<br><br>“Oh, it has been ages since a Habitican has been foolish enough to summon me! How wonderful it feels, to have a tangible form at last.”<br><br>Buzzing in terror, the magic bees of Mistiflying flee the floating city, which sags from the sky. One by one, the brilliant spring flowers wither up and wisp away.<br><br>“My dearest friends, why so alarmed?” crows the Be-Wilder, beating its wings. “Theres no need to toil for your rewards any more. Ill just give you all the things that you desire!”<br><br>A rain of coins pours from the sky, hammering into the ground with brutal force, and the crowd screams and flees for cover. “Is this a joke?” Baconsaur shouts, as the gold smashes through windows and shatters roof shingles.<br><br>PainterProphet ducks as lightning bolts crackle overhead, and fog blots out the sun. “No! This time, I dont think it is!”<br><br>Quickly, Habiticans, dont let this World Boss distract us from our goals! Stay focused on the tasks that you need to complete so we can rescue Mistiflying -- and hopefully, ourselves.",
"questBewilderNotes": "The party begins like any other.<br><br>The appetisers are excellent, the music is swinging, and even the dancing elephants have become routine. Habiticans laugh and frolic amid the overflowing floral centrepieces, happy to have a distraction from their least-favourite tasks, and the April Fool whirls among them, eagerly providing an amusing trick here and a witty twist there.<br><br>As the Mistiflying clock tower strikes midnight, the April Fool leaps onto the stage to give a speech.<br><br>“Friends! Enemies! Tolerant acquaintances! Lend me your ears.” The crowd chuckles as animal ears sprout from their heads, and they pose with their new accessories.<br><br>“As you know,” the Fool continues, “my confusing illusions usually only last a single day. But Im pleased to announce that Ive discovered a shortcut that will guarantee us non-stop fun, without having to deal with the pesky weight of our responsibilities. Charming Habiticans, meet my magical new friend... the Be-Wilder!”<br><br>Lemoness pales suddenly, dropping her hors d'oeuvres. “Wait! Dont trust--”<br><br>But suddenly mists are pouring into the room, glittering and thick, and they swirl around the April Fool, coalescing into cloudy feathers and a stretching neck. The crowd is speechless as a monstrous bird unfolds before them, its wings shimmering with illusions. It lets out a horrible screeching laugh.<br><br>“Oh, it has been ages since a Habitican has been foolish enough to summon me! How wonderful it feels, to have a tangible form at last.”<br><br>Buzzing in terror, the magic bees of Mistiflying flee the floating city, which sags from the sky. One by one, the brilliant spring flowers wither up and wisp away.<br><br>“My dearest friends, why so alarmed?” crows the Be-Wilder, beating its wings. “Theres no need to toil for your rewards any more. Ill just give you all the things that you desire!”<br><br>A rain of coins pours from the sky, hammering into the ground with brutal force, and the crowd screams and flees for cover. “Is this a joke?” Baconsaur shouts, as the gold smashes through windows and shatters roof shingles.<br><br>PainterProphet ducks as lightning bolts crackle overhead, and fog blots out the sun. “No! This time, I dont think it is!”<br><br>Quickly, Habiticans, dont let this World Boss distract us from our goals! Stay focused on the tasks that you need to complete so we can rescue Mistiflying -- and hopefully, ourselves.",
"questBewilderCompletion": "<strong>The Be-Wilder is DEFEATED!</strong><br><br>We've done it! The Be-Wilder lets out a ululating cry as it twists in the air, shedding feathers like falling rain. Slowly, gradually, it coils into a cloud of sparkling mist. As the newly-revealed sun pierces the fog, it burns away, revealing the coughing, mercifully human forms of Bailey, Matt, Alex.... and the April Fool himself.<br><br><strong>Mistiflying is saved!</strong><br><br>The April Fool has enough shame to look a bit sheepish. “Oh, hm,” he says. “Perhaps I got a little…. carried away.”<br><br>The crowd mutters. Sodden flowers wash up on pavements. Somewhere in the distance, a roof collapses with a spectacular splash.<br><br>“Er, yes,” the April Fool says. “That is. What I meant to say was, Im dreadfully sorry.” He heaves a sigh. “I suppose it cant all be fun and games, after all. It might not hurt to focus occasionally. Maybe Ill get a head start on next years pranking.”<br><br>Redphoenix coughs meaningfully.<br><br>“I mean, get a head start on this years spring cleaning!” the April Fool says. “Nothing to fear, Ill have Habit City in spit-shape soon. Luckily nobody is better than I at dual-wielding mops.”<br><br>Encouraged, the marching band starts up.<br><br>It isnt long before all is back to normal in Habit City. Plus, now that the Be-Wilder has evaporated, the magical bees of Mistiflying bustle back to work, and soon the flowers are blooming and the city is floating once more.<br><br>As Habiticans cuddle the magical fuzzy bees, the April Fools eyes light up. “Oho, Ive had a thought! Why dont you all keep some of these fuzzy Bee Pets and Mounts? Its a gift that perfectly symbolises the balance between hard work and sweet rewards, if Im going to get all boring and allegorical on you.” He winks. “Besides, they dont have stingers! Fools honour.”",
"questBewilderCompletionChat": "`The Be-Wilder is DEFEATED!`\n\nWe've done it! The Be-Wilder lets out a ululating cry as it twists in the air, shedding feathers like falling rain. Slowly, gradually, it coils into a cloud of sparkling mist. As the newly-revealed sun pierces the fog, it burns away, revealing the coughing, mercifully human forms of Bailey, Matt, Alex.... and the April Fool himself.\n\n`Mistiflying is saved!`\n\nThe April Fool has enough shame to look a bit sheepish. “Oh, hm,” he says. “Perhaps I got a little…. carried away.”\n\nThe crowd mutters. Sodden flowers wash up on pavements. Somewhere in the distance, a roof collapses with a spectacular splash.\n\n“Er, yes,” the April Fool says. “That is. What I meant to say was, Im dreadfully sorry.” He heaves a sigh. “I suppose it cant all be fun and games, after all. It might not hurt to focus occasionally. Maybe Ill get a head start on next years pranking.”\n\nRedphoenix coughs meaningfully.\n\n“I mean, get a head start on this years spring cleaning!” the April Fool says. “Nothing to fear, Ill have Habit City in spit-shape soon. Luckily nobody is better than I at dual-wielding mops.”\n\nEncouraged, the marching band starts up.\n\nIt isnt long before all is back to normal in Habit City. Plus, now that the Be-Wilder has evaporated, the magical bees of Mistiflying bustle back to work, and soon the flowers are blooming and the city is floating once more.\n\nAs Habiticans cuddle the magical fuzzy bees, the April Fools eyes light up. “Oho, Ive had a thought! Why dont you all keep some of these fuzzy Bee Pets and Mounts? Its a gift that perfectly symbolises the balance between hard work and sweet rewards, if Im going to get all boring and allegorical on you.” He winks. “Besides, they dont have stingers! Fools honour.”",
"questBewilderBossRageTitle": "Beguilement Strike",
@@ -473,7 +473,7 @@
"questButterflyUnlockText": "Unlocks Caterpillar Eggs for purchase in the Market",
"questGroupMayhemMistiflying": "Mayhem in Mistiflying",
"questMayhemMistiflying1Text": "Mayhem in Mistiflying, Part 1: In Which Mistiflying Experiences a Dreadful Bother",
"questMayhemMistiflying1Notes": "Although local soothsayers predicted pleasant weather, the afternoon is extremely breezy, so you gratefully follow your friend @Kiwibot into their house to escape the blustery day.<br><br>Neither of you expects to find the April Fool lounging at the kitchen table.<br><br>“Oh, hello,” he says. “Fancy seeing you here. Please, let me offer you some of this delicious tea.”<br><br>“Thats…” @Kiwibot begins. “Thats MY—“<br><br>“Yes, yes, of course,” says the April Fool, helping himself to some cookies. “Just thought Id pop indoors and get a nice reprieve from all the tornado-summoning skulls.” He takes a casual sip from his teacup. “Incidentally, the city of Mistiflying is under attack.”<br><br>Horrified, you and your friends race to the Stables and saddle your fastest winged mounts. As you soar towards the floating city, you see that a swarm of chattering, flying skulls are laying siege to the city… and several turn their attentions towards you!",
"questMayhemMistiflying1Notes": "Although local soothsayers predicted pleasant weather, the afternoon is extremely breezy, so you gratefully follow your friend @Kiwibot into their house to escape the blustery day.<br><br>Neither of you expects to find the April Fool lounging at the kitchen table.<br><br>“Oh, hello,” he says. “Fancy seeing you here. Please, let me offer you some of this delicious tea.”<br><br>“Thats…” @Kiwibot begins. “Thats MY—“<br><br>“Yes, yes, of course,” says the April Fool, helping himself to some cookies. “Just thought Id pop indoors and get a nice reprieve from all the tornado-summoning skulls.” He takes a casual sip from his teacup. “Incidentally, the city of Mistiflying is under attack.”<br><br>Horrified, you and your friends race to the stables and saddle your fastest winged mounts. As you soar towards the floating city, you see that a swarm of chattering, flying skulls are laying siege to the city… and several turn their attentions towards you!",
"questMayhemMistiflying1Completion": "The final skull drops from the sky, a shimmering set of rainbow robes clasped in its jaws, but the steady wind has not slackened. Something else is at play here. And where is that slacking April Fool? You pick up the robes, then swoop into the city.",
"questMayhemMistiflying1Boss": "Air Skull Swarm",
"questMayhemMistiflying1RageTitle": "Swarm Respawn",
@@ -544,7 +544,7 @@
"questLostMasterclasser3DropZombiePotion": "Zombie Hatching Potion",
"questLostMasterclasser4Text": "The Mystery of the Masterclassers, Part 4: The Lost Masterclasser",
"questLostMasterclasser4Notes": "You surface from the portal, but youre still suspended in a strange, shifting netherworld. “That was bold,” says a cold voice. “I have to admit, I hadnt 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 Antizinnya 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, Antizinnyas 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 youre 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 Antizinnyas 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 youll 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 youre 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 Antizinnyas 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 youll 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!",
@@ -651,7 +651,7 @@
"questSilverUnlockText": "Unlocks Silver Hatching Potions for purchase in the Market",
"questSilverCollectMoonRunes": "Moon Runes",
"questSilverCollectCancerRunes": "Cancer Zodiac Runes",
"questSilverCompletion": "You've delved. You've dredged. You've scavenged. At last you emerge from the Dungeons, laden with runes and bars of silver, covered in sludge but exhilarated with success. You journey back to Habit City and set to work in an alchemy lab. You and @starsystemic follow the formulas @QuartzFox found, under the careful supervision of @Edge. Finally, in a great puff of glitter and smoke, your concoction settles into the familiar viscosity of a Hatching Potion!<br><br>@Edge scoops the mixture into vials and grins. “Let's give it a try, shall we? Anyone got any Eggs?”<br><br>You rush to the Stables, wondering what shining secrets may yet remain undiscovered...",
"questSilverCompletion": "You've delved. You've dredged. You've scavenged. At last you emerge from the Dungeons, laden with runes and bars of silver, covered in sludge but exhilarated with success. You journey back to Habit City and set to work in an alchemy lab. You and @starsystemic follow the formulas @QuartzFox found, under the careful supervision of @Edge. Finally, in a great puff of glitter and smoke, your concoction settles into the familiar viscosity of a Hatching Potion!<br><br>@Edge scoops the mixture into vials and grins. “Let's give it a try, shall we? Anyone got any Eggs?”<br><br>You rush to the stables, wondering what shining secrets may yet remain undiscovered...",
"questSilverNotes": "The recent discovery of Bronze Hatching Potions has all of Habitica talking. Could potions of even brighter metals be possible? You head to Habit City's central Public Library, accompanied by @QuartzFox and @starsystemic, and gather up great armloads of books on alchemy to study.<br><br>After hours of eye-straining labour, @QuartzFox lets out a not-quite-library-appropriate shout of triumph. “Aha! I've found it!” You hurry over to see. “A Silver Hatching Potion can be made with runes of the zodiac sign Cancer, dissolved in pure silver melted over flame infused with the power of Moon runes.”<br><br>“We'll need a lot of those ingredients,” muses @starsystemic. “In case an attempt goes wrong.”<br><br>“There's only one place to find huge quantities of such random crafting materials,” says @Edge, standing in the shadow of the stacks with arms crossed. Have they been there the whole time? “The Dungeons of Drudgery. Let's get going.”",
"questSilverText": "The Silver Solution",
"questDolphinUnlockText": "Unlocks Dolphin Eggs for purchase in the Market",
@@ -722,5 +722,54 @@
"questWindupDropWindupPotion": "Wind-Up Hatching Potion",
"questWindupBoss": "Clankton",
"questWindupCompletion": "As you dodge the attacks, you notice something odd: a stripy brass tail sticking out of the robots chassis. You plunge a hand amid the grinding gears and pull out… a trembling wind-up tiger cub. It snuggles against your shirt.<br><br>The clockwork robot immediately stops flailing and smiles, its cogs clicking back into place. “Ki-Ki-Kitty! Kitty got in me!”<br><br>“Great!” the Powerful says, blushing. “Ive been working hard on these wind-up pet potions. I guess I lost track of my new creations. Ive been missing my Tidy the workshop daily a lot lately…”<br><br>You follow the tinkerer and Clankton inside. Parts, tools and potions cover every surface. “Powerful” takes your watch, but hands you a few potions.<br><br>“Take these. Clearly theyll be safer with you!”",
"questTurquoiseNotes": "@gawrone runs into your room holding their Habitican Diploma in one hand and an extraordinarily large and dusty leather-bound tome in the other.<br><br>“Youll never guess what Ive discovered!” they say. “The reason the Flourishing Fields are so fertile is that they were once covered with a vast ocean. It is rumored that ancient people once inhabited that ocean floor in enchanted cities. I have used forgotten maps to find the most likely location! Get your shovel!”<br><br>The next evening you meet up, @QuartzFox and @starsystemic joining the party, and begin to dig. Deep in the ground you find a rune, with a turquoise gem nearby!<br><br>“Keep digging!” @gawrone urges. “If we find enough, we can make one of their ancient potions and history at the same time!”"
"questTurquoiseNotes": "@gawrone runs into your room holding their Habitican Diploma in one hand and an extraordinarily large and dusty leather-bound tome in the other.<br><br>“Youll never guess what Ive discovered!” they say. “The reason the Flourishing Fields are so fertile is that they were once covered with a vast ocean. It is rumored that ancient people once inhabited that ocean floor in enchanted cities. I have used forgotten maps to find the most likely location! Get your shovel!”<br><br>The next evening you meet up, @QuartzFox and @starsystemic joining the party, and begin to dig. Deep in the ground you find a rune, with a turquoise gem nearby!<br><br>“Keep digging!” @gawrone urges. “If we find enough, we can make one of their ancient potions and history at the same time!”",
"questStoneCollectCapricornRunes": "Capricorn Runes",
"questStoneCompletion": "The work clearing overgrowth and moving loose stones taxes you to the limits of your strength. But you divide the work among the team, and place stones in the paths behind you to help you find your way back to the others. The runes you find bolster your strength and determination, too, and in the end the garden doesn't look so neglected at all!<br><br>You convene at the Library as @starsystemic suggested, and find a Magic Potion formula that uses the runes you collected. “This is an unexpected reward for attending to our neglected tasks,” says @jjgame83.<br><br>@QuartzFox agrees, “And that is on top of having a beautiful garden to enjoy with our pets.”<br><br>“Let's start making some a-mazing Mossy Stone Hatching Potions!” says @starsystemic, and everyone joins in happily.",
"questStoneCollectMossyStones": "Mossy Stones",
"questFungiNotes": "Its been a rainy spring in Habitica and the ground around the stables is spongy and damp. You notice quite a few mushrooms have appeared along the wooden stable walls and fences. Theres a fog hanging about, not quite letting the sun peek through, and its a bit dispiriting.<br><br>Out of the mist you see the outline of the April Fool, not at all his usual bouncy self.<br><br>”Id hoped to bring you all some delightful Fungi Magic Hatching Potions so that you can keep your mushroom friends from my special day forever,” he says, his expression alarmingly unsmiling. “But this cold fog is really getting to me, its making me feel too tired and dismal to work my usual magic.”<br><br>“Oh no, sorry to hear that,” you say, noticing your own increasingly somber mood. “This fog is really making the day gloomy. I wonder where it came from…”<br><br>A low rumble sounds across the fields, and you see an outline emerging from the mist. Youre alarmed to see a gigantic and unhappy looking mushroom creature, and the mist appears to be emanating from it.<br><br>“Aha,” says the Fool, “I think this fungal fellow may be the source of our blues. Lets see if we can summon a little cheer for our friend here and ourselves.”",
"questPinkMarbleUnlockText": "Unlocks Pink Marble Hatching Potions for purchase in the Market.",
"questFungiText": "The Moody Mushroom",
"questFungiCompletion": "You and the April Fool look at each other with a sign of relief as the mushroom retreats to the forest.<br><br>“Ah,” the Fool exclaims, “that was quite a mycelial melancholy. Im glad we could improve his mood, and ours too! I feel my energy coming back. Come with me and well get those Fungi potions going together.”",
"questFungiBoss": "Moody Mushroom",
"questFungiRageTitle": "Moody Mushroom Mist",
"questFungiRageDescription": "This bar fills when you don't complete your Dailies. When it's full, the Moody Mushroom will take away some of your party's pending damage",
"questFungiRageEffect": "A Mist emanates from the Moody Mushroom and surrounds your party, dampening the mood and subduing your magic. The party's MP is reduced!",
"questFungiDropFungiPotion": "Fungi Hatching Potion",
"questFungiUnlockText": "Unlocks Fungi Hatching Potions for purchase in the Market.",
"questStoneText": "A Maze of Moss",
"questSolarSystemUnlockText": "Unlocks Solar System Hatching Potions for purchase in the Market",
"questSolarSystemText": "A Voyage of Cosmic Concentration",
"questSolarSystemNotes": "Your party is traveling through the cosmos, seeing the sights in a fantastical airship designed by talented space engineer @gawrone. Its meditationite propulsion relies on the calm of your Party to stay on course.<br><br>Up ahead in the clouds of sparkling galaxies, you spot an ominously pulsing star. “Keep your focus,” warns @beffymaroo. “If we get too distracted when were passing that nova, the pull between the star and our ship may veer us off course!”<br><br>As you near the star, pulses of strange energy come toward the ship.<br><br>“Theyre Diversionoids, thought creatures trying to get us lost,” says @SabreCat. “If we can let them flow by without carrying us away, we should be able to stay pointed toward our goal!”",
"questStoneCollectMarsRunes": "Mars Runes",
"questSolarSystemCompletion": "Through careful practice, you and the crew manage to keep the Diversionoids from sweeping you overboard, just by noticing and acknowledging them without letting them take over. As you pass safely by the pulsing star, @gawrone notices a cluster of floating bottles and pulls them aboard. Each appears to contain a tiny solar system!<br><br>“Well, looks like our hard work has brought us some fine rewards!” says @beffymaroo. “Lets see what celestial wonders might appear if we hatch pet eggs with these new potions.”",
"questStoneDropMossyStonePotion": "Mossy Stone Hatching Potion",
"questSolarSystemDropSolarSystemPotion": "Solar System Hatching Potion",
"questStoneNotes": "You open the gates to the Fortress of Neglect only to be surprised by the moss that has grown all over the statues, rocks and surfaces in the garden. “Oh no, the garden has been neglected for too long!” says @jjgame83.<br><br>“Well, it's never too late to start tending to the garden,” @PixelStormArt says enthusiastically, “but where shall we start tackling the maze of moss?”<br><br>“We can make and follow a plan so we don't get lost,” says @QuartzFox.<br><br>While clearing away the mossy rocks, @starsystemic spots Mars and Capricorn runes hidden underneath. “What are these for? Let's take them back to the Habit City Library to look them up when we're finished.”<br><br>That's assuming you find your way back out of here at all, you think, but don't say aloud.",
"questSolarSystemBoss": "Diversionoids",
"questStoneUnlockText": "Unlocks Mossy Stone Hatching Potions for purchase in the Market",
"questOnyxCollectPlutoRunes": "Pluto Runes",
"questOnyxText": "The Onyx Odyssey",
"questOnyxNotes": "@Vikte, @aspiring_advocate, and @starsystemic know youve been feeling unmotivated lately and decide that a fun day out might boost your mood. However, “fun” apparently means going deep-sea diving to search the Dark Crevasse for treasure! You don your diving gear, board the boat, and row towards the ancient city of Dilatory. As you travel, you ask them what kind of treasure youre looking for.<br><br>“Pluto runes!” says @Vikte.<br><br>“No, Leo runes!” says @aspiring_advocate.<br><br>“No, onyx stones!” says @starsystemic.<br><br>As they argue among themselves, you look into the ocean and see the cave entrance directly below you! Excited, you jump up, and dive into the sea, leaving the trio to watch as you swim towards the Dark Crevasse to search for the treasure yourself.",
"questOnyxCompletion": "As you enter the Dark Crevasse, the mantis shrimps that live there dart away, seemingly scared of you. However, they quickly return carrying small coloured orbs, and you realise that these are the treasures that the others wanted! You pocket a healthy collection of each type, say goodbye to the shrimps, and head back to the boat where the others help you aboard.<br><br>“Where have you been?” @Vikte exclaims. In response you show them the treasure youve collected.<br><br>“These ingredients make Onyx Magic Hatching Potions!”, @aspiring_advocate says excitedly as you begin to head back to shore.<br><br>“So… we can hatch Onyx pets!” @starsystemic smiles. “Didnt we say this would be fun?”<br><br>You smile back, excited for your new pets, and ready to finish your tasks!",
"questOnyxCollectLeoRunes": "Leo Runes",
"questOnyxCollectOnyxStones": "Onyx Stones",
"questOnyxUnlockText": "Unlocks Onyx Hatching Potions for purchase in the Market",
"questOnyxDropOnyxPotion": "Onyx Hatching Potion",
"questVirtualPetText": "Virtual Mayhem with the April Fool: The Beepening",
"questVirtualPetNotes": "Its a quiet and pleasant spring morning in Habitica, a week past a memorable April Fools Day. You and @Beffymaroo are at the stables tending to your pets (who are still a bit confused from their time spent virtually!).<br><br>In the distance you hear a rumble and a beeping noise, soft at first but increasing in volume as if its getting closer. An egg-shape appears on the horizon and as it nears, beeping ever louder, you see that it is a gigantic virtual pet!<br><br>“Oh no,” @Beffymaroo exclaims, “I think the April Fool left some unfinished business with this big fella here, he seems to want attention!”<br><br>The virtual pet beeps angrily, throwing a virtual tantrum and whomping ever closer.",
"questVirtualPetCompletion": "Some careful button pushing seems to have fulfilled the virtual pets mysterious needs, and finally it has quieted down and appears content.<br><br>Suddenly in a burst of confetti, the April Fool appears with a basket full of strange potions emitting soft beeps.<br><br>“What timing, April Fool,” @Beffymaroo says with a wry smile. “I suspect this large beeping fellow is an acquaintance of yours.”<br><br>“Uh, yes,” the Fool says, sheepishly. “So sorry about that, and thank you both for taking care of Wotchimon! Take these potions in the way of thanks, they can bring your Virtual pets back anytime you like!”<br><br>Youre not 100% sure youre on board with all the beeping, but theyre sure cute so its worth a shot!",
"questVirtualPetBoss": "Wotchimon",
"questVirtualPetRageTitle": "The Beepening",
"questVirtualPetRageEffect": "`Wotchimon uses Bothersome Beep!` Wotchimon sounds a bothersome beep, and its happiness bar suddenly disappears! Pending damage reduced.",
"questVirtualPetDropVirtualPetPotion": "Virtual Pet Hatching Potion",
"questVirtualPetUnlockText": "Unlocks Virtual Pet Hatching Potion for purchase in the Market",
"questVirtualPetRageDescription": "This bar fills when you don't complete your Dailies. When it is full, the Wotchimon will take away some of your party's pending damage!",
"questPinkMarbleNotes": "After hearing rumors about a cave in the Meandering Mountains that has pink rocks and dust shooting out of it, your party starts to investigate. As you approach the cave, there is indeed a huge pink dust cloud and strangely, you hear a tiny voice's battle cry, followed by the sound of shattering rock.<br><br>@Empress42 accidentally inhales some of the dust and suddenly feels dreamy and less productive. “Same here!” says @QuartzFox, “I'm suddenly fantasizing about a person that I barely know!”<br><br>@a_diamond peeks into the cave and finds a little being zipping around and smashing pink marbled rock to dust. “Take cover! This Cupid has been corrupted and is using his magic to cause limerence and unrealistic infatuations! We have to subdue him!”",
"questPinkMarbleCompletion": "You manage to pin the little guy down at last he was much tougher and faster than expected. Before he stirs again, you take away his quiver of glowing arrows. He blinks and suddenly looks around in surprise. “To escape my own sorrow and heartbreak for a while I pricked myself with one of my arrows… I don't remember anything after that!”<br><br>He is just about to flee the cave, notices that @Loremi has taken a sample of the marble dust and grins. “Try using some of this pink marble dust in a potion! Nurture the pets that hatch from it and you will find that real relationships are born from communication, mutual trust and care. I wish you luck, and I wish you love!”",
"questPinkMarbleBoss": "Cupido",
"questPinkMarbleRageTitle": "Pink Punch",
"questPinkMarbleRageDescription": "This bar fills when you don't complete your Dailies. When it is full, Cupido will take away some of your party's pending damage!",
"questPinkMarbleRageEffect": "`Cupido uses Pink Punch!` That wasn't affectionate at all! Your partymates are taken aback. Pending damage reduced.",
"questPinkMarbleDropPinkMarblePotion": "Pink Marble Hatching Potion",
"questPinkMarbleText": "Calm the Corrupted Cupid"
}

View File

@@ -2,7 +2,7 @@
"settings": "Settings",
"language": "Language",
"americanEnglishGovern": "In the event of a discrepancy in the translations, the American English version governs.",
"helpWithTranslation": "Would you like to help with the translation of Habitica? Great! Then visit <a href=\"https://translate.habitica.com\">Habitica's Weblate site</a>!",
"helpWithTranslation": "Are you interested in helping with the translation of Habitica? Great! Then visit <a href=\"https://translate.habitica.com\">Habitica's Weblate site</a>!",
"stickyHeader": "Sticky header",
"newTaskEdit": "Open new tasks in edit mode",
"dailyDueDefaultView": "Set Dailies default to 'due' tab",
@@ -26,7 +26,7 @@
"resetAccPop": "Start over, removing all levels, gold, gear, history, and tasks.",
"deleteAccount": "Delete Account",
"deleteAccPop": "Cancel and remove your Habitica account.",
"feedback": "If you'd like to give us feedback, please enter it below - we'd love to know what you liked or didn't like about Habitica! Don't speak English well? No problem! Use the language you prefer.",
"feedback": "If you'd like to give us feedback, please enter it below - we'd love to hear your feedback! It will be anonymous unless you choose to enter your contact details. Don't speak English well? No problem! Use the language you prefer.",
"qrCode": "QR Code",
"dataExport": "Data Export",
"saveData": "Here are a few options for saving your data.",
@@ -36,13 +36,13 @@
"userData": "User Data",
"exportUserData": "Export User Data:",
"export": "Export",
"xml": "(XML)",
"json": "(JSON)",
"xml": "XML",
"json": "JSON",
"customDayStart": "Custom Day Start",
"sureChangeCustomDayStartTime": "Are you sure you want to change your Custom Day Start time? Your Dailies will next reset the first time you use Habitica after <%= time %>. Make sure you have completed your Dailies before then!",
"customDayStartHasChanged": "Your custom day start has changed.",
"nextCron": "Your Dailies will next reset the first time you use Habitica after <%= time %>. Make sure you have completed your Dailies before this time!",
"customDayStartInfo1": "Habitica defaults to check and reset your Dailies at midnight in your own time zone each day. You can customise that time here.",
"customDayStartInfo1": "Habitica checks and resets your Dailies at midnight in your own time zone each day. You can adjust when that happens past the default time here.",
"misc": "Misc",
"showHeader": "Show Header",
"changePass": "Change Password",
@@ -54,10 +54,10 @@
"confirmPass": "Confirm New Password",
"newUsername": "New Username",
"dangerZone": "Danger Zone",
"resetText1": "WARNING! This resets many parts of your account. This is highly discouraged, but some people find it useful in the beginning after playing with the site for a short time.",
"resetText2": "You will lose all your levels, Gold, and Experience points. All your tasks (except those from challenges) will be deleted permanently and you will lose all of their historical data. You will lose all your equipment but you will be able to buy it all back, including all limited edition equipment or subscriber Mystery items that you already own (you will need to be in the correct class to re-buy class-specific gear). You will keep your current class and your pets and mounts. You might prefer to use an Orb of Rebirth instead, which is a much safer option and which will preserve your tasks and equipment.",
"deleteLocalAccountText": "Are you sure? This will delete your account forever, and it can never be restored! You will need to register a new account to use Habitica again. Banked or spent Gems will not be refunded. If you're absolutely certain, type your password into the text box below.",
"deleteSocialAccountText": "Are you sure? This will delete your account forever, and it can never be restored! You will need to register a new account to use Habitica again. Banked or spent Gems will not be refunded. If you're absolutely certain, type \"<%= magicWord %>\" into the text box below.",
"resetText1": "<b>Be careful!</b> This resets many parts of your account. This is highly discouraged, but some people find it useful in the beginning after playing with the site for a short time.",
"resetText2": "Another option is using an <b>Orb of Rebirth</b>, which will reset everything else while preserving your Tasks and Equipment.",
"deleteLocalAccountText": "<b>Are you sure?</b> This will delete your account forever, and it can never be restored! You will need to register a new account to use Habitica again. Banked or spent Gems will not be refunded. If you're absolutely certain, type your password into the text box below.",
"deleteSocialAccountText": "<b>Are you sure?</b> This will delete your account forever, and it can never be restored! You will need to register a new account to use Habitica again. Banked or spent Gems will not be refunded. If you're absolutely certain, type <b>\"<%= magicWord %>\"</b> into the text box below.",
"API": "API",
"APIv3": "API v3",
"APIText": "Copy these for use in third party applications. However, think of your API Token like a password, and do not share it publicly. You may occasionally be asked for your User ID, but never post your API Token where others can see it, including on Github.",
@@ -76,8 +76,8 @@
"resetDo": "Do it, reset my account!",
"resetComplete": "Reset complete!",
"fixValues": "Fix Values",
"fixValuesText1": "If you've encountered a bug or made a mistake that unfairly changed your character (damage you shouldn't have taken, Gold you didn't really earn, etc.), you can manually correct your numbers here. Yes, this makes it possible to cheat: use this feature wisely, or you'll sabotage your own habit-building!",
"fixValuesText2": "Note that you cannot restore Streaks on individual tasks here. To do that, edit the Daily and go to Advanced Settings, where you will find a Restore Streak field.",
"fixValuesText1": "If you&apos;ve encountered an issue that unfairly changed your character (damage you shouldn&apos;t have taken, Gold you didn&apos;t really earn, etc.), you can manually correct those values here. Yes, this makes it possible to cheat: use this feature wisely, or you&apos;ll sabotage your own habit-building!",
"fixValuesText2": "<b>Note</b>: To restore Streaks on individual Tasks, edit the Task and use the Restore Streak field.",
"fix21Streaks": "21-Day Streaks",
"discardChanges": "Discard Changes",
"deleteDo": "Do it, delete my account!",
@@ -103,26 +103,26 @@
"giftedSubscriptionInfo": "<%= name %> gifted you a <%= months %> month subscription",
"giftedSubscriptionFull": "Hello <%= username %>, <%= sender %> has sent you <%= monthCount %> months of subscription!",
"invitedParty": "You were invited to a Party",
"invitedGuild": "You were invited to a Guild",
"invitedGuild": "You were invited to a Group",
"importantAnnouncements": "Reminders to check in to complete tasks and receive prizes",
"weeklyRecaps": "Summaries of your account activity in the past week (Note: this is currently disabled due to performance issues, but we hope to have this back up and sending e-mails again soon!)",
"onboarding": "Guidance with setting up your Habitica account",
"majorUpdates": "Important announcements",
"questStarted": "Your Quest has Begun",
"invitedQuest": "Invited to Quest",
"kickedGroup": "Kicked from group",
"kickedGroup": "Removed from group",
"remindersToLogin": "Reminders to check in to Habitica",
"unsubscribedSuccessfully": "Unsubscribed successfully!",
"unsubscribedTextUsers": "You have successfully unsubscribed from all Habitica emails. You can enable only the emails you want to receive from <a href=\"/user/settings/notifications\">Settings > &gt; Notifications</a> (requires login).",
"unsubscribedTextOthers": "You won't receive any other email from Habitica.",
"unsubscribeAllEmails": "Tick to Unsubscribe from Emails",
"unsubscribeAllEmailsText": "By ticking this box, I certify that I understand that by unsubscribing from all emails, Habitica will never be able to notify me via email about important changes to the site or my account.",
"unsubscribeAllPush": "Check to Unsubscribe from all Push Notifications",
"unsubscribeAllEmails": "Unsubscribe from Emails",
"unsubscribeAllEmailsText": "Habitica will be unable to notify you via email about important changes to the site or your account.",
"unsubscribeAllPush": "Unsubscribe from all Push Notifications",
"correctlyUnsubscribedEmailType": "Correctly unsubscribed from \"<%= emailType %>\" emails.",
"subscriptionRateText": "Recurring <strong>$<%= price %> USD</strong> every <strong><%= months %> months</strong>",
"benefits": "Benefits",
"coupon": "Coupon",
"couponText": "We sometimes have events and give out promo codes for special gear (eg, those who stop by our Wondercon booth)",
"couponText": "We sometimes have events and give out promo codes for special gear.",
"apply": "Apply",
"promoCode": "Promo Code",
"promoCodeApplied": "Promo Code Applied! Check your inventory",
@@ -135,7 +135,7 @@
"generate": "Generate",
"getCodes": "Get Codes",
"webhooks": "Webhooks",
"webhooksInfo": "Habitica provides webhooks so that when certain actions occur in your account, information can be sent to a script on another website. You can specify those scripts here. Be careful with this feature because specifying an incorrect URL can cause errors or slowness in Habitica. For more information, see the wiki's <a target=\"_blank\" href=\"https://habitica.fandom.com/wiki/Webhooks\">Webhooks</a> page.",
"webhooksInfo": "Webhooks provide a way for developers to receive notifications when a particular action is performed, such as scoring or updating a Task, or sending a message in a Group. By creating a webhook, you will be able to listen to changes in Habitica and build apps that respond to these changes.<br><br>For additional information and examples on webhooks, please visit our <a target=\"_blank\" href=\"https://habitica.fandom.com/wiki/Webhooks\">API Docs</a>",
"enabled": "Enabled",
"webhookURL": "Webhook URL",
"invalidUrl": "invalid URL",
@@ -159,7 +159,7 @@
"amazonPayments": "Amazon Payments",
"amazonPaymentsRecurring": "Ticking the checkbox below is necessary for your subscription to be created. It allows your Amazon account to be used for ongoing payments for <strong>this</strong> subscription. It will not cause your Amazon account to be automatically used for any future purchases.",
"timezone": "Time Zone",
"timezoneUTC": "Habitica uses the time zone set on your PC, which is: <strong><%= utc %></strong>",
"timezoneUTC": "Your time zone is set by your computer, which is: <strong><%= utc %></strong>",
"timezoneInfo": "If that time zone is wrong, first reload this page using your browser's reload or refresh button to ensure that Habitica has the most recent information. If it is still wrong, adjust the time zone on your PC and then reload this page again.<br><br> <strong>If you use Habitica on other PCs or mobile devices, the time zone must be the same on them all.</strong> If your Dailies have been resetting at the wrong time, repeat this check on all other PCs and on a browser on your mobile devices.",
"push": "Push",
"about": "About",
@@ -183,5 +183,101 @@
"chatExtension": "<a target='blank' href='https://chrome.google.com/webstore/detail/habitrpg-chat-client/hidkdfgonpoaiannijofifhjidbnilbb'>Chrome Chat Extension</a> and <a target='blank' href='https://addons.mozilla.org/en-US/firefox/addon/habitica-chat-client-2/'>Firefox Chat Extension</a>",
"displaynameIssueNewline": "Display Names may not contain backslashes followed by the letter N.",
"resetAccount": "Reset Account",
"giftedSubscriptionWinterPromo": "Hello <%= username %>, you received <%= monthCount %> months of subscription as part of our holiday gift-giving promotion!"
"giftedSubscriptionWinterPromo": "Hello <%= username %>, you received <%= monthCount %> months of subscription as part of our holiday gift-giving promotion!",
"dayStartAdjustment": "Day Start Adjustment",
"suggestMyUsername": "Suggest my username",
"transaction_gift_send": "<b>Gifted</b> to",
"contentRelease": "Content releases + Events",
"bannedWordUsedInProfile": "Your Display Name or About text contained inappropriate language.",
"changeDisplayNameDisclaimer": "This is the name that will be displayed for your Avatar in Habitica.",
"changePasswordDisclaimer": "Password must be 8 characters or more. We recommend a strong password that you're not using elsewhere.",
"dateFormatDisclaimer": "Adjust the date formatting across Habitica.",
"enableAudio": "Enable Audio",
"playDemoAudio": "Play Demo",
"bannedSlurUsedInProfile": "Your Display Name or About text contained a slur, and your chat privileges have been revoked.",
"timestamp": "Timestamp",
"amount": "Amount",
"action": "Action",
"note": "Note",
"noClassSelected": "No Class Selected",
"currentClass": "Current Class",
"changeClassSetting": "Change Class",
"chooseClassSetting": "Choose Class",
"changeClassDisclaimer": "Changing your class will refund all of your existing Stat Points. Once you have selected your new class, adjust your Stat Points from the Stats section of your profile.",
"remainingBalance": "Remaining Balance",
"noHourglassTransactions": "You don't have any hourglass transactions yet.",
"transaction_create_guild": "<b>Created</b> guild",
"transaction_change_class": "<b>Class</b> change",
"transaction_rebirth": "Used Orb of Rebirth",
"transaction_release_pets": "Released pets",
"transaction_release_mounts": "Released mounts",
"transaction_reroll": "Used Fortify Potion",
"transaction_admin_update_hourglasses": "<b>Admin</b> updated",
"connected": "Connected",
"connect": "Connect",
"remove": "Remove",
"resetTextLocal": "If you're absolutely certain, type your password into the text box below.",
"resetTextSocial": "If you're absolutely certain, type <b>\"<%= magicWord %>\"</b> into the text box below.",
"APITokenDisclaimer": "<b>Your API Token is like a password; Do not share it publicly.</b> You may occasionally be asked for your User ID, but never post your API Token where others can see it, including on Github.<br><br><b>Note:</b> If you need a new API Token (e.g., if you accidentally shared it), email <a href='mailto:admin@habitica.com' target='_blank'>admin@habitica.com</a> 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.",
"audioThemeDisclaimer": "Audio themes add optional sound effects to the Habitica website. Volume levels are controlled using your computer's volume settings.",
"gemCap": "Gem Cap",
"nextHourglass": "Next Hourglass",
"transaction_buy_gold": "<b>Bought</b> with gold",
"transaction_create_challenge": "<b>Created</b> challenge",
"transaction_create_bank_challenge": "<b>Created</b> bank challenge",
"transaction_subscription_perks": "<b>Subscription</b> perk",
"transaction_admin_update_balance": "<b>Admin</b> given",
"thirdPartyTools": "Find third party apps, extensions, and all kinds of other tools you can use with your account on the <a href='https://habitica.fandom.com/wiki/Extensions,_Add-Ons,_and_Customizations' target='_blank'>Habitica wiki</a>.",
"passwordSuccess": "Password successfully changed",
"giftSubscriptionRateText": "<strong>$<%= price %> USD</strong> for <strong><%= months %> months</strong>",
"addPasswordAuth": "Add Password",
"onlyPrivateSpaces": "Only in private spaces",
"adjustment": "Adjustment",
"passwordIssueLength": "Passwords must be between 8 and 64 characters.",
"mentioning": "Mentioning",
"everywhere": "Everywhere",
"transactions": "Transactions",
"hourglassTransactions": "Hourglass Transactions",
"noGemTransactions": "You don't have any gem transactions yet.",
"transaction_debug": "Debug Action",
"transaction_buy_money": "<b>Bought</b> with money",
"transaction_contribution": "<b>Tier</b> change",
"nextHourglassDescription": "Subscribers receive Mystic Hourglasses within\nthe first three days of the month.",
"transaction_spend": "<b>Spent</b> on",
"transaction_gift_receive": "<b>Received</b> from",
"generalSettings": "General Settings",
"siteData": "Site Data",
"taskSettings": "Task Settings",
"confirmCancelChanges": "Are you sure? You will lose your unsaved changes.",
"account": "Account",
"loginMethods": "Login Methods",
"character": "Character",
"siteLanguage": "Site Language",
"showLevelUpModal": "When Gaining a Level",
"showHatchPetModal": "When Hatching a Pet",
"showRaisePetModal": "When Raising a Pet into a Mount",
"showStreakModal": "When Attaining a Streak Achievement",
"baileyAnnouncement": "Latest Bailey Announcement",
"view": "View",
"feedbackPlaceholder": "Add your feedback",
"downloadCSV": "Download CSV",
"downloadAs": "Download as",
"yourUserData": "Your User Data",
"taskHistory": "Task History",
"yourUserDataDisclaimer": "Here you can download a copy of your task history or your full user data.",
"useridCopied": "User ID copied to clipboard.",
"userIdTooltip": "The User ID is a unique number that Habitica automatically generates when a player joins, similar to a Username. However, unlike the Username, a User ID can not be changed.",
"developerMode": "Developer Mode",
"developerModeTooltip": "Habitica provides a developer mode to enable additional features that interact with Habitica's API.",
"api": "API",
"currentPass": "Current Password",
"resetDetail1": "You will lose all your levels, Gold, and Experience points.",
"resetDetail2": "You will keep your current class, achievements and your pets and mounts.",
"resetDetail3": "All your tasks (except those from challenges) will be deleted permanently and you will lose all of their historical data.",
"resetDetail4": "You will lose all your equipment except Subscriber Mystery Items and free commemorative items. You will be able to buy the deleted items back, including all limited edition equipment (you will need to be in the correct class to re-buy class-specific gear).",
"APICopied": "API token copied to clipboard.",
"APITokenTitle": "API Token",
"userNameSuccess": "Username successfully changed",
"addWebhook": "Add Webhook",
"changeEmailDisclaimer": "This is the email address that you use to log in to Habitica, as well as receive notifications."
}

View File

@@ -120,7 +120,7 @@
"paypalCanceled": "Your subscription has been cancelled",
"choosePaymentMethod": "Choose your payment method",
"buyGemsSupportsDevs": "Purchasing Gems supports the developers and helps keep Habitica running",
"support": "SUPPORT",
"support": "Support",
"gemBenefitLeadin": "What can you buy with Gems?",
"gemBenefit1": "Unique and fashionable costumes for your avatar.",
"gemBenefit2": "Backgrounds to immerse your avatar in the world of Habitica!",
@@ -132,8 +132,8 @@
"subscriptionBenefit5": "Receive the Royal Purple Jackalope pet when you become a new subscriber.",
"subscriptionBenefit6": "Earn Mystic Hourglasses to purchase items in the Time Travelers Shop!",
"purchaseAll": "Purchase Set",
"gemsRemaining": "Gems remaining",
"notEnoughGemsToBuy": "You are unable to buy that amount of Gems",
"gemsRemaining": "remaining",
"notEnoughGemsToBuy": "No more Gems available for purchase this month. More will become available within the first 3 days of each month.",
"mysterySet201902": "Cryptic Crush Set",
"mysterySet201908": "Footloose Faun Set",
"mysterySet201907": "Beach Buddy Set",
@@ -159,7 +159,7 @@
"needToUpdateCard": "Need to update your card?",
"subMonths": "Sub Months",
"subscriptionStats": "Subscription Stats",
"subscriptionInactiveDate": "Your subscription benefits will become inactive on <strong><%= date %></strong>",
"subscriptionInactiveDate": "Your subscription benefits will become inactive on <br><strong><%= date %></strong>",
"subscriptionCanceled": "Your subscription is canceled",
"youAreSubscribed": "You are subscribed to Habitica",
"doubleDropCap": "Double the Drops",
@@ -191,5 +191,51 @@
"howManyGemsPurchase": "How many Gems would you like to purchase?",
"howManyGemsSend": "How many Gems would you like to send?",
"needToPurchaseGems": "Need to purchase Gems as a gift?",
"wantToSendOwnGems": "Want to send your own Gems?"
"wantToSendOwnGems": "Want to send your own Gems?",
"mysterySet202312": "Wintry Blue Set",
"mysterySet202303": "Mane Character Set",
"mysterySet202403": "Lucky Legend Set",
"mysterySet202401": "Snowy Spellbinder Set",
"mysterySet202112": "Antarctic Undine Set",
"mysterySet202209": "Magical Scholar Set",
"mysterySet202402": "Paradise Pink Set",
"mysterySet202308": "Purple Protagonist Set",
"mysterySet202404": "Mycelial Magus Set",
"mysterySet202405": "Gilded Dragon Set",
"mysterySet202210": "Ominous Ophidian Set",
"mysterySet202406": "Phantom Buccaneer Set",
"mysterySet202311": "All-Seeing Spellbinder Set",
"sendAGift": "Send Gift",
"haveNonRecurringSub": "You have a non-recurring gift subscription.",
"switchToRecurring": "Switch to a recurring subscription?",
"subscriptionCreditConversion": "Starting a new subscription will convert any remaining months to credit that will be used after the recurring subscription is cancelled.",
"monthlyGems": "Monthly Gems:",
"mysterySet202301": "Valiant Vulpine Set",
"continueGiftSubBenefits": "Want to continue your benefits? You can start a new subscription before your gifted one runs out to keep your benefits active.",
"mysterySet202103": "Blossom Viewing Set",
"mysterySet202104": "Thistle Guardian Set",
"mysterySet202105": "Nebula Dragon Set",
"mysterySet202106": "Sunset Siren Set",
"mysterySet202107": "Beachy Keen Set",
"mysterySet202108": "Fiery Shounen Set",
"mysterySet202109": "Lunar Lepidopteran Set",
"mysterySet202111": "Cosmic Chronomancer Set",
"mysterySet202201": "Midnight Merrymaker Set",
"mysterySet202203": "Dauntless Dragonfly Set",
"mysterySet202205": "Dusk-Winged Dragon Set",
"mysterySet202207": "Jammin' Jelly Set",
"mysterySet202211": "Electromancer Set",
"mysterySet202206": "Sea Sprite Set",
"mysterySet202110": "Mossy Gargoyle Set",
"mysterySet202208": "Perky Ponytail Set",
"mysterySet202306": "Razzle Dazzle Rainbow Set",
"mysterySet202204": "Virtual Adventurer Set",
"mysterySet202202": "Turquoise Twintails Set",
"mysterySet202307": "Perilous Kraken Set",
"mysterySet202212": "Glacial Guardian Set",
"mysterySet202309": "Colossal Comet Moth Set",
"mysterySet202305": "Eventide Dragon Set",
"mysterySet202302": "Trickster Tabby Set",
"mysterySet202304": "Tiptop Teapot Set",
"mysterySet202310": "Ghostlight Wraith Set"
}

View File

@@ -135,5 +135,15 @@
"pressEnterToAddTag": "Press Enter to add tag: '<%= tagName %>'",
"enterTag": "Enter a tag",
"addTags": "Add tags...",
"tomorrow": "Tomorrow"
"tomorrow": "Tomorrow",
"counter": "Counter",
"taskSummary": "<%= type %> Summary",
"adjustCounter": "Adjust Counter",
"resetCounter": "Reset Counter",
"editTagsText": "Edit Tags",
"taskAlias": "Task Alias",
"taskAliasPopover": "This task alias can be used when integrating with 3rd party integrations. Only dashes, underscores, and alphanumeric characters are supported. The task alias must be unique among all your tasks.",
"taskAliasPlaceholder": "your-task-alias-here",
"scoreUp": "Score up",
"scoreDown": "Score down"
}

View File

@@ -686,7 +686,7 @@
"questFluoriteBoss": "蛍石の素",
"questAmberText": "琥珀の同盟",
"questFluoriteCompletion": "あなたが戦闘を始めると、クリスタルクリーチャーは、あなたが作成している光のショーに気を取られているように見えます。「ぴかぴかだ……」と呟きました。<br><br>「もちろん!」と @nirbhaoは叫びます。「『蛍石の素 』に違いない。彼らが欲しがっているのは、光だ。輝かせてあげよう」<br><br>魔法の松明やちりに火を灯すと蛍石の素は楽しそうに輝き、一気に明るくなります。また輝いていて嬉しいので、蛍石の結晶の豊富な鉱床へと導いてくれます。<br><br>「これは新しいたまごがえしの薬の材料として最適です」と@nirbhaoは言います。「私たちのペットを蛍光灯のように明るくしてくれるものとして」",
"sandySidekicksNotes": "「ゆるゆるのアルマジロ」「気晴らしの大蛇」「氷のクモ」のセット。<%= date %>まで購入できます。",
"sandySidekicksNotes": "「ゆるゆるのアルマジロ」「気晴らしの大蛇」「氷のクモ」のセット。",
"sandySidekicksText": "「砂の相棒」クエストセット",
"questAmberBoss": "琥珀トカゲ",
"questAmberCompletion": "「琥珀トカゲさん?」@-Tyr-は慎重に口を開きます。「@Vikteを放してもらえますか @Vikteは高いところはそんなに好きじゃないみたい」<br><br>琥珀トカゲは琥珀色の肌の顔を赤くして、@Vikteを優しく地面に下ろしました。「すまんのう ずいぶんと長い間、お客さんなど来たことがなかったから、マナーなぞ忘れておったわい」琥珀トカゲは木から滑り降りると、礼儀よく挨拶し、住み家に向かいました。そして腕いっぱいに魔法のたまごがえしの薬をお詫びとして持ってきたのです<br><br>「魔法の薬!」@Vikteは息を切らしながら言います。<br><br>「おや、この薬はちょっと古いかのう」琥珀トカゲの舌が考えるようにちらちら動きます。「こういうのはどうじゃろう? お前さんたちが定期的に我が家に遊びに来てくれると約束してくれるなら、うちにある全部の魔法の薬をお前さんたちにあげようじゃないか……」<br><br>そうして3人はタスクの森を後にしました。新しい魔法の薬のことと、新しい友達のことをみんなに話さなくっちゃ",

View File

@@ -762,5 +762,15 @@
"questPinkMarbleText": "Acalme o Cupido Corrompido",
"questPinkMarbleNotes": "Depois de ouvir rumores sobre uma caverna nas Montanhas Sinuosas que possui rochas e poeira rosas dentro dela, nosso grupo começou a investigar. Conforme vocês se aproximam da caverna, há de fato uma enorme nuvem de poeira rosa e é estranho porque vocês começam a ouvir um grito de guerra bem baixo, seguido do som de uma rocha quebrando.<br><br>@Empress42 acidentalmente inala um pouco de poeira e começa a se sentir com sono e com menos produtividade. \"Eu também!\" diz @QuartzFox, \"Estou alucinando com uma pessoa que mal conheço!\"<br><br>@a_diamond olha dentro da caverna e encontra um pequeno ser correndo e quebrando mármore rosa, transformando em poeira. \"Protejam-se! Esse Cupido foi corrompido e está usando sua mágica para causar limerência e paixão mentirosa! Devemos esmagá-lo!\"",
"questPinkMarbleCompletion": "Vocês conseguiram derrotar o pequeno ser finalmente ele era muito mais forte e rápido do que se imaginava. Antes dele se mexer novamente, você pega a aljava de flechas brilhantes dele. Ele pisca e de repente olha ao redor surpreso. \"Para não ficar tão triste de coração quebrado, eu me espetei com uma das minhas flechas... Não me lembro de mais nada!\"<br><br>Ele estava prestes a voar pra fora da caverna, mas nota que @Loremi pegou uma amostra de poeira do mármore e dá um grande sorriso. \"Tente usar um pouco dessa poeira de mármore rosa em uma poção! Alimente os mascotes que foram chocados com ela e você saberá que relações verdadeiras nascem da comunicação, confiança e cuidado mútuo. Desejo sorte e amor para vocês!\"",
"QuestPinkMarbleUnlockText": "Habilita a compra de Poções de Eclosão de Mármore Rosa pelo Mercado."
"QuestPinkMarbleUnlockText": "Habilita a compra de Poções de Eclosão de Mármore Rosa pelo Mercado.",
"questPinkMarbleUnlockText": "Desbloqueia Poções de Eclosão de Pérola Negra para compra no Mercado.",
"questFungiRageEffect": "Uma névoa emana do Cogumelo Mal-humorado e cerca seu grupo, abafando o clima e subjugando sua magia. O MP do grupo é reduzido!",
"questFungiNotes": "Foi uma primavera chuvosa em Habitica e o chão ao redor dos estábulos está esponjoso e úmido. Você percebe que alguns cogumelos apareceram ao longo das paredes e cercas de madeira do estábulo. Há uma névoa pairando, não deixando o sol aparecer, e é um pouco desanimador.<br><br>Fora da névoa, você vê o contorno do Piadista, nem um pouco saltitante como de costume.<br><br>\"Eu esperava trazer a todos vocês algumas deliciosas Poções de Eclosão de Fungos Mágicos para que vocês pudessem manter seus amigos cogumelos do meu dia especial para sempre\", ele diz, sua expressão alarmantemente séria. \"Mas essa névoa fria está realmente me afetando, me fazendo sentir muito cansado e triste para fazer minha mágica habitual.\"<br><br>\"Ah, não, sinto muito por ouvir isso\", você diz, percebendo seu próprio humor cada vez mais sombrio. \"Essa névoa está realmente tornando o dia sombrio. Eu me pergunto de onde veio…\"<br><br>Um estrondo baixo soa pelos campos, e você vê um contorno emergindo da névoa. Você fica alarmado ao ver uma criatura gigante e infeliz em forma de cogumelo, e a névoa parece estar emanando dela.<br><br>\"Aha,\" diz o Piadista, \"eu acho que esse sujeito fungo pode ser a fonte da nossa tristeza. Vamos ver se conseguimos invocar um pouco de alegria para o nosso amigo aqui e para nós mesmos.\"",
"questFungiText": "O Cogumelo Mal-humorado",
"questFungiBoss": "Cogumelo Mal-humorado",
"questFungiRageTitle": "Névoa do Cogumelo Mal-humorado",
"questFungiRageDescription": "Esta barra enche quando você não completa suas Diárias. Quando estiver cheia, o Cogumelo Mal-humorado removerá parte do dano pendente do seu grupo",
"questFungiDropFungiPotion": "Poção de Eclosão de Fungos",
"questFungiUnlockText": "Desbloqueia Poções de Eclosão de Fungos para compra no Mercado.",
"questFungiCompletion": "Você e o Piadista olham um para o outro com um sinal de alívio enquanto o cogumelo recua para a floresta.<br><br>“Ah,” o Piadista exclama, \"aquela foi uma melancolia micelial. Estou feliz que conseguimos melhorar o humor dele, e o nosso também! Sinto minha energia voltando. Venha comigo e vamos fazer aquelas poções de fungos juntos.\""
}

View File

@@ -1,7 +1,7 @@
{
"questEvilSantaText": "Pälsjägartomten",
"questEvilSantaNotes": "Du hör sorgfulla vrål djupt från isfälten. Du följer rytandet och morrandet - blandat med en kacklande röst - till en glänta i skogen där du ser en fullvuxen isbjörn. Hon är inburad och kedjad och vrålar för sitt liv. Ovanpå buren dansar en ondsint liten imp, iförd gamla tomtedräkter. Besegra PälsjägarTomten och rädda besten!",
"questEvilSantaCompletion": "PälsjägarTomten tjuter av ilska och studsar iväg i natten. En tacksam Hon-björn försöker genom att ryta och morra tala om något för dig. Du tar henne till stallarna, där Matt Boch Djurviskaren lyssnar till hennes berättelse och flämtar till av fasa. Hon har en unge! Han flydde in i isfälten när mamma björn fångades. Hjälp henne hitta sin unge.",
"questEvilSantaCompletion": "Pälsjägartomten tjuter av ilska och studsar iväg i natten. En tacksam hon-björn försöker genom att ryta och morra tala om något för dig. Du tar henne till stallet, där Djurviskaren Matt Boch lyssnar till hennes berättelse och flämtar till av fasa. Hon har en unge! Han flydde till isfälten när mamma björn fångades.",
"questEvilSantaBoss": "Pälsjägartomten",
"questEvilSantaDropBearCubPolarMount": "Isbjörn (Riddjur)",
"questEvilSanta2Text": "Hitta Björnungen",

View File

@@ -623,6 +623,9 @@ const backgrounds = {
backgrounds062024: {
shell_gate: { },
},
backgrounds072024: {
river_bottom: { },
},
eventBackgrounds: {
birthday_bash: {
price: 0,

View File

@@ -0,0 +1,21 @@
export const ARMOIRE_RELEASE_DATES = {
somethingSpooky: { year: 2023, month: 10 },
cookingImplementsTwo: { year: 2023, month: 11 },
greenTrapper: { year: 2023, month: 12 },
schoolUniform: { year: 2024, month: 1 },
whiteLoungeWear: { year: 2024, month: 2 },
hatterSet: { year: 2024, month: 3 },
optimistSet: { year: 2024, month: 4 },
pottersSet: { year: 2024, month: 5 },
beachsideSet: { year: 2024, month: 6 },
corsairSet: { year: 2024, month: 7 },
};
export const EGGS_RELEASE_DATES = {
Giraffe: { year: 2024, month: 6, day: 1 },
Chameleon: { year: 2024, month: 7, day: 1 },
};
export const HATCHING_POTIONS_RELEASE_DATES = {
Koi: { year: 2024, month: 6, day: 1 },
};

View File

@@ -377,6 +377,7 @@ export const MONTHLY_SCHEDULE = {
'dilatory_derby',
'armadillo',
'guineapig',
'chameleon',
],
},
{

View File

@@ -1,7 +1,10 @@
import assign from 'lodash/assign';
import defaults from 'lodash/defaults';
import each from 'lodash/each';
import assign from 'lodash/assign';
import t from './translation';
import { filterReleased } from './is_released';
import { EGGS_RELEASE_DATES } from './constants/releaseDates';
import datedMemoize from '../fns/datedMemoize';
function applyEggDefaults (set, config) {
each(set, (egg, key) => {
@@ -396,6 +399,12 @@ const quests = {
adjective: t('questEggGiraffeAdjective'),
canBuy: hasQuestAchievementFunction('giraffe'),
},
Chameleon: {
text: t('questEggChameleonText'),
mountText: t('questEggChameleonMountText'),
adjective: t('questEggChameleonAdjective'),
canBuy: hasQuestAchievementFunction('chameleon'),
},
};
applyEggDefaults(drops, {
@@ -410,10 +419,20 @@ applyEggDefaults(quests, {
},
});
const all = assign({}, drops, quests);
function filterEggs (eggs) {
return filterReleased(eggs, 'key', EGGS_RELEASE_DATES);
}
export {
drops,
quests,
all,
const memoizedFilter = datedMemoize(filterEggs);
export default {
get drops () {
return memoizedFilter({ memoizeConfig: true, identifier: 'drops' }, drops);
},
get quests () {
return memoizedFilter({ memoizeConfig: true, identifier: 'quests' }, quests);
},
get all () {
return assign({}, this.drops, this.quests);
},
};

View File

@@ -2,12 +2,13 @@ import defaults from 'lodash/defaults';
import find from 'lodash/find';
import forEach from 'lodash/forEach';
import moment from 'moment';
import nconf from 'nconf';
import upperFirst from 'lodash/upperFirst';
import { ownsItem } from '../gear-helper';
import { ATTRIBUTES } from '../../../constants';
import t from '../../translation';
import memoize from '../../../fns/datedMemoize';
import { ARMOIRE_RELEASE_DATES as releaseDates } from '../../constants/releaseDates';
import { buildReleaseDate } from '../../is_released';
const armor = {
lunarArmor: {
@@ -485,6 +486,10 @@ const armor = {
con: 13,
set: 'beachsideSet',
},
corsairsCoatAndCape: {
con: 14,
set: 'corsairSet',
},
};
const body = {
@@ -994,6 +999,10 @@ const head = {
int: 8,
set: 'pottersSet',
},
corsairsBandana: {
int: 7,
set: 'corsairSet',
},
};
const shield = {
@@ -1831,21 +1840,13 @@ const weapon = {
per: 12,
set: 'beachsideSet',
},
corsairsBlade: {
str: 7,
set: 'corsairSet',
},
};
const SWITCHOVER_TIME = nconf.get('CONTENT_SWITCHOVER_TIME_OFFSET') || 0;
const releaseDay = 7;
const releaseDates = {
somethingSpooky: { year: 2023, month: 10 },
cookingImplementsTwo: { year: 2023, month: 11 },
greenTrapper: { year: 2023, month: 12 },
schoolUniform: { year: 2024, month: 1 },
whiteLoungeWear: { year: 2024, month: 2 },
hatterSet: { year: 2024, month: 3 },
optimistSet: { year: 2024, month: 4 },
pottersSet: { year: 2024, month: 5 },
beachsideSet: { year: 2024, month: 6 },
};
forEach({
armor,
@@ -1890,12 +1891,12 @@ forEach({
function updateReleased (type) {
const today = moment();
const releaseDateEndPart = `${String(releaseDay).padStart(2, '0')}T${String(SWITCHOVER_TIME).padStart(2, '0')}:00-0500`;
const returnType = {};
forEach(type, (gearItem, gearKey) => {
let released;
if (releaseDates[gearItem.set]) {
const releaseDateString = `${releaseDates[gearItem.set].year}-${String(releaseDates[gearItem.set].month).padStart(2, '0')}-${releaseDateEndPart}`;
const components = releaseDates[gearItem.set];
const releaseDateString = buildReleaseDate(components.year, components.month, releaseDay);
released = today.isAfter(releaseDateString);
} else {
released = true;
@@ -1931,4 +1932,16 @@ export default {
get weapon () {
return memoizedUpdatReleased({ identifier: 'weapon', memoizeConfig: true }, weapon);
},
// convenience method for tests mostly. Not used in the app
get all () {
const items = [];
items.push(...Object.values(this.armor));
items.push(...Object.values(this.body));
items.push(...Object.values(this.eyewear));
items.push(...Object.values(this.head));
items.push(...Object.values(this.headAccessory));
items.push(...Object.values(this.shield));
items.push(...Object.values(this.weapon));
return items;
},
};

View File

@@ -66,6 +66,7 @@ const armor = {
202310: { },
202401: { },
202406: { },
202407: { },
301404: { },
301703: { },
301704: { },
@@ -226,6 +227,7 @@ const head = {
202403: { },
202404: { },
202406: { },
202407: { },
301404: { },
301405: { },
301703: { },

View File

@@ -973,6 +973,7 @@ const eyewear = {
text: t('eyewearSpecialSummerRogueText'),
notes: t('eyewearSpecialSummerRogueNotes'),
value: 20,
season: 'summer',
},
summerWarrior: {
specialClass: 'warrior',
@@ -980,6 +981,7 @@ const eyewear = {
text: t('eyewearSpecialSummerWarriorText'),
notes: t('eyewearSpecialSummerWarriorNotes'),
value: 20,
season: 'summer',
},
blackTopFrame: {
gearSet: 'glasses',

View File

@@ -2,6 +2,9 @@ import defaults from 'lodash/defaults';
import each from 'lodash/each';
import { assign } from 'lodash';
import t from './translation';
import datedMemoize from '../fns/datedMemoize';
import { filterReleased } from './is_released';
import { HATCHING_POTIONS_RELEASE_DATES } from './constants/releaseDates';
function hasQuestAchievementFunction (key) {
return user => user.achievements.quests && user.achievements.quests[key] > 0;
@@ -194,8 +197,23 @@ each(wacky, (pot, key) => {
});
});
const all = assign({}, drops, premium, wacky);
function filterEggs (eggs) {
return filterReleased(eggs, 'key', HATCHING_POTIONS_RELEASE_DATES);
}
export {
drops, premium, wacky, all,
const memoizedFilter = datedMemoize(filterEggs);
export default {
get drops () {
return memoizedFilter({ memoizeConfig: true, identifier: 'drops' }, drops);
},
get premium () {
return memoizedFilter({ memoizeConfig: true, identifier: 'premium' }, premium);
},
get wacky () {
return memoizedFilter({ memoizeConfig: true, identifier: 'wacky' }, wacky);
},
get all () {
return assign({}, this.drops, this.premium, this.wacky);
},
};

View File

@@ -18,9 +18,9 @@ import {
import achievements from './achievements';
import * as eggs from './eggs';
import * as hatchingPotions from './hatching-potions';
import * as stable from './stable';
import eggs from './eggs';
import hatchingPotions from './hatching-potions';
import stable from './stable';
import gear from './gear';
import { quests, questsByLevel, userCanOwnQuestCategories } from './quests';
@@ -38,6 +38,7 @@ import { REPEATING_EVENTS, getRepeatingEvents } from './constants/events';
import loginIncentives from './loginIncentives';
import officialPinnedItems from './officialPinnedItems';
import memoize from '../fns/datedMemoize';
const api = {};
@@ -165,9 +166,18 @@ api.cardTypes = {
api.special = api.spells.special;
api.dropEggs = eggs.drops;
api.questEggs = eggs.quests;
api.eggs = eggs.all;
Object.defineProperty(api, 'dropEggs', {
get () { return eggs.drops; },
enumerable: true,
});
Object.defineProperty(api, 'questEggs', {
get () { return eggs.quests; },
enumerable: true,
});
Object.defineProperty(api, 'eggs', {
get () { return eggs.all; },
enumerable: true,
});
api.timeTravelStable = {
pets: {
@@ -186,298 +196,354 @@ api.timeTravelStable = {
},
};
api.dropHatchingPotions = hatchingPotions.drops;
api.premiumHatchingPotions = hatchingPotions.premium;
api.wackyHatchingPotions = hatchingPotions.wacky;
api.hatchingPotions = hatchingPotions.all;
api.pets = stable.dropPets;
api.premiumPets = stable.premiumPets;
api.questPets = stable.questPets;
api.specialPets = stable.specialPets;
api.wackyPets = stable.wackyPets;
api.petInfo = stable.petInfo;
api.mounts = stable.dropMounts;
api.questMounts = stable.questMounts;
api.premiumMounts = stable.premiumMounts;
api.specialMounts = stable.specialMounts;
api.mountInfo = stable.mountInfo;
api.food = {
Meat: {
text: t('foodMeat'),
textA: t('foodMeatA'),
textThe: t('foodMeatThe'),
target: 'Base',
},
Milk: {
text: t('foodMilk'),
textA: t('foodMilkA'),
textThe: t('foodMilkThe'),
target: 'White',
},
Potatoe: {
text: t('foodPotatoe'),
textA: t('foodPotatoeA'),
textThe: t('foodPotatoeThe'),
target: 'Desert',
},
Strawberry: {
text: t('foodStrawberry'),
textA: t('foodStrawberryA'),
textThe: t('foodStrawberryThe'),
target: 'Red',
},
Chocolate: {
text: t('foodChocolate'),
textA: t('foodChocolateA'),
textThe: t('foodChocolateThe'),
target: 'Shade',
},
Fish: {
text: t('foodFish'),
textA: t('foodFishA'),
textThe: t('foodFishThe'),
target: 'Skeleton',
},
RottenMeat: {
text: t('foodRottenMeat'),
textA: t('foodRottenMeatA'),
textThe: t('foodRottenMeatThe'),
target: 'Zombie',
},
CottonCandyPink: {
text: t('foodCottonCandyPink'),
textA: t('foodCottonCandyPinkA'),
textThe: t('foodCottonCandyPinkThe'),
target: 'CottonCandyPink',
},
CottonCandyBlue: {
text: t('foodCottonCandyBlue'),
textA: t('foodCottonCandyBlueA'),
textThe: t('foodCottonCandyBlueThe'),
target: 'CottonCandyBlue',
},
Honey: {
text: t('foodHoney'),
textA: t('foodHoneyA'),
textThe: t('foodHoneyThe'),
target: 'Golden',
},
Saddle: {
sellWarningNote: t('foodSaddleSellWarningNote'),
text: t('foodSaddleText'),
value: 5,
notes: t('foodSaddleNotes'),
canDrop: false,
},
/* eslint-disable camelcase */
Cake_Skeleton: {
text: t('foodCakeSkeleton'),
textA: t('foodCakeSkeletonA'),
textThe: t('foodCakeSkeletonThe'),
target: 'Skeleton',
},
Cake_Base: {
text: t('foodCakeBase'),
textA: t('foodCakeBaseA'),
textThe: t('foodCakeBaseThe'),
target: 'Base',
},
Cake_CottonCandyBlue: {
text: t('foodCakeCottonCandyBlue'),
textA: t('foodCakeCottonCandyBlueA'),
textThe: t('foodCakeCottonCandyBlueThe'),
target: 'CottonCandyBlue',
},
Cake_CottonCandyPink: {
text: t('foodCakeCottonCandyPink'),
textA: t('foodCakeCottonCandyPinkA'),
textThe: t('foodCakeCottonCandyPinkThe'),
target: 'CottonCandyPink',
},
Cake_Shade: {
text: t('foodCakeShade'),
textA: t('foodCakeShadeA'),
textThe: t('foodCakeShadeThe'),
target: 'Shade',
},
Cake_White: {
text: t('foodCakeWhite'),
textA: t('foodCakeWhiteA'),
textThe: t('foodCakeWhiteThe'),
target: 'White',
},
Cake_Golden: {
text: t('foodCakeGolden'),
textA: t('foodCakeGoldenA'),
textThe: t('foodCakeGoldenThe'),
target: 'Golden',
},
Cake_Zombie: {
text: t('foodCakeZombie'),
textA: t('foodCakeZombieA'),
textThe: t('foodCakeZombieThe'),
target: 'Zombie',
},
Cake_Desert: {
text: t('foodCakeDesert'),
textA: t('foodCakeDesertA'),
textThe: t('foodCakeDesertThe'),
target: 'Desert',
},
Cake_Red: {
text: t('foodCakeRed'),
textA: t('foodCakeRedA'),
textThe: t('foodCakeRedThe'),
target: 'Red',
},
Candy_Skeleton: {
text: t('foodCandySkeleton'),
textA: t('foodCandySkeletonA'),
textThe: t('foodCandySkeletonThe'),
target: 'Skeleton',
},
Candy_Base: {
text: t('foodCandyBase'),
textA: t('foodCandyBaseA'),
textThe: t('foodCandyBaseThe'),
target: 'Base',
},
Candy_CottonCandyBlue: {
text: t('foodCandyCottonCandyBlue'),
textA: t('foodCandyCottonCandyBlueA'),
textThe: t('foodCandyCottonCandyBlueThe'),
target: 'CottonCandyBlue',
},
Candy_CottonCandyPink: {
text: t('foodCandyCottonCandyPink'),
textA: t('foodCandyCottonCandyPinkA'),
textThe: t('foodCandyCottonCandyPinkThe'),
target: 'CottonCandyPink',
},
Candy_Shade: {
text: t('foodCandyShade'),
textA: t('foodCandyShadeA'),
textThe: t('foodCandyShadeThe'),
target: 'Shade',
},
Candy_White: {
text: t('foodCandyWhite'),
textA: t('foodCandyWhiteA'),
textThe: t('foodCandyWhiteThe'),
target: 'White',
},
Candy_Golden: {
text: t('foodCandyGolden'),
textA: t('foodCandyGoldenA'),
textThe: t('foodCandyGoldenThe'),
target: 'Golden',
},
Candy_Zombie: {
text: t('foodCandyZombie'),
textA: t('foodCandyZombieA'),
textThe: t('foodCandyZombieThe'),
target: 'Zombie',
},
Candy_Desert: {
text: t('foodCandyDesert'),
textA: t('foodCandyDesertA'),
textThe: t('foodCandyDesertThe'),
target: 'Desert',
},
Candy_Red: {
text: t('foodCandyRed'),
textA: t('foodCandyRedA'),
textThe: t('foodCandyRedThe'),
target: 'Red',
},
Pie_Skeleton: {
text: t('foodPieSkeleton'),
textA: t('foodPieSkeletonA'),
textThe: t('foodPieSkeletonThe'),
target: 'Skeleton',
},
Pie_Base: {
text: t('foodPieBase'),
textA: t('foodPieBaseA'),
textThe: t('foodPieBaseThe'),
target: 'Base',
},
Pie_CottonCandyBlue: {
text: t('foodPieCottonCandyBlue'),
textA: t('foodPieCottonCandyBlueA'),
textThe: t('foodPieCottonCandyBlueThe'),
target: 'CottonCandyBlue',
},
Pie_CottonCandyPink: {
text: t('foodPieCottonCandyPink'),
textA: t('foodPieCottonCandyPinkA'),
textThe: t('foodPieCottonCandyPinkThe'),
target: 'CottonCandyPink',
},
Pie_Shade: {
text: t('foodPieShade'),
textA: t('foodPieShadeA'),
textThe: t('foodPieShadeThe'),
target: 'Shade',
},
Pie_White: {
text: t('foodPieWhite'),
textA: t('foodPieWhiteA'),
textThe: t('foodPieWhiteThe'),
target: 'White',
},
Pie_Golden: {
text: t('foodPieGolden'),
textA: t('foodPieGoldenA'),
textThe: t('foodPieGoldenThe'),
target: 'Golden',
},
Pie_Zombie: {
text: t('foodPieZombie'),
textA: t('foodPieZombieA'),
textThe: t('foodPieZombieThe'),
target: 'Zombie',
},
Pie_Desert: {
text: t('foodPieDesert'),
textA: t('foodPieDesertA'),
textThe: t('foodPieDesertThe'),
target: 'Desert',
},
Pie_Red: {
text: t('foodPieRed'),
textA: t('foodPieRedA'),
textThe: t('foodPieRedThe'),
target: 'Red',
},
/* eslint-enable camelcase */
};
let FOOD_SEASON = 'Normal';
getRepeatingEvents(moment()).forEach(event => {
if (event.foodSeason) {
FOOD_SEASON = event.foodSeason;
}
Object.defineProperty(api, 'dropHatchingPotions', {
get () { return hatchingPotions.drops; },
enumerable: true,
});
each(api.food, (food, key) => {
let foodType = 'Normal';
if (key.startsWith('Cake_')) {
foodType = 'Cake';
} else if (key.startsWith('Candy_')) {
foodType = 'Candy';
} else if (key.startsWith('Pie_')) {
foodType = 'Pie';
}
defaults(food, {
value: 1,
key,
notes: t('foodNotes'),
canBuy: () => FOOD_SEASON === foodType,
canDrop: FOOD_SEASON === foodType,
Object.defineProperty(api, 'premiumHatchingPotions', {
get () { return hatchingPotions.premium; },
enumerable: true,
});
Object.defineProperty(api, 'wackyHatchingPotions', {
get () { return hatchingPotions.wacky; },
enumerable: true,
});
Object.defineProperty(api, 'hatchingPotions', {
get () { return hatchingPotions.all; },
enumerable: true,
});
Object.defineProperty(api, 'pets', {
get () { return stable.dropPets; },
enumerable: true,
});
Object.defineProperty(api, 'premiumPets', {
get () { return stable.premiumPets; },
enumerable: true,
});
Object.defineProperty(api, 'questPets', {
get () { return stable.questPets; },
enumerable: true,
});
Object.defineProperty(api, 'specialPets', {
get () { return stable.specialPets; },
enumerable: true,
});
Object.defineProperty(api, 'wackyPets', {
get () { return stable.wackyPets; },
enumerable: true,
});
Object.defineProperty(api, 'petInfo', {
get () { return stable.petInfo; },
enumerable: true,
});
Object.defineProperty(api, 'mounts', {
get () { return stable.dropMounts; },
enumerable: true,
});
Object.defineProperty(api, 'premiumMounts', {
get () { return stable.premiumMounts; },
enumerable: true,
});
Object.defineProperty(api, 'questMounts', {
get () { return stable.questMounts; },
enumerable: true,
});
Object.defineProperty(api, 'specialMounts', {
get () { return stable.specialMounts; },
enumerable: true,
});
Object.defineProperty(api, 'mountInfo', {
get () { return stable.mountInfo; },
enumerable: true,
});
function buildFood () {
const food = {
Meat: {
text: t('foodMeat'),
textA: t('foodMeatA'),
textThe: t('foodMeatThe'),
target: 'Base',
},
Milk: {
text: t('foodMilk'),
textA: t('foodMilkA'),
textThe: t('foodMilkThe'),
target: 'White',
},
Potatoe: {
text: t('foodPotatoe'),
textA: t('foodPotatoeA'),
textThe: t('foodPotatoeThe'),
target: 'Desert',
},
Strawberry: {
text: t('foodStrawberry'),
textA: t('foodStrawberryA'),
textThe: t('foodStrawberryThe'),
target: 'Red',
},
Chocolate: {
text: t('foodChocolate'),
textA: t('foodChocolateA'),
textThe: t('foodChocolateThe'),
target: 'Shade',
},
Fish: {
text: t('foodFish'),
textA: t('foodFishA'),
textThe: t('foodFishThe'),
target: 'Skeleton',
},
RottenMeat: {
text: t('foodRottenMeat'),
textA: t('foodRottenMeatA'),
textThe: t('foodRottenMeatThe'),
target: 'Zombie',
},
CottonCandyPink: {
text: t('foodCottonCandyPink'),
textA: t('foodCottonCandyPinkA'),
textThe: t('foodCottonCandyPinkThe'),
target: 'CottonCandyPink',
},
CottonCandyBlue: {
text: t('foodCottonCandyBlue'),
textA: t('foodCottonCandyBlueA'),
textThe: t('foodCottonCandyBlueThe'),
target: 'CottonCandyBlue',
},
Honey: {
text: t('foodHoney'),
textA: t('foodHoneyA'),
textThe: t('foodHoneyThe'),
target: 'Golden',
},
Saddle: {
sellWarningNote: t('foodSaddleSellWarningNote'),
text: t('foodSaddleText'),
value: 5,
notes: t('foodSaddleNotes'),
canBuy: () => true,
canDrop: false,
},
/* eslint-disable camelcase */
Cake_Skeleton: {
text: t('foodCakeSkeleton'),
textA: t('foodCakeSkeletonA'),
textThe: t('foodCakeSkeletonThe'),
target: 'Skeleton',
},
Cake_Base: {
text: t('foodCakeBase'),
textA: t('foodCakeBaseA'),
textThe: t('foodCakeBaseThe'),
target: 'Base',
},
Cake_CottonCandyBlue: {
text: t('foodCakeCottonCandyBlue'),
textA: t('foodCakeCottonCandyBlueA'),
textThe: t('foodCakeCottonCandyBlueThe'),
target: 'CottonCandyBlue',
},
Cake_CottonCandyPink: {
text: t('foodCakeCottonCandyPink'),
textA: t('foodCakeCottonCandyPinkA'),
textThe: t('foodCakeCottonCandyPinkThe'),
target: 'CottonCandyPink',
},
Cake_Shade: {
text: t('foodCakeShade'),
textA: t('foodCakeShadeA'),
textThe: t('foodCakeShadeThe'),
target: 'Shade',
},
Cake_White: {
text: t('foodCakeWhite'),
textA: t('foodCakeWhiteA'),
textThe: t('foodCakeWhiteThe'),
target: 'White',
},
Cake_Golden: {
text: t('foodCakeGolden'),
textA: t('foodCakeGoldenA'),
textThe: t('foodCakeGoldenThe'),
target: 'Golden',
},
Cake_Zombie: {
text: t('foodCakeZombie'),
textA: t('foodCakeZombieA'),
textThe: t('foodCakeZombieThe'),
target: 'Zombie',
},
Cake_Desert: {
text: t('foodCakeDesert'),
textA: t('foodCakeDesertA'),
textThe: t('foodCakeDesertThe'),
target: 'Desert',
},
Cake_Red: {
text: t('foodCakeRed'),
textA: t('foodCakeRedA'),
textThe: t('foodCakeRedThe'),
target: 'Red',
},
Candy_Skeleton: {
text: t('foodCandySkeleton'),
textA: t('foodCandySkeletonA'),
textThe: t('foodCandySkeletonThe'),
target: 'Skeleton',
},
Candy_Base: {
text: t('foodCandyBase'),
textA: t('foodCandyBaseA'),
textThe: t('foodCandyBaseThe'),
target: 'Base',
},
Candy_CottonCandyBlue: {
text: t('foodCandyCottonCandyBlue'),
textA: t('foodCandyCottonCandyBlueA'),
textThe: t('foodCandyCottonCandyBlueThe'),
target: 'CottonCandyBlue',
},
Candy_CottonCandyPink: {
text: t('foodCandyCottonCandyPink'),
textA: t('foodCandyCottonCandyPinkA'),
textThe: t('foodCandyCottonCandyPinkThe'),
target: 'CottonCandyPink',
},
Candy_Shade: {
text: t('foodCandyShade'),
textA: t('foodCandyShadeA'),
textThe: t('foodCandyShadeThe'),
target: 'Shade',
},
Candy_White: {
text: t('foodCandyWhite'),
textA: t('foodCandyWhiteA'),
textThe: t('foodCandyWhiteThe'),
target: 'White',
},
Candy_Golden: {
text: t('foodCandyGolden'),
textA: t('foodCandyGoldenA'),
textThe: t('foodCandyGoldenThe'),
target: 'Golden',
},
Candy_Zombie: {
text: t('foodCandyZombie'),
textA: t('foodCandyZombieA'),
textThe: t('foodCandyZombieThe'),
target: 'Zombie',
},
Candy_Desert: {
text: t('foodCandyDesert'),
textA: t('foodCandyDesertA'),
textThe: t('foodCandyDesertThe'),
target: 'Desert',
},
Candy_Red: {
text: t('foodCandyRed'),
textA: t('foodCandyRedA'),
textThe: t('foodCandyRedThe'),
target: 'Red',
},
Pie_Skeleton: {
text: t('foodPieSkeleton'),
textA: t('foodPieSkeletonA'),
textThe: t('foodPieSkeletonThe'),
target: 'Skeleton',
},
Pie_Base: {
text: t('foodPieBase'),
textA: t('foodPieBaseA'),
textThe: t('foodPieBaseThe'),
target: 'Base',
},
Pie_CottonCandyBlue: {
text: t('foodPieCottonCandyBlue'),
textA: t('foodPieCottonCandyBlueA'),
textThe: t('foodPieCottonCandyBlueThe'),
target: 'CottonCandyBlue',
},
Pie_CottonCandyPink: {
text: t('foodPieCottonCandyPink'),
textA: t('foodPieCottonCandyPinkA'),
textThe: t('foodPieCottonCandyPinkThe'),
target: 'CottonCandyPink',
},
Pie_Shade: {
text: t('foodPieShade'),
textA: t('foodPieShadeA'),
textThe: t('foodPieShadeThe'),
target: 'Shade',
},
Pie_White: {
text: t('foodPieWhite'),
textA: t('foodPieWhiteA'),
textThe: t('foodPieWhiteThe'),
target: 'White',
},
Pie_Golden: {
text: t('foodPieGolden'),
textA: t('foodPieGoldenA'),
textThe: t('foodPieGoldenThe'),
target: 'Golden',
},
Pie_Zombie: {
text: t('foodPieZombie'),
textA: t('foodPieZombieA'),
textThe: t('foodPieZombieThe'),
target: 'Zombie',
},
Pie_Desert: {
text: t('foodPieDesert'),
textA: t('foodPieDesertA'),
textThe: t('foodPieDesertThe'),
target: 'Desert',
},
Pie_Red: {
text: t('foodPieRed'),
textA: t('foodPieRedA'),
textThe: t('foodPieRedThe'),
target: 'Red',
},
/* eslint-enable camelcase */
};
let FOOD_SEASON = 'Normal';
getRepeatingEvents(moment()).forEach(event => {
if (event.foodSeason) {
FOOD_SEASON = event.foodSeason;
}
});
each(food, (foodItem, key) => {
let foodType = 'Normal';
if (key.startsWith('Cake_')) {
foodType = 'Cake';
} else if (key.startsWith('Candy_')) {
foodType = 'Candy';
} else if (key.startsWith('Pie_')) {
foodType = 'Pie';
}
defaults(foodItem, {
value: 1,
key,
notes: t('foodNotes'),
canBuy: () => FOOD_SEASON === foodType,
canDrop: FOOD_SEASON === foodType,
});
});
return food;
}
const memoizedBuildFood = memoize(buildFood);
Object.defineProperty(api, 'food', {
get () { return memoizedBuildFood(); },
});
api.appearances = appearances;

View File

@@ -0,0 +1,30 @@
import moment from 'moment';
import filter from 'lodash/filter';
import { pickBy } from 'lodash';
import nconf from 'nconf';
const SWITCHOVER_TIME = nconf.get('CONTENT_SWITCHOVER_TIME_OFFSET') || 0;
const releaseDateEndPart = `T${String(SWITCHOVER_TIME).padStart(2, '0')}:00-0000`;
export function buildReleaseDate (year, month, day = 1) {
return `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}${releaseDateEndPart}`;
}
function isReleased (item, fieldName, releaseDateMap, releaseByDefault) {
if (releaseDateMap[item[fieldName]]) {
const release = releaseDateMap[item[fieldName]];
if (release.day) {
return moment().isAfter(moment(buildReleaseDate(release.year, release.month, release.day)));
}
return moment().isAfter(releaseDateMap[item[fieldName]]);
}
return releaseByDefault;
}
export function filterReleased (items, fieldName, releaseDateMap, releaseByDefault = true) {
if (typeof items === 'object') {
return pickBy(items, item => isReleased(item, fieldName, releaseDateMap, releaseByDefault));
}
return filter(items, item => isReleased(item, fieldName, releaseDateMap, releaseByDefault));
}

View File

@@ -232,6 +232,38 @@ const QUEST_PETS = {
unlock: t('questButterflyUnlockText'),
},
},
chameleon: {
text: t('questChameleonText'),
notes: t('questChameleonNotes'),
completion: t('questChameleonCompletion'),
value: 4,
category: 'pet',
boss: {
name: t('questChameleonBoss'),
hp: 400,
str: 1.5,
},
drop: {
items: [
{
type: 'eggs',
key: 'Chameleon',
text: t('questChameleonDropChameleonEgg'),
}, {
type: 'eggs',
key: 'Chameleon',
text: t('questChameleonDropChameleonEgg'),
}, {
type: 'eggs',
key: 'Chameleon',
text: t('questChameleonDropChameleonEgg'),
},
],
gp: 35,
exp: 250,
unlock: t('questChameleonUnlockText'),
},
},
cheetah: {
text: t('questCheetahText'),
notes: t('questCheetahNotes'),

View File

@@ -20,6 +20,7 @@ const potentialFeaturedPetQuests = [
'giraffe',
'guineapig',
'chameleon',
'cheetah',
@@ -34,7 +35,6 @@ const potentialFeaturedPetQuests = [
'sabretooth',
];
// hatching potions and food names should be capitalized lest you break the market
const featuredItems = {
market () {
const featured = [{

View File

@@ -1,21 +1,12 @@
import each from 'lodash/each';
import moment from 'moment';
import { EVENTS } from './constants/events';
import {
drops as dropEggs,
quests as questEggs,
} from './eggs';
import {
drops as dropPotions,
premium as premiumPotions,
wacky as wackyPotions,
} from './hatching-potions';
import allEggs from './eggs';
import allPotions from './hatching-potions';
import t from './translation';
import memoize from '../fns/datedMemoize';
const petInfo = {};
const mountInfo = {};
function constructSet (type, eggs, potions) {
function constructSet (type, eggs, potions, petInfo, mountInfo, hasMounts = true) {
const pets = {};
const mounts = {};
@@ -37,52 +28,24 @@ function constructSet (type, eggs, potions) {
potion: potion.text,
egg: egg.text,
}));
mountInfo[key] = getAnimalData(t('mountName', {
potion: potion.text,
mount: egg.mountText,
}));
pets[key] = true;
mounts[key] = true;
});
});
return [pets, mounts];
}
function constructPetOnlySet (type, eggs, potions) {
const pets = {};
each(eggs, egg => {
each(potions, potion => {
const key = `${egg.key}-${potion.key}`;
function getAnimalData (text) {
return {
key,
type,
potion: potion.key,
egg: egg.key,
text,
};
if (hasMounts) {
mountInfo[key] = getAnimalData(t('mountName', {
potion: potion.text,
mount: egg.mountText,
}));
mounts[key] = true;
}
petInfo[key] = getAnimalData(t('petName', {
potion: potion.text,
egg: egg.text,
}));
pets[key] = true;
});
});
if (hasMounts) {
return [pets, mounts];
}
return pets;
}
const [dropPets, dropMounts] = constructSet('drop', dropEggs, dropPotions);
const [premiumPets, premiumMounts] = constructSet('premium', dropEggs, premiumPotions);
const [questPets, questMounts] = constructSet('quest', questEggs, dropPotions);
const wackyPets = constructPetOnlySet('wacky', dropEggs, wackyPotions);
const canFindSpecial = {
pets: {
// Veteran Pet Ladder - awarded on major updates
@@ -208,44 +171,88 @@ const specialMounts = {
'JackOLantern-RoyalPurple': 'royalPurpleJackolantern',
};
each(specialPets, (translationString, key) => {
petInfo[key] = {
key,
type: 'special',
text: t(translationString),
canFind: canFindSpecial.pets[key],
};
});
function buildInfo () {
const petInfo = {};
const mountInfo = {};
Object.assign(petInfo['Gryphatrice-Jubilant'], {
canBuy () {
return moment().isBetween(EVENTS.birthday10.start, EVENTS.birthday10.end);
const [dropPets, dropMounts] = constructSet('drop', allEggs.drops, allPotions.drops, petInfo, mountInfo);
const [premiumPets, premiumMounts] = constructSet('premium', allEggs.drops, allPotions.premium, petInfo, mountInfo);
const [questPets, questMounts] = constructSet('quest', allEggs.quests, allPotions.drops, petInfo, mountInfo);
const wackyPets = constructSet('wacky', allEggs.drops, allPotions.wacky, petInfo, mountInfo, false);
each(specialPets, (translationString, key) => {
petInfo[key] = {
key,
type: 'special',
text: t(translationString),
canFind: canFindSpecial.pets[key],
};
});
Object.assign(petInfo['Gryphatrice-Jubilant'], {
canBuy () {
return moment().isBetween(EVENTS.birthday10.start, EVENTS.birthday10.end);
},
currency: 'gems',
event: 'birthday10',
value: 60,
purchaseType: 'pets',
});
each(specialMounts, (translationString, key) => {
mountInfo[key] = {
key,
type: 'special',
text: t(translationString),
canFind: canFindSpecial.mounts[key],
};
});
return {
dropPets,
premiumPets,
questPets,
wackyPets,
dropMounts,
questMounts,
premiumMounts,
specialPets,
specialMounts,
petInfo,
mountInfo,
};
}
const memoizedBuildInfo = memoize(buildInfo);
export default {
get dropPets () {
return memoizedBuildInfo().dropPets;
},
get premiumPets () {
return memoizedBuildInfo().premiumPets;
},
get questPets () {
return memoizedBuildInfo().questPets;
},
get wackyPets () {
return memoizedBuildInfo().wackyPets;
},
get dropMounts () {
return memoizedBuildInfo().dropMounts;
},
get questMounts () {
return memoizedBuildInfo().questMounts;
},
get premiumMounts () {
return memoizedBuildInfo().premiumMounts;
},
get petInfo () {
return memoizedBuildInfo().petInfo;
},
get mountInfo () {
return memoizedBuildInfo().mountInfo;
},
currency: 'gems',
event: 'birthday10',
value: 60,
purchaseType: 'pets',
});
each(specialMounts, (translationString, key) => {
mountInfo[key] = {
key,
type: 'special',
text: t(translationString),
canFind: canFindSpecial.mounts[key],
};
});
export {
dropPets,
premiumPets,
questPets,
wackyPets,
dropMounts,
questMounts,
premiumMounts,
specialPets,
specialMounts,
petInfo,
mountInfo,
};

View File

@@ -33,6 +33,10 @@ const memoize = fn => {
identifier = config.identifier;
}
}
if (identifier.length === 0) {
identifier = args.filter(arg => typeof arg === 'string').join('-');
}
}
if (!checkedDate) {
checkedDate = new Date();

View File

@@ -1,10 +1,10 @@
import { drops as eggs } from '../content/eggs';
import { drops as hatchingPotions } from '../content/hatching-potions';
import allEggs from '../content/eggs';
import allPotions from '../content/hatching-potions';
import randomVal from '../libs/randomVal';
export default function firstDrops (user) {
const eggDrop = randomVal(eggs);
const potionDrop = randomVal(hatchingPotions);
const eggDrop = randomVal(allEggs.drops);
const potionDrop = randomVal(allPotions.drops);
user.items.eggs = {
...user.items.eggs,