Compare commits

...

115 Commits

Author SHA1 Message Date
Phillip Thelen 8a317c269e Fix news related permission issues 2024-08-01 15:24:19 +02:00
Sabe Jones 618cdafd10 fix(lint): clean up migration for ongoing use 2024-07-30 15:42:54 -05:00
Sabe Jones e7b37d0378 chore(migration): set up for Naming Day 2024 2024-07-30 15:13:33 -05:00
Phillip Thelen 765e08f999 fix displaying if a pet is hatchable (#15281) 2024-07-30 12:16:43 -05:00
dependabot[bot] 598bc29647 Bump fast-xml-parser from 4.3.4 to 4.4.1 (#15280)
Bumps [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) from 4.3.4 to 4.4.1.
- [Release notes](https://github.com/NaturalIntelligence/fast-xml-parser/releases)
- [Changelog](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/NaturalIntelligence/fast-xml-parser/compare/v4.3.4...v4.4.1)

---
updated-dependencies:
- dependency-name: fast-xml-parser
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Sabe Jones <sabe@habitica.com>
2024-07-29 17:24:11 -05:00
Sabe Jones 39ccddfb1c fix(customization): restore broken popovers 2024-07-29 16:17:33 -05:00
Sabe Jones 108214a217 fix(lint): remove console statement 2024-07-29 14:15:47 -05:00
Sabe Jones 271f40e355 Squashed commit of the following:
commit 8ed95731cb
Author: Phillip Thelen <phillip@habitica.com>
Date:   Tue Jul 23 17:59:56 2024 +0200

    fix hatched dialog

commit 53242ad96c
Author: Phillip Thelen <phillip@habitica.com>
Date:   Tue Jul 23 17:38:13 2024 +0200

    fix popover not showing

commit ce4bfd25bd
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jul 3 17:28:30 2024 +0200

    move item popover to own component

commit 2e6a300c46
Author: Phillip Thelen <phillip@habitica.com>
Date:   Mon Jul 1 18:48:24 2024 +0200

    make scaled sprites look nice

commit a3cbadb8c2
Author: Phillip Thelen <phillip@habitica.com>
Date:   Mon Jul 1 18:48:17 2024 +0200

    fix hatching dialog

commit 0e5126df5e
Author: Phillip Thelen <phillip@habitica.com>
Date:   Mon Jul 1 18:48:12 2024 +0200

    fix popover alignment

commit 7362af9236
Author: Phillip Thelen <phillip@habitica.com>
Date:   Fri Jun 28 17:07:03 2024 +0200

    fix item display

commit cf353efdb7
Author: Phillip Thelen <phillip@habitica.com>
Date:   Fri Jun 28 16:59:13 2024 +0200

    fix pet display

commit caf0cba9f2
Author: Phillip Thelen <phillip@habitica.com>
Date:   Fri Jun 28 15:24:39 2024 +0200

    fix background icon display

commit 3b06febc01
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 26 12:30:04 2024 +0200

    fix sprites for notifications

commit 160b2debdc
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 26 10:35:13 2024 +0200

    fix gear display in profile

commit b200a2f17d
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 26 10:28:11 2024 +0200

    fix sprites for keys to the kennel

commit 3614e7a8fb
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 26 10:28:00 2024 +0200

    fix sprites on avatar customization

commit 35f993d055
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 26 09:18:41 2024 +0200

    fix hover icons

commit 28fc80115e
Author: Phillip Thelen <phillip@habitica.com>
Date:   Tue Jun 11 16:50:37 2024 +0200

    remove console

commit b041c67679
Author: Phillip Thelen <phillip@habitica.com>
Date:   Tue Jun 11 15:18:44 2024 +0200

    more lint fixes

commit f4261d0440
Author: Phillip Thelen <phillip@habitica.com>
Date:   Tue Jun 11 15:18:16 2024 +0200

    fix lint

commit 878ee8f77b
Author: Phillip Thelen <phillip@habitica.com>
Date:   Tue Jun 11 13:23:08 2024 +0200

    support gifs

commit aac24715aa
Author: Phillip Thelen <phillip@habitica.com>
Date:   Tue Jun 11 13:15:52 2024 +0200

    move avatar customization to sprites

commit f4d3663130
Author: Phillip Thelen <phillip@habitica.com>
Date:   Fri Jun 7 17:25:19 2024 +0200

    Move more sprites out of css

commit 6e6b4c981a
Author: Phillip Thelen <phillip@habitica.com>
Date:   Fri Jun 7 16:59:30 2024 +0200

    add new sprite to item and shopItem component

commit 8712413f5d
Author: Phillip Thelen <phillip@habitica.com>
Date:   Fri Jun 7 16:37:24 2024 +0200

    use new sprites for pets list

commit 1172893826
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 5 09:43:51 2024 +0200

    Begin building new system for loading sprites
2024-07-29 14:10:27 -05:00
Phillip Thelen e801547580 Seasonal gear fix (#15255)
* cleanup unneeded season definitions

* assign first winter seasonal gear right season

* add missing winter definition

* Fix enddate for winter galas

* fix lint

* fix halloween sprites

* set season

* fix loading habitoween sprites

* add missing customization shop sprites

* Fix test

* update customization shop sprites
2024-07-29 10:30:23 -05:00
Phillip Thelen fc11941186 Steampunk gear should not have an end date (#15256) 2024-07-29 10:29:42 -05:00
Sabe Jones 882fad3113 5.27.0 2024-07-29 10:04:59 -05:00
Weblate 6168492711 Translated using Weblate (French)
Currently translated at 99.7% (386 of 387 strings)

Translated using Weblate (French)

Currently translated at 100.0% (878 of 878 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (235 of 235 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (3153 of 3153 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (794 of 794 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (387 of 387 strings)

Translated using Weblate (Spanish)

Currently translated at 99.7% (876 of 878 strings)

Translated using Weblate (Slovak)

Currently translated at 100.0% (182 of 182 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (140 of 140 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 96.9% (129 of 133 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (22 of 22 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 97.5% (3067 of 3143 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (240 of 240 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 78.1% (147 of 188 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 96.2% (764 of 794 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (875 of 875 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (167 of 167 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (140 of 140 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (234 of 234 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 94.7% (108 of 114 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 98.8% (261 of 264 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (427 of 427 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 97.2% (3055 of 3143 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 76.5% (144 of 188 strings)

Translated using Weblate (Indonesian)

Currently translated at 39.3% (74 of 188 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 96.2% (764 of 794 strings)

Translated using Weblate (Spanish)

Currently translated at 99.3% (789 of 794 strings)

Translated using Weblate (Indonesian)

Currently translated at 79.1% (72 of 91 strings)

Translated using Weblate (Slovak)

Currently translated at 100.0% (384 of 384 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (377 of 377 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (110 of 110 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (167 of 167 strings)

Translated using Weblate (Portuguese)

Currently translated at 97.6% (163 of 167 strings)

Translated using Weblate (Japanese)

Currently translated at 96.8% (760 of 785 strings)

Co-authored-by: Alex Kalergi <nitrogenphospat@proton.me>
Co-authored-by: Céu <marcel.ufscar@gmail.com>
Co-authored-by: Filip Betko <filipbetko@gmail.com>
Co-authored-by: Jaime Martí <jaumemarti77@icloud.com>
Co-authored-by: Muhammad Hanafi <Cytricgame@gmail.com>
Co-authored-by: Sophie LE MASLE <sophiesuff@gmail.com>
Co-authored-by: TOMA Mitsuru <toma0001@gmail.com>
Co-authored-by: Tetiana <merekka13@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/pt/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/es/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/id/
Translate-URL: https://translate.habitica.com/projects/habitica/content/es/
Translate-URL: https://translate.habitica.com/projects/habitica/content/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/content/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/content/sk/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/id/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/front/sk/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/es/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/loginincentives/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/pets/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/es/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/es/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/uk/
Translation: Habitica/Achievements
Translation: Habitica/Backgrounds
Translation: Habitica/Challenge
Translation: Habitica/Communityguidelines
Translation: Habitica/Content
Translation: Habitica/Faq
Translation: Habitica/Front
Translation: Habitica/Gear
Translation: Habitica/Generic
Translation: Habitica/Groups
Translation: Habitica/Limited
Translation: Habitica/Loginincentives
Translation: Habitica/Npc
Translation: Habitica/Pets
Translation: Habitica/Questscontent
Translation: Habitica/Subscriber
Translation: Habitica/Tasks
2024-07-29 17:03:35 +02:00
Natalie 2aade9aaa6 August 2024 Content Prebuild (#15277)
* add sprites

* 2024-08 content build

* fixing stuff

* update boss rage effects

* update quest rage text and releaseDates.js

* update shop-featuredItems.js

* fricken fracken beach umbrella

* more beach umbrella

* remove egregious typo
2024-07-25 12:55:38 -05:00
Sabe Jones 4789946c4e 5.26.3 2024-07-25 08:53:26 -05:00
Sabe Jones a69d8877c9 Merge branch 'develop' into release 2024-07-25 08:51:26 -05:00
Weblate 7cc0c3bc57 Translated using Weblate (German)
Currently translated at 91.8% (2888 of 3143 strings)

Translated using Weblate (Slovak)

Currently translated at 97.2% (177 of 182 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (785 of 785 strings)

Translated using Weblate (Slovak)

Currently translated at 100.0% (56 of 56 strings)

Translated using Weblate (Slovak)

Currently translated at 92.3% (12 of 13 strings)

Translated using Weblate (German)

Currently translated at 91.7% (2883 of 3143 strings)

Translated using Weblate (Slovak)

Currently translated at 96.7% (176 of 182 strings)

Translated using Weblate (Indonesian)

Currently translated at 33.5% (63 of 188 strings)

Translated using Weblate (English (United Kingdom))

Currently translated at 2.6% (5 of 188 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 97.4% (765 of 785 strings)

Translated using Weblate (Slovak)

Currently translated at 100.0% (384 of 384 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (377 of 377 strings)

Translated using Weblate (Slovak)

Currently translated at 100.0% (193 of 193 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (193 of 193 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (167 of 167 strings)

Translated using Weblate (Indonesian)

Currently translated at 32.9% (62 of 188 strings)

Translated using Weblate (Indonesian)

Currently translated at 29.2% (55 of 188 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (140 of 140 strings)

Translated using Weblate (Slovak)

Currently translated at 100.0% (140 of 140 strings)

Translated using Weblate (German)

Currently translated at 91.6% (2881 of 3143 strings)

Translated using Weblate (Slovak)

Currently translated at 93.9% (171 of 182 strings)

Translated using Weblate (French)

Currently translated at 100.0% (785 of 785 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (110 of 110 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (140 of 140 strings)

Translated using Weblate (Turkish)

Currently translated at 80.4% (107 of 133 strings)

Translated using Weblate (Turkish)

Currently translated at 7.9% (15 of 188 strings)

Translated using Weblate (Russian)

Currently translated at 95.6% (751 of 785 strings)

Translated using Weblate (French)

Currently translated at 98.3% (772 of 785 strings)

Translated using Weblate (German)

Currently translated at 91.6% (2879 of 3143 strings)

Translated using Weblate (French)

Currently translated at 98.0% (770 of 785 strings)

Co-authored-by: Adithya Mahadev. B <adithyamahadev2521@gmail.com>
Co-authored-by: Céu <marcel.ufscar@gmail.com>
Co-authored-by: Ece Ekinci <plutonium3613@gmail.com>
Co-authored-by: Filip Betko <filipbetko@gmail.com>
Co-authored-by: Hanafi <naflizo@gmail.com>
Co-authored-by: Jaime Martí <jaumemarti77@icloud.com>
Co-authored-by: Natalie Luhrs <eilatan@gmail.com>
Co-authored-by: Sophie LE MASLE <sophiesuff@gmail.com>
Co-authored-by: Tetiana <merekka13@gmail.com>
Co-authored-by: Toro Mor <thomas.bizer@gmx.de>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/character/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/character/sk/
Translate-URL: https://translate.habitica.com/projects/habitica/content/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/content/sk/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/en_GB/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/id/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/tr/
Translate-URL: https://translate.habitica.com/projects/habitica/front/sk/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/de/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/tr/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/es/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/rebirth/sk/
Translate-URL: https://translate.habitica.com/projects/habitica/spells/sk/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/sk/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/uk/
Translation: Habitica/Achievements
Translation: Habitica/Challenge
Translation: Habitica/Character
Translation: Habitica/Content
Translation: Habitica/Faq
Translation: Habitica/Front
Translation: Habitica/Gear
Translation: Habitica/Npc
Translation: Habitica/Questscontent
Translation: Habitica/Rebirth
Translation: Habitica/Spells
Translation: Habitica/Tasks
2024-07-25 15:49:36 +02:00
Sabe Jones fb78495a1b feat(avatar): popovers for customization 2024-07-24 16:38:58 -05:00
Phillip Thelen 22def5111f fix purchasing wacky potions (#15276) 2024-07-24 10:35:26 -05:00
Phillip Thelen 6e91d51def Fix some scheduling issues (#15274)
* fix logic for time travelers schedule

* fix potion availability

* fix tests
2024-07-23 11:33:59 -05:00
Sabe Jones f3b8a4e931 5.26.2 2024-07-21 13:05:07 -05:00
Weblate 69afa52beb Merge branch 'origin/develop' into Weblate. 2024-07-21 20:04:10 +02:00
Weblate f09a39d27c Translated using Weblate (Chinese (Simplified))
Currently translated at 99.6% (872 of 875 strings)

Translated using Weblate (German)

Currently translated at 91.5% (2877 of 3143 strings)

Translated using Weblate (Slovak)

Currently translated at 100.0% (110 of 110 strings)

Translated using Weblate (Spanish)

Currently translated at 98.2% (771 of 785 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 96.9% (3046 of 3143 strings)

Translated using Weblate (Portuguese)

Currently translated at 57.0% (1793 of 3143 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 97.4% (765 of 785 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (13 of 13 strings)

Translated using Weblate (Italian)

Currently translated at 87.5% (7 of 8 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (22 of 22 strings)

Translated using Weblate (Italian)

Currently translated at 86.1% (368 of 427 strings)

Translated using Weblate (Italian)

Currently translated at 11.1% (21 of 188 strings)

Translated using Weblate (Italian)

Currently translated at 94.2% (740 of 785 strings)

Translated using Weblate (Italian)

Currently translated at 54.9% (50 of 91 strings)

Translated using Weblate (Italian)

Currently translated at 95.7% (45 of 47 strings)

Translated using Weblate (Italian)

Currently translated at 97.4% (188 of 193 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (167 of 167 strings)

Translated using Weblate (Italian)

Currently translated at 74.9% (194 of 259 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (94 of 94 strings)

Translated using Weblate (German)

Currently translated at 91.4% (2875 of 3143 strings)

Translated using Weblate (Italian)

Currently translated at 94.6% (828 of 875 strings)

Translated using Weblate (Italian)

Currently translated at 94.0% (823 of 875 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (427 of 427 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 76.5% (144 of 188 strings)

Translated using Weblate (German)

Currently translated at 91.4% (2873 of 3143 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (94 of 94 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (94 of 94 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (113 of 113 strings)

Translated using Weblate (Czech)

Currently translated at 85.7% (114 of 133 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (427 of 427 strings)

Translated using Weblate (German)

Currently translated at 91.3% (2871 of 3143 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (133 of 133 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (240 of 240 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (22 of 22 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (113 of 113 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (133 of 133 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (1 of 1 strings)

Translated using Weblate (Slovak)

Currently translated at 100.0% (22 of 22 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 95.4% (21 of 22 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (22 of 22 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (427 of 427 strings)

Translated using Weblate (German)

Currently translated at 91.2% (2869 of 3143 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (240 of 240 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (240 of 240 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (188 of 188 strings)

Translated using Weblate (Slovak)

Currently translated at 100.0% (193 of 193 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (193 of 193 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (110 of 110 strings)

Translated using Weblate (Slovak)

Currently translated at 100.0% (110 of 110 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (167 of 167 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (167 of 167 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (113 of 113 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (133 of 133 strings)

Translated using Weblate (French)

Currently translated at 100.0% (133 of 133 strings)

Translated using Weblate (German)

Currently translated at 98.4% (131 of 133 strings)

Translated using Weblate (French)

Currently translated at 100.0% (264 of 264 strings)

Translated using Weblate (French)

Currently translated at 100.0% (22 of 22 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (427 of 427 strings)

Translated using Weblate (French)

Currently translated at 100.0% (3143 of 3143 strings)

Translated using Weblate (Ukrainian)

Currently translated at 99.5% (239 of 240 strings)

Translated using Weblate (French)

Currently translated at 100.0% (240 of 240 strings)

Translated using Weblate (German)

Currently translated at 98.7% (237 of 240 strings)

Translated using Weblate (Slovak)

Currently translated at 100.0% (384 of 384 strings)

Translated using Weblate (Slovak)

Currently translated at 97.9% (189 of 193 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (110 of 110 strings)

Translated using Weblate (Hebrew)

Currently translated at 92.8% (155 of 167 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (259 of 259 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (182 of 182 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (182 of 182 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.4% (781 of 785 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (259 of 259 strings)

Translated using Weblate (Slovak)

Currently translated at 100.0% (140 of 140 strings)

Translated using Weblate (Portuguese)

Currently translated at 65.3% (153 of 234 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 98.8% (261 of 264 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 96.9% (3046 of 3143 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 76.5% (144 of 188 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 76.5% (144 of 188 strings)

Translated using Weblate (Indonesian)

Currently translated at 28.1% (53 of 188 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.4% (781 of 785 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (377 of 377 strings)

Translated using Weblate (Portuguese)

Currently translated at 98.1% (377 of 384 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (193 of 193 strings)

Translated using Weblate (Portuguese)

Currently translated at 97.6% (163 of 167 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.6% (258 of 259 strings)

Translated using Weblate (Slovak)

Currently translated at 100.0% (140 of 140 strings)

Translated using Weblate (German)

Currently translated at 91.2% (2867 of 3143 strings)

Translated using Weblate (Ukrainian)

Currently translated at 98.4% (773 of 785 strings)

Translated using Weblate (French)

Currently translated at 100.0% (234 of 234 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (94 of 94 strings)

Translated using Weblate (French)

Currently translated at 100.0% (114 of 114 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (60 of 60 strings)

Translated using Weblate (Ukrainian)

Currently translated at 61.7% (1940 of 3143 strings)

Translated using Weblate (Portuguese)

Currently translated at 57.0% (1793 of 3143 strings)

Translated using Weblate (German)

Currently translated at 91.1% (2865 of 3143 strings)

Translated using Weblate (Japanese)

Currently translated at 99.4% (3085 of 3102 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (234 of 234 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (114 of 114 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (264 of 264 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (384 of 384 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (113 of 113 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (114 of 114 strings)

Translated using Weblate (Ukrainian)

Currently translated at 61.7% (1940 of 3143 strings)

Translated using Weblate (German)

Currently translated at 91.0% (2863 of 3143 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (234 of 234 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (113 of 113 strings)

Translated using Weblate (Slovak)

Currently translated at 74.9% (588 of 785 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (113 of 113 strings)

Translated using Weblate (German)

Currently translated at 95.6% (109 of 114 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (427 of 427 strings)

Translated using Weblate (German)

Currently translated at 91.0% (2861 of 3143 strings)

Translated using Weblate (German)

Currently translated at 98.7% (231 of 234 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (113 of 113 strings)

Translated using Weblate (German)

Currently translated at 99.2% (262 of 264 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (91 of 91 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (234 of 234 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (264 of 264 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (3143 of 3143 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (384 of 384 strings)

Translated using Weblate (Slovak)

Currently translated at 100.0% (140 of 140 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (233 of 233 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (286 of 286 strings)

Translated using Weblate (German)

Currently translated at 90.9% (2857 of 3143 strings)

Translated using Weblate (Ukrainian)

Currently translated at 99.4% (382 of 384 strings)

Translated using Weblate (Ukrainian)

Currently translated at 99.4% (382 of 384 strings)

Translated using Weblate (Slovak)

Currently translated at 97.6% (375 of 384 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (875 of 875 strings)

Translated using Weblate (German)

Currently translated at 99.7% (383 of 384 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 96.8% (3043 of 3143 strings)

Translated using Weblate (German)

Currently translated at 90.8% (2855 of 3143 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 96.7% (3041 of 3143 strings)

Translated using Weblate (French)

Currently translated at 99.6% (3132 of 3143 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (377 of 377 strings)

Translated using Weblate (French)

Currently translated at 100.0% (384 of 384 strings)

Translated using Weblate (Indonesian)

Currently translated at 91.3% (799 of 875 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (167 of 167 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (188 of 188 strings)

Translated using Weblate (German)

Currently translated at 98.9% (380 of 384 strings)

Translated using Weblate (Indonesian)

Currently translated at 95.3% (184 of 193 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (167 of 167 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (167 of 167 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (193 of 193 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.7% (377 of 378 strings)

Translated using Weblate (Portuguese)

Currently translated at 100.0% (47 of 47 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (188 of 188 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (193 of 193 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (875 of 875 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (167 of 167 strings)

Translated using Weblate (Indonesian)

Currently translated at 94.0% (157 of 167 strings)

Translated using Weblate (Japanese)

Currently translated at 99.4% (192 of 193 strings)

Translated using Weblate (French)

Currently translated at 99.0% (3114 of 3143 strings)

Translated using Weblate (German)

Currently translated at 90.7% (2853 of 3143 strings)

Translated using Weblate (French)

Currently translated at 100.0% (785 of 785 strings)

Translated using Weblate (Indonesian)

Currently translated at 94.0% (157 of 167 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (188 of 188 strings)

Translated using Weblate (German)

Currently translated at 98.5% (421 of 427 strings)

Translated using Weblate (French)

Currently translated at 98.7% (3105 of 3143 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (188 of 188 strings)

Translated using Weblate (French)

Currently translated at 100.0% (193 of 193 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (193 of 193 strings)

Translated using Weblate (German)

Currently translated at 98.4% (190 of 193 strings)

Translated using Weblate (French)

Currently translated at 100.0% (875 of 875 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (140 of 140 strings)

Translated using Weblate (Turkish)

Currently translated at 5.8% (11 of 188 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (785 of 785 strings)

Translated using Weblate (German)

Currently translated at 98.4% (773 of 785 strings)

Translated using Weblate (German)

Currently translated at 65.9% (60 of 91 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (189 of 189 strings)

Translated using Weblate (Spanish)

Currently translated at 99.7% (873 of 875 strings)

Translated using Weblate (German)

Currently translated at 100.0% (875 of 875 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (773 of 773 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (868 of 868 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (3143 of 3143 strings)

Co-authored-by: Alex G <powerali18@gmail.com>
Co-authored-by: Antonio Spinelli <tonicospinelli@users.noreply.translate.habitica.com>
Co-authored-by: Céu <marcel.ufscar@gmail.com>
Co-authored-by: Elisa Bailo <bailoelisa5@gmail.com>
Co-authored-by: Eva <kornmann.eva@gmx.de>
Co-authored-by: Filip Betko <filipbetko@gmail.com>
Co-authored-by: Isabela de Carvalho <isabela.c.escritora@gmail.com>
Co-authored-by: Jaime Martí <jaumemarti77@icloud.com>
Co-authored-by: Justcallme rye <Blizzardscf32@gmail.com>
Co-authored-by: Miguel Rocha de Macedo Amaral <miguelrmamaral@gmail.com>
Co-authored-by: Natalie Luhrs <eilatan@gmail.com>
Co-authored-by: Paolo Bizzarri <pibizza@gmail.com>
Co-authored-by: Sophie LE MASLE <sophiesuff@gmail.com>
Co-authored-by: TOMA Mitsuru <toma0001@gmail.com>
Co-authored-by: Tetiana <merekka13@gmail.com>
Co-authored-by: Toro Mor <thomas.bizer@gmx.de>
Co-authored-by: Vinicius Rodrigues <suburbanizar@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: Yan <ariamao0802@gmail.com>
Co-authored-by: billypat <kreideraine@gmail.com>
Co-authored-by: diamondmonster09 <diamondmonster09@gmail.com>
Co-authored-by: tamara <tab.bravani@gmail.com>
Co-authored-by: 过客是个铁憨憨 <1811304592@qq.com>
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/he/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/id/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/it/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/pt/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/de/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/es/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/id/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/it/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/sk/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/character/de/
Translate-URL: https://translate.habitica.com/projects/habitica/character/es/
Translate-URL: https://translate.habitica.com/projects/habitica/character/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/character/id/
Translate-URL: https://translate.habitica.com/projects/habitica/character/it/
Translate-URL: https://translate.habitica.com/projects/habitica/character/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/character/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/character/sk/
Translate-URL: https://translate.habitica.com/projects/habitica/character/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/de/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/it/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/content/de/
Translate-URL: https://translate.habitica.com/projects/habitica/content/es/
Translate-URL: https://translate.habitica.com/projects/habitica/content/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/content/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/content/pt/
Translate-URL: https://translate.habitica.com/projects/habitica/content/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/content/sk/
Translate-URL: https://translate.habitica.com/projects/habitica/content/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/contrib/it/
Translate-URL: https://translate.habitica.com/projects/habitica/contrib/pt/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/id/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/it/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/tr/
Translate-URL: https://translate.habitica.com/projects/habitica/front/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/de/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/es/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/de/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/es/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/de/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/it/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/de/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/es/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/id/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/loginincentives/es/
Translate-URL: https://translate.habitica.com/projects/habitica/loginincentives/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/loginincentives/it/
Translate-URL: https://translate.habitica.com/projects/habitica/loginincentives/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/loginincentives/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/loginincentives/sk/
Translate-URL: https://translate.habitica.com/projects/habitica/merch/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/messages/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/cs/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/de/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/es/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/overview/it/
Translate-URL: https://translate.habitica.com/projects/habitica/pets/de/
Translate-URL: https://translate.habitica.com/projects/habitica/pets/es/
Translate-URL: https://translate.habitica.com/projects/habitica/pets/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/pets/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/pets/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/quests/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/de/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/es/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/it/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/sk/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/rebirth/it/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/it/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/de/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/es/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/pt/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/sk/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/tr/
Translation: Habitica/Achievements
Translation: Habitica/Backgrounds
Translation: Habitica/Challenge
Translation: Habitica/Character
Translation: Habitica/Communityguidelines
Translation: Habitica/Content
Translation: Habitica/Contrib
Translation: Habitica/Faq
Translation: Habitica/Front
Translation: Habitica/Gear
Translation: Habitica/Generic
Translation: Habitica/Groups
Translation: Habitica/Limited
Translation: Habitica/Loginincentives
Translation: Habitica/Merch
Translation: Habitica/Messages
Translation: Habitica/Npc
Translation: Habitica/Overview
Translation: Habitica/Pets
Translation: Habitica/Quests
Translation: Habitica/Questscontent
Translation: Habitica/Rebirth
Translation: Habitica/Settings
Translation: Habitica/Subscriber
Translation: Habitica/Tasks
2024-07-21 20:03:59 +02:00
Phillip Thelen 2e71963fbf Update schedule.js (#15273)
Add SandSculpture for July
2024-07-21 12:58:28 -05:00
Sabe Jones f740a92fb7 Update README.md
fix awkward line breaks
2024-07-19 17:37:31 -05:00
Sabe Jones 21e7ddea16 Update README.md 2024-07-19 17:36:26 -05:00
Sabe Jones 923d90cf22 Merge branch 'sabrecat/postfixes' into develop 2024-07-17 17:43:05 -05:00
Sabe Jones b386a1917d Merge branch 'sabrecat/more-api-sunset' into develop 2024-07-17 17:42:28 -05:00
Sabe Jones 4a5427b2b2 Merge branch 'develop' into release 2024-07-03 14:23:53 -05:00
Sabe Jones 04554c5309 5.26.1 2024-07-03 14:23:37 -05:00
Phillip Thelen 5ef88b5c56 Update releaseDates.js 2024-07-03 18:52:23 +02:00
Sabe Jones 1f2397b81a fix(quests): adjust margins 2024-07-02 17:13:40 -05:00
Weblate 892c4934d5 Translated using Weblate (Japanese)
Currently translated at 99.2% (3080 of 3103 strings)

Co-authored-by: Natalie Luhrs <eilatan@gmail.com>
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ja/
Translation: Habitica/Gear
2024-07-01 22:51:54 +02:00
Sabe Jones 60d5aaaaa6 fix(memoize): enumerate food 2024-07-01 09:02:12 -05:00
Sabe Jones f506b840ed fix(lint): add missing whitespace for curlies 2024-06-28 23:34:32 -05:00
Sabe Jones f357750d88 test(chat): coverage for new sunsets 2024-06-28 23:29:58 -05:00
Sabe Jones a2dbe68338 Merge branch 'release' into sabrecat/more-api-sunset 2024-06-28 22:20:07 -05:00
Sabe Jones 491d2cfab1 fix(modals): various tweks 2024-06-28 22:03:45 -05:00
Sabe Jones fa91abb739 Merge branch 'develop' into sabrecat/postfixes 2024-06-28 21:28:39 -05:00
Sabe Jones 6b46d04537 Merge branch 'develop' into release 2024-06-28 11:27:58 -05:00
Sabe Jones b90457c04f fix(test): correct hatching potion test 2024-06-28 11:20:21 -05:00
Sabe Jones 379d98a91e fix(test): correct schedule test 2024-06-28 11:09:09 -05:00
Sabe Jones 07352480cd Merge remote-tracking branch 'origin/phillip/memoize-me' into develop 2024-06-28 10:26:38 -05:00
Phillip Thelen a6ff8e095a fix naming 2024-06-28 10:21:03 -05:00
Phillip Thelen 1fb44bbe73 fix naming 2024-06-28 10:20:11 -05:00
Phillip Thelen 5323849f90 fix naming 2024-06-28 17:16:45 +02:00
Sabe Jones 034327f647 5.26.0 2024-06-28 09:55:53 -05:00
Sabe Jones de9aac0988 Squashed commit of the following:
commit 8309686922
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Tue Jun 25 15:41:41 2024 -0400

    melior updates - loading screen & menu bar

commit 53608dd688
Author: Phillip Thelen <phillip@habitica.com>
Date:   Mon Jun 24 22:12:09 2024 +0200

    fix food

commit eecae86454
Merge: 95c562fdbc 960e262f19
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Mon Jun 24 16:05:04 2024 -0400

    Merge branch '2024-07-content-prebuild' into subs-private

commit 960e262f19
Merge: c5bbadaacd 7ec8b84b01
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Mon Jun 24 16:03:40 2024 -0400

    Merge branch '2024-07-content-prebuild' of https://github.com/HabitRPG/habitica-private into 2024-07-content-prebuild

commit c5bbadaacd
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Mon Jun 24 16:03:23 2024 -0400

    add missing string info to July mystery items

commit 7ec8b84b01
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Mon Jun 24 11:29:17 2024 -0400

    add missing info to mystery item strings

commit 95c562fdbc
Author: Phillip Thelen <phillip@habitica.com>
Date:   Fri Jun 21 11:12:18 2024 +0200

    Fix serving memoized content

commit 877fe48225
Author: Phillip Thelen <phillip@habitica.com>
Date:   Thu Jun 20 12:23:24 2024 +0200

    correctly memoize conent api

commit e0f6f79c5b
Author: Phillip Thelen <phillip@habitica.com>
Date:   Thu Jun 20 10:11:27 2024 +0200

    don’t build multiple times on heroku

commit f62254d68e
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 19:40:20 2024 +0200

    fix client command

commit d054e6fc16
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 19:36:57 2024 +0200

    correct build call

commit 7231f699c1
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 19:32:32 2024 +0200

    try setting up with heroku buildpack

commit 1dae0793fd
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 18:50:32 2024 +0200

    call gulp build:prod

commit f18fbe86b6
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 18:40:53 2024 +0200

    build client

commit 61a61724ca
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 18:33:18 2024 +0200

    testing

commit 93cf30eb18
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 18:20:25 2024 +0200

    integration fix

commit cff08adcd0
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 18:13:20 2024 +0200

    specify dev docker file

commit 4da2ed4a1f
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 18:10:07 2024 +0200

    initialize stub

commit 11c5b26c59
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 18:08:45 2024 +0200

    test heroku file

commit ac85bb2e2d
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 18:03:15 2024 +0200

    fix stub reference

commit 74dfb2710f
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 18:01:27 2024 +0200

    test fixes

commit 8dbd3c3db1
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 17:37:04 2024 +0200

    fix canOwn test

commit 74b3b348ff
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 17:32:31 2024 +0200

    fix buy test

commit 3386d61fde
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 17:30:37 2024 +0200

    fix debug tests

commit 19da14531c
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 17:05:25 2024 +0200

    add chameleon to featured quests

commit 254dd80f24
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 17:05:14 2024 +0200

    fix import

commit 0bc3f16b4b
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 16:33:22 2024 +0200

    add new content to new release file

commit 5184973bd5
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 16:33:11 2024 +0200

    fix release date tests

commit b6accca5ca
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 16:33:06 2024 +0200

    fix armoire tests

commit fec68e6211
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 16:02:03 2024 +0200

    fix tests

commit fc63c906dd
Author: Phillip Thelen <phillip@habitica.com>
Date:   Mon Jun 10 14:44:21 2024 +0200

    Improve test coverage

commit 3333f8f0f5
Author: Phillip Thelen <phillip@habitica.com>
Date:   Mon Jun 10 14:24:59 2024 +0200

    allow hatching potions to have a release date

commit 89a3ac3dde
Author: Phillip Thelen <phillip@habitica.com>
Date:   Mon Jun 10 14:11:38 2024 +0200

    allow eggs to have a release date

    # Conflicts:
    #	test/content/armoire.test.js

commit 16551ec83f
Merge: f5f4974a73 2645bf6023
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Tue Jun 18 15:03:12 2024 -0400

    Merge branch '2024-07-content-prebuild' into subs-private

commit 2645bf6023
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Tue Jun 18 15:02:47 2024 -0400

    update habitica images

commit f5f4974a73
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Tue Jun 18 14:58:13 2024 -0400

    update habitica-images

commit 162e337d14
Merge: f2506c3231 21a7d36b7b
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Tue Jun 18 13:46:03 2024 -0400

    Merge branch '2024-07-content-prebuild' into subs-private

commit 21a7d36b7b
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Tue Jun 18 13:45:09 2024 -0400

    update sprites

commit f2506c3231
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Tue Jun 18 13:24:21 2024 -0400

    updated sprites css

commit d47641e25a
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Tue Jun 18 12:46:59 2024 -0400

    typo fix

commit fb8479ad1e
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Mon Jun 17 13:44:36 2024 -0400

    finish July prebuild

commit 3810cf3ef3
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Fri Jun 14 10:42:47 2024 -0400

    add chameleon quest

commit d05da3722c
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Thu Jun 13 17:12:43 2024 -0400

    add June background notes

commit b8a3440ef2
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Thu Jun 13 16:40:04 2024 -0400

    fix mystery item and background description

commit 44d63032d8
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Thu Jun 13 15:38:23 2024 -0400

    add subscriber gear, enchanted armoire, and background

commit 9d7da91ec6
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Thu Jun 13 14:44:59 2024 -0400

    add sprites
2024-06-28 09:55:41 -05:00
Sabe Jones f55d836398 Squashed commit of the following:
commit 960e262f19
Merge: c5bbadaacd 7ec8b84b01
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Mon Jun 24 16:03:40 2024 -0400

    Merge branch '2024-07-content-prebuild' of https://github.com/HabitRPG/habitica-private into 2024-07-content-prebuild

commit c5bbadaacd
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Mon Jun 24 16:03:23 2024 -0400

    add missing string info to July mystery items

commit 7ec8b84b01
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Mon Jun 24 11:29:17 2024 -0400

    add missing info to mystery item strings

commit 2645bf6023
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Tue Jun 18 15:02:47 2024 -0400

    update habitica images

commit 21a7d36b7b
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Tue Jun 18 13:45:09 2024 -0400

    update sprites

commit d47641e25a
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Tue Jun 18 12:46:59 2024 -0400

    typo fix

commit fb8479ad1e
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Mon Jun 17 13:44:36 2024 -0400

    finish July prebuild

commit 3810cf3ef3
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Fri Jun 14 10:42:47 2024 -0400

    add chameleon quest

commit d05da3722c
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Thu Jun 13 17:12:43 2024 -0400

    add June background notes

commit b8a3440ef2
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Thu Jun 13 16:40:04 2024 -0400

    fix mystery item and background description

commit 44d63032d8
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Thu Jun 13 15:38:23 2024 -0400

    add subscriber gear, enchanted armoire, and background

commit 9d7da91ec6
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Thu Jun 13 14:44:59 2024 -0400

    add sprites
2024-06-28 09:50:28 -05:00
Sabe Jones 287014518d Squashed commit of the following:
commit 28193f86fb
Author: Phillip Thelen <phillip@habitica.com>
Date:   Fri Jun 21 11:12:18 2024 +0200

    Fix serving memoized content

commit 877fe48225
Author: Phillip Thelen <phillip@habitica.com>
Date:   Thu Jun 20 12:23:24 2024 +0200

    correctly memoize conent api

commit e0f6f79c5b
Author: Phillip Thelen <phillip@habitica.com>
Date:   Thu Jun 20 10:11:27 2024 +0200

    don’t build multiple times on heroku

commit f62254d68e
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 19:40:20 2024 +0200

    fix client command

commit d054e6fc16
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 19:36:57 2024 +0200

    correct build call

commit 7231f699c1
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 19:32:32 2024 +0200

    try setting up with heroku buildpack

commit 1dae0793fd
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 18:50:32 2024 +0200

    call gulp build:prod

commit f18fbe86b6
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 18:40:53 2024 +0200

    build client

commit 61a61724ca
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 18:33:18 2024 +0200

    testing

commit 93cf30eb18
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 18:20:25 2024 +0200

    integration fix

commit cff08adcd0
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 18:13:20 2024 +0200

    specify dev docker file

commit 4da2ed4a1f
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 18:10:07 2024 +0200

    initialize stub

commit 11c5b26c59
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 18:08:45 2024 +0200

    test heroku file

commit ac85bb2e2d
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 18:03:15 2024 +0200

    fix stub reference

commit 74dfb2710f
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 18:01:27 2024 +0200

    test fixes

commit 8dbd3c3db1
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 17:37:04 2024 +0200

    fix canOwn test

commit 74b3b348ff
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 17:32:31 2024 +0200

    fix buy test

commit 3386d61fde
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 17:30:37 2024 +0200

    fix debug tests

commit 19da14531c
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 17:05:25 2024 +0200

    add chameleon to featured quests

commit 254dd80f24
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 17:05:14 2024 +0200

    fix import

commit 0bc3f16b4b
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 16:33:22 2024 +0200

    add new content to new release file

commit 5184973bd5
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 16:33:11 2024 +0200

    fix release date tests

commit b6accca5ca
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 16:33:06 2024 +0200

    fix armoire tests

commit fec68e6211
Author: Phillip Thelen <phillip@habitica.com>
Date:   Wed Jun 19 16:02:03 2024 +0200

    fix tests

commit fc63c906dd
Author: Phillip Thelen <phillip@habitica.com>
Date:   Mon Jun 10 14:44:21 2024 +0200

    Improve test coverage

commit 3333f8f0f5
Author: Phillip Thelen <phillip@habitica.com>
Date:   Mon Jun 10 14:24:59 2024 +0200

    allow hatching potions to have a release date

commit 89a3ac3dde
Author: Phillip Thelen <phillip@habitica.com>
Date:   Mon Jun 10 14:11:38 2024 +0200

    allow eggs to have a release date

    # Conflicts:
    #	test/content/armoire.test.js

commit 16551ec83f
Merge: f5f4974a73 2645bf6023
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Tue Jun 18 15:03:12 2024 -0400

    Merge branch '2024-07-content-prebuild' into subs-private

commit 2645bf6023
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Tue Jun 18 15:02:47 2024 -0400

    update habitica images

commit f5f4974a73
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Tue Jun 18 14:58:13 2024 -0400

    update habitica-images

commit 162e337d14
Merge: f2506c3231 21a7d36b7b
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Tue Jun 18 13:46:03 2024 -0400

    Merge branch '2024-07-content-prebuild' into subs-private

commit 21a7d36b7b
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Tue Jun 18 13:45:09 2024 -0400

    update sprites

commit f2506c3231
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Tue Jun 18 13:24:21 2024 -0400

    updated sprites css

commit d47641e25a
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Tue Jun 18 12:46:59 2024 -0400

    typo fix

commit fb8479ad1e
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Mon Jun 17 13:44:36 2024 -0400

    finish July prebuild

commit 3810cf3ef3
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Fri Jun 14 10:42:47 2024 -0400

    add chameleon quest

commit d05da3722c
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Thu Jun 13 17:12:43 2024 -0400

    add June background notes

commit b8a3440ef2
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Thu Jun 13 16:40:04 2024 -0400

    fix mystery item and background description

commit 44d63032d8
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Thu Jun 13 15:38:23 2024 -0400

    add subscriber gear, enchanted armoire, and background

commit 9d7da91ec6
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Thu Jun 13 14:44:59 2024 -0400

    add sprites
2024-06-28 09:49:08 -05:00
Weblate b46e2da61b Merge branch 'develop' of github.com:HabitRPG/habitica into develop 2024-06-28 16:41:20 +02:00
Emilia Skoglund ef47d6cf0b Translated using Weblate (Swedish)
Currently translated at 80.0% (619 of 773 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/sv/
2024-06-28 05:28:46 +02:00
Daniel Faria Gomes 1f5d66cd58 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (773 of 773 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/pt_BR/
2024-06-28 05:28:46 +02:00
Natalie Luhrs a88602a21f Translated using Weblate (Japanese)
Currently translated at 100.0% (773 of 773 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/ja/
2024-06-27 20:24:32 +02:00
Sabe Jones ffd2b4b76f fix(quests): modest Bundle revisions 2024-06-27 11:41:39 -05:00
Sabe Jones c50ed843fb Merge branch 'release' into sabrecat/postfixes 2024-06-27 10:03:30 -05:00
Sabe Jones 760c05df5d 5.25.8 2024-06-26 12:36:32 -05:00
Phillip Thelen 26d070f2c3 improve loggly request logging call (#15259) 2024-06-26 12:30:13 -05:00
Sabe Jones 850ae5114f fix(schedule): add Oddballs to November 2024-06-24 13:27:13 -05:00
Petal Forrest bc9577439e Translated using Weblate (English (United Kingdom))
Currently translated at 100.0% (286 of 286 strings)

Translation: Habitica/Limited
Translate-URL: https://translate.habitica.com/projects/habitica/limited/en_GB/
2024-06-22 10:40:51 +02:00
Petal Forrest 10cd596f0b Translated using Weblate (English (United Kingdom))
Currently translated at 100.0% (427 of 427 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/en_GB/
2024-06-22 10:40:50 +02:00
Toro Mor d180062ad2 Translated using Weblate (German)
Currently translated at 91.9% (2852 of 3103 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/de/
2024-06-22 10:40:50 +02:00
Petal Forrest bfacf4b36e Translated using Weblate (English (United Kingdom))
Currently translated at 100.0% (259 of 259 strings)

Translation: Habitica/Settings
Translate-URL: https://translate.habitica.com/projects/habitica/settings/en_GB/
2024-06-22 10:40:50 +02:00
Weblate 2912f31dec Translated using Weblate (English (United Kingdom))
Currently translated at 100.0% (140 of 140 strings)

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (233 of 233 strings)

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (94 of 94 strings)

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (113 of 113 strings)

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (60 of 60 strings)

Translated using Weblate (English (United Kingdom))

Currently translated at 76.1% (325 of 427 strings)

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (182 of 182 strings)

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (773 of 773 strings)

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (91 of 91 strings)

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (47 of 47 strings)

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (378 of 378 strings)

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (189 of 189 strings)

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (868 of 868 strings)

Translated using Weblate (English (United Kingdom))

Currently translated at 97.3% (184 of 189 strings)

Translated using Weblate (English (United Kingdom))

Currently translated at 97.3% (184 of 189 strings)

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (131 of 131 strings)

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (239 of 239 strings)

Translated using Weblate (English (United Kingdom))

Currently translated at 99.8% (772 of 773 strings)

Translated using Weblate (English (United Kingdom))

Currently translated at 96.8% (183 of 189 strings)

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (110 of 110 strings)

Translated using Weblate (English (United Kingdom))

Currently translated at 79.6% (691 of 868 strings)

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (167 of 167 strings)

Co-authored-by: Petal Forrest <adrijanaskar2008backup@gmail.com>
Co-authored-by: Razi H <razi.haj@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/en_GB/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/en_GB/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/en_GB/
Translate-URL: https://translate.habitica.com/projects/habitica/character/en_GB/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/en_GB/
Translate-URL: https://translate.habitica.com/projects/habitica/content/en_GB/
Translate-URL: https://translate.habitica.com/projects/habitica/contrib/en_GB/
Translate-URL: https://translate.habitica.com/projects/habitica/front/en_GB/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/en_GB/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/en_GB/
Translate-URL: https://translate.habitica.com/projects/habitica/messages/en_GB/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/en_GB/
Translate-URL: https://translate.habitica.com/projects/habitica/pets/en_GB/
Translate-URL: https://translate.habitica.com/projects/habitica/quests/en_GB/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/en_GB/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/en_GB/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/en_GB/
Translation: Habitica/Achievements
Translation: Habitica/Backgrounds
Translation: Habitica/Challenge
Translation: Habitica/Character
Translation: Habitica/Communityguidelines
Translation: Habitica/Content
Translation: Habitica/Contrib
Translation: Habitica/Front
Translation: Habitica/Generic
Translation: Habitica/Groups
Translation: Habitica/Messages
Translation: Habitica/Npc
Translation: Habitica/Pets
Translation: Habitica/Quests
Translation: Habitica/Questscontent
Translation: Habitica/Subscriber
Translation: Habitica/Tasks
2024-06-22 01:12:00 +02:00
Sabe Jones c47b287a89 5.25.7 2024-06-21 13:28:34 -05:00
Sabe Jones 3aa626d2ae fix(sprites): remove potion PNG override 2024-06-21 13:28:29 -05:00
Sabe Jones 647ee2a073 5.25.6 2024-06-21 11:56:07 -05:00
Sabe Jones 2080c3f7b8 fix(content): restore Fungi Potions and Snail Armor 2024-06-21 11:56:01 -05:00
Sabe Jones 6f65c72921 5.25.5 2024-06-21 10:14:57 -05:00
Sabe Jones 22bbdd6a28 Merge branch 'develop' into release 2024-06-21 10:14:54 -05:00
Phillip Thelen 1a3d6f6520 fix mage gear being shown as twohanded (#15254) 2024-06-21 10:14:25 -05:00
Sabe Jones aa1e78ac94 5.25.4 2024-06-21 09:59:08 -05:00
Sabe Jones 858caa4582 fix(cShop): price display for animal pieces 2024-06-21 09:58:33 -05:00
Phillip Thelen 28193f86fb Fix serving memoized content 2024-06-21 11:12:18 +02:00
Phillip Thelen 877fe48225 correctly memoize conent api 2024-06-20 12:23:24 +02:00
Phillip Thelen e0f6f79c5b don’t build multiple times on heroku 2024-06-20 10:11:27 +02:00
Phillip Thelen f62254d68e fix client command 2024-06-19 19:40:20 +02:00
Phillip Thelen d054e6fc16 correct build call 2024-06-19 19:36:57 +02:00
Phillip Thelen 7231f699c1 try setting up with heroku buildpack 2024-06-19 19:32:32 +02:00
Phillip Thelen 1dae0793fd call gulp build:prod 2024-06-19 18:50:32 +02:00
Phillip Thelen f18fbe86b6 build client 2024-06-19 18:40:53 +02:00
Phillip Thelen 61a61724ca testing 2024-06-19 18:33:18 +02:00
Phillip Thelen 93cf30eb18 integration fix 2024-06-19 18:20:43 +02:00
Phillip Thelen cff08adcd0 specify dev docker file 2024-06-19 18:13:20 +02:00
Phillip Thelen 4da2ed4a1f initialize stub 2024-06-19 18:10:07 +02:00
Phillip Thelen 11c5b26c59 test heroku file 2024-06-19 18:08:45 +02:00
Phillip Thelen ac85bb2e2d fix stub reference 2024-06-19 18:03:15 +02:00
Phillip Thelen 74dfb2710f test fixes 2024-06-19 18:02:28 +02:00
Phillip Thelen 8dbd3c3db1 fix canOwn test 2024-06-19 17:37:04 +02:00
Phillip Thelen 74b3b348ff fix buy test 2024-06-19 17:32:31 +02:00
Phillip Thelen 3386d61fde fix debug tests 2024-06-19 17:30:52 +02:00
Phillip Thelen 19da14531c add chameleon to featured quests 2024-06-19 17:05:25 +02:00
Phillip Thelen 254dd80f24 fix import 2024-06-19 17:05:14 +02:00
Phillip Thelen 0bc3f16b4b add new content to new release file 2024-06-19 16:33:22 +02:00
Phillip Thelen 5184973bd5 fix release date tests 2024-06-19 16:33:11 +02:00
Phillip Thelen b6accca5ca fix armoire tests 2024-06-19 16:33:06 +02:00
Phillip Thelen fec68e6211 fix tests 2024-06-19 16:02:03 +02:00
Phillip Thelen fc63c906dd Improve test coverage 2024-06-19 15:25:45 +02:00
Phillip Thelen 3333f8f0f5 allow hatching potions to have a release date 2024-06-19 15:25:45 +02:00
Phillip Thelen 89a3ac3dde allow eggs to have a release date
# Conflicts:
#	test/content/armoire.test.js
2024-06-19 15:24:21 +02:00
CuriousMagpie 16551ec83f Merge branch '2024-07-content-prebuild' into subs-private 2024-06-18 15:03:12 -04:00
CuriousMagpie 2645bf6023 update habitica images 2024-06-18 15:02:47 -04:00
CuriousMagpie f5f4974a73 update habitica-images 2024-06-18 14:58:13 -04:00
CuriousMagpie 162e337d14 Merge branch '2024-07-content-prebuild' into subs-private 2024-06-18 13:46:03 -04:00
CuriousMagpie 21a7d36b7b update sprites 2024-06-18 13:45:09 -04:00
CuriousMagpie f2506c3231 updated sprites css 2024-06-18 13:24:21 -04:00
CuriousMagpie d47641e25a typo fix 2024-06-18 12:46:59 -04:00
CuriousMagpie fb8479ad1e finish July prebuild 2024-06-17 13:44:36 -04:00
CuriousMagpie 3810cf3ef3 add chameleon quest 2024-06-14 10:42:47 -04:00
CuriousMagpie d05da3722c add June background notes 2024-06-13 17:12:43 -04:00
CuriousMagpie b8a3440ef2 fix mystery item and background description 2024-06-13 16:40:04 -04:00
CuriousMagpie 44d63032d8 add subscriber gear, enchanted armoire, and background 2024-06-13 15:38:23 -04:00
CuriousMagpie 9d7da91ec6 add sprites 2024-06-13 14:44:59 -04:00
Sabe Jones 8b3267458b fix(groups): fix TypeError when missing 2024-02-05 18:06:18 -06:00
Sabe Jones bccfaab350 Merge branch 'release' into sabrecat/more-api-sunset 2024-02-05 17:28:11 -06:00
Sabe Jones 753f12979e fix(api): close lingering deprecated APIs 2024-02-05 17:22:47 -06:00
257 changed files with 4385 additions and 18876 deletions
+5 -2
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
+12 -6
View File
@@ -1,14 +1,20 @@
Habitica ![Build Status](https://github.com/HabitRPG/habitica/workflows/Test/badge.svg) [![Code Climate](https://codeclimate.com/github/HabitRPG/habitrpg.svg)](https://codeclimate.com/github/HabitRPG/habitrpg) [![Bountysource](https://api.bountysource.com/badge/tracker?tracker_id=68393)](https://www.bountysource.com/trackers/68393-habitrpg?utm_source=68393&utm_medium=shield&utm_campaign=TRACKER_BADGE)
Habitica ![Build Status](https://github.com/HabitRPG/habitica/workflows/Test/badge.svg)
===============
[Habitica](https://habitica.com) is an open-source habit-building program that treats your life like a role-playing game. Level up as you succeed, lose HP as you fail, and earn money to buy weapons and armor.
[Habitica](https://habitica.com) is an open-source habit-building program that treats your life like a role-playing game. Level up as you succeed, lose HP as you fail, and earn Gold to buy weapons and armor!
**We need more programmers!** Your assistance will be greatly appreciated. The wiki pages below and the additional pages they link to will tell you how to get started on contributing code and where you can go to seek further help or ask questions:
**Want to contribute code to Habitica?** We're always looking for assistance on any issues in our repo with the "Help Wanted" label. The wiki pages below and the additional linked pages will tell you how to start contributing code and where you can seek further help or ask questions:
* [Guidance for Blacksmiths](https://habitica.fandom.com/wiki/Guidance_for_Blacksmiths) - an introduction to the technologies used and how the software is organized.
* [Setting up Habitica Locally](https://habitica.fandom.com/wiki/Setting_up_Habitica_Locally) - how to set up a local install of Habitica for development and testing on various platforms.
* [Setting up Habitica Locally](https://github.com/HabitRPG/habitica/wiki/Setting-Up-Habitica-for-Local-Development) - how to set up a local install of Habitica for development and testing.
**Interested in contributing to Habiticas mobile apps?** Visit the links below for our mobile repositories.
* **Android:** https://github.com/HabitRPG/habitica-android
* **iOS:** https://github.com/HabitRPG/habitica-ios
Habitica's code is licensed as described at https://github.com/HabitRPG/habitica/blob/develop/LICENSE
**Found a bug?** Please report it to [admin email](mailto:admin@habitica.com) rather than creating an issue (an admin will advise you if a new issue is necessary; usually it is not).
**Found a bug?** Please report it to [admin email](mailto:admin@habitica.com) rather than create an issue (an admin will advise you if a new issue is necessary; usually it is not).
**Have any questions about Habitica or its community?** See the links in the [habitica.com](https://habitica.com) website's Help menu or drop in to [Guilds > Tavern Chat](https://habitica.com/groups/tavern) to ask questions or chat socially!
**Creating a third-party tool?** Please review our [API Usage Guidelines](https://github.com/HabitRPG/habitica/wiki/API-Usage-Guidelines) to ensure that your tool is compliant and maintains the best experience for Habitica players.
**Have any questions about Habitica or contributing?** See the links in the [Habitica](https://habitica.com) website's Help menu. Theres FAQs, guides, and the option to reach out to us with any further questions!
+33 -2
View File
@@ -42,10 +42,41 @@ function cssVarMap (sprite) {
}
}
function createSpritesStream (name, src) {
function filterFile (file) {
if (file.relative.indexOf('Mount_Icon_') !== -1) {
return false;
}
if (file.path.indexOf('shop/') !== -1) {
return false;
}
if (file.path.indexOf('stable/eggs') !== -1) {
return false;
}
if (file.path.indexOf('stable/food') !== -1) {
return false;
}
if (file.path.indexOf('stable/potions') !== -1) {
return false;
}
if (file.relative.indexOf('shop_') === 0) {
return false;
}
if (file.relative.indexOf('icon_background') === 0) {
return false;
}
return true;
}
async function createSpritesStream (name, src) {
const stream = mergeStream();
// need to import this way bc of weird dependency things
// eslint-disable-next-line global-require
const filter = require('gulp-filter');
const f = filter(filterFile);
const spriteData = gulp.src(src)
.pipe(f)
.pipe(spritesmith({
imgName: `spritesmith-${name}.png`,
cssName: `spritesmith-${name}.css`,
@@ -63,7 +94,7 @@ function createSpritesStream (name, src) {
return stream;
}
gulp.task('sprites:main', () => {
gulp.task('sprites:main', async () => {
const mainSrc = sync('habitica-images/**/*.png');
return createSpritesStream('main', mainSrc);
});
@@ -1,14 +1,12 @@
/* eslint-disable no-console */
const MIGRATION_NAME = '20230731_naming_day';
import { v4 as uuid } from 'uuid';
import { model as User } from '../../../website/server/models/user';
import { model as User } from '../../website/server/models/user';
const MIGRATION_NAME = '20240731_naming_day';
const progressCount = 1000;
let count = 0;
async function updateUser (user) {
count++;
count += 1;
let set;
let push;
@@ -115,16 +113,16 @@ async function updateUser (user) {
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
if (push) {
return await user.updateOne({ $set: set, $inc: inc, $push: push }).exec();
} else {
return await user.updateOne({ $set: set, $inc: inc }).exec();
return user.updateOne({ $set: set, $inc: inc, $push: push }).exec();
}
return user.updateOne({ $set: set, $inc: inc }).exec();
}
export default async function processUsers () {
let query = {
const query = {
migration: { $ne: MIGRATION_NAME },
'auth.timestamps.loggedin': { $gt: new Date('2023-07-01') },
'auth.timestamps.loggedin': { $gt: new Date('2024-07-01') },
};
const fields = {
@@ -136,7 +134,7 @@ export default async function processUsers () {
const users = await User // eslint-disable-line no-await-in-loop
.find(query)
.limit(250)
.sort({_id: 1})
.sort({ _id: 1 })
.select(fields)
.exec();
@@ -152,4 +150,4 @@ export default async function processUsers () {
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
}
};
}
+73 -5
View File
@@ -1,12 +1,12 @@
{
"name": "habitica",
"version": "5.25.3",
"version": "5.27.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "habitica",
"version": "5.25.3",
"version": "5.27.0",
"hasInstallScript": true,
"dependencies": {
"@babel/core": "^7.22.10",
@@ -40,6 +40,7 @@
"got": "^11.8.6",
"gulp": "^4.0.0",
"gulp-babel": "^8.0.0",
"gulp-filter": "^7.0.0",
"gulp-imagemin": "^7.1.0",
"gulp-nodemon": "^2.5.0",
"gulp.spritesmith": "^6.13.0",
@@ -4360,6 +4361,14 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/array-differ": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz",
"integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==",
"engines": {
"node": ">=8"
}
},
"node_modules/array-each": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz",
@@ -9721,9 +9730,9 @@
"integrity": "sha512-VhXlQgj9ioXCqGstD37E/HBeqEGV/qOD/kmbVG8h5xKBYvM1L3lR1Zn4555cQ8GkYbJa8aJSipLPndE1k6zK2w=="
},
"node_modules/fast-xml-parser": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.3.4.tgz",
"integrity": "sha512-utnwm92SyozgA3hhH2I8qldf2lBqm6qHOICawRNRFu1qMe3+oqr+GcXjGqTmXTMGE5T4eC03kr/rlh5C1IRdZA==",
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz",
"integrity": "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==",
"funding": [
{
"type": "github",
@@ -11493,6 +11502,31 @@
"@babel/core": "^7.0.0"
}
},
"node_modules/gulp-filter": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/gulp-filter/-/gulp-filter-7.0.0.tgz",
"integrity": "sha512-ZGWtJo0j1mHfP77tVuhyqem4MRA5NfNRjoVe6VAkLGeQQ/QGo2VsFwp7zfPTGDsd1rwzBmoDHhxpE6f5B3Zuaw==",
"dependencies": {
"multimatch": "^5.0.0",
"plugin-error": "^1.0.1",
"streamfilter": "^3.0.0",
"to-absolute-glob": "^2.0.2"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
},
"peerDependencies": {
"gulp": ">=4"
},
"peerDependenciesMeta": {
"gulp": {
"optional": true
}
}
},
"node_modules/gulp-imagemin": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/gulp-imagemin/-/gulp-imagemin-7.1.0.tgz",
@@ -15043,6 +15077,29 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node_modules/multimatch": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/multimatch/-/multimatch-5.0.0.tgz",
"integrity": "sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==",
"dependencies": {
"@types/minimatch": "^3.0.3",
"array-differ": "^3.0.0",
"array-union": "^2.1.0",
"arrify": "^2.0.1",
"minimatch": "^3.0.4"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/multimatch/node_modules/@types/minimatch": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz",
"integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ=="
},
"node_modules/mute-stdout": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz",
@@ -19468,6 +19525,17 @@
"resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz",
"integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ=="
},
"node_modules/streamfilter": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/streamfilter/-/streamfilter-3.0.0.tgz",
"integrity": "sha512-kvKNfXCmUyC8lAXSSHCIXBUlo/lhsLcCU/OmzACZYpRUdtKIH68xYhm/+HI15jFJYtNJGYtCgn2wmIiExY1VwA==",
"dependencies": {
"readable-stream": "^3.0.6"
},
"engines": {
"node": ">=8.12.0"
}
},
"node_modules/strict-uri-encode": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
+4 -2
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.3",
"version": "5.27.0",
"main": "./website/server/index.js",
"dependencies": {
"@babel/core": "^7.22.10",
@@ -35,6 +35,7 @@
"got": "^11.8.6",
"gulp": "^4.0.0",
"gulp-babel": "^8.0.0",
"gulp-filter": "^7.0.0",
"gulp-imagemin": "^7.1.0",
"gulp-nodemon": "^2.5.0",
"gulp.spritesmith": "^6.13.0",
@@ -107,7 +108,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",
+1 -1
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);
});
@@ -3,6 +3,7 @@ import {
createAndPopulateGroup,
translate as t,
} from '../../../../helpers/api-integration/v3';
import { model as Group } from '../../../../../website/server/models/group';
describe('GET /groups/:groupId/chat', () => {
let user;
@@ -37,4 +38,34 @@ describe('GET /groups/:groupId/chat', () => {
});
});
});
context('public Guild', () => {
let group;
before(async () => {
({ group } = await createAndPopulateGroup({
groupDetails: {
name: 'test group',
type: 'guild',
privacy: 'private',
},
members: 1,
upgradeToGroupPlan: true,
chat: [
'Hello',
'Welcome to the Guild',
],
}));
// Creation API is shut down, we need to simulate an extant public group
await Group.updateOne({ _id: group._id }, { $set: { privacy: 'public' }, $unset: { 'purchased.plan': 1 } }).exec();
});
it('returns error if user attempts to fetch a sunset Guild', async () => {
await expect(user.get(`/groups/${group._id}/chat`)).to.eventually.be.rejected.and.eql({
code: 400,
error: 'BadRequest',
message: t('featureRetired'),
});
});
});
});
@@ -4,6 +4,7 @@ import {
createAndPopulateGroup,
translate as t,
} from '../../../../helpers/api-integration/v3';
import { model as Group } from '../../../../../website/server/models/group';
describe('POST /chat/:chatId/like', () => {
let user;
@@ -111,4 +112,18 @@ describe('POST /chat/:chatId/like', () => {
message: t('groupNotFound'),
});
});
it('does not like a message that belongs to a sunset public group', async () => {
const message = await anotherUser.post(`/groups/${groupWithChat._id}/chat`, { message: testMessage });
// Creation API is shut down, we need to simulate an extant public group
await Group.updateOne({ _id: groupWithChat._id }, { $set: { privacy: 'public' }, $unset: { 'purchased.plan': 1 } }).exec();
await expect(user.post(`/groups/${groupWithChat._id}/chat/${message.message.id}/like`))
.to.eventually.be.rejected.and.eql({
code: 400,
error: 'BadRequest',
message: t('featureRetired'),
});
});
});
@@ -123,7 +123,7 @@ describe('GET /world-state', () => {
const res = await requester().get('/world-state');
expect(res.npcImageSuffix).to.equal('winter');
expect(res.npcImageSuffix).to.equal('fall');
});
});
});
+10
View File
@@ -341,6 +341,16 @@ describe('shops', () => {
const backgrounds = shopCategories.find(cat => cat.identifier === 'backgrounds').items;
expect(backgrounds.length).to.be.greaterThan(0);
});
it('does not add an end date to steampunk gear', () => {
const categories = shopCategories.filter(cat => cat.identifier.startsWith('30'));
categories.forEach(category => {
expect(category.end).to.not.exist;
category.items.forEach(item => {
expect(item.end).to.not.exist;
});
});
});
});
describe('customizationShop', () => {
+1
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({
+11
View File
@@ -233,6 +233,17 @@ describe('shared.ops.purchase', () => {
expect(user.items.hatchingPotions[key]).to.eql(1);
});
it('purchases event hatching potion', async () => {
clock.restore();
clock = sandbox.useFakeTimers(moment('2022-04-10').valueOf());
const type = 'hatchingPotions';
const key = 'Veggie';
await purchase(user, { params: { type, key } });
expect(user.items.hatchingPotions[key]).to.eql(1);
});
it('purchases hatching potion if user completed quest', async () => {
const type = 'hatchingPotions';
const key = 'Bronze';
+15 -26
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;
}
+40 -18
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);
});
});
+10
View File
@@ -68,6 +68,16 @@ describe('Gear', () => {
});
});
it('only assigns mage weapons twoHanded', () => {
each([allGear.armor.special, allGear.head.special, allGear.shield.special], gearType => {
each(gearType, gear => {
if (gear.specialClass === 'wizard') {
expect(gear.twoHanded, gear.key).to.not.eql(true);
}
});
});
});
describe('backer gear', () => {
let user;
+18 -2
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
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-20'));
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-20'));
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);
});
});
});
+82
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');
});
});
});
});
+23 -11
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';
@@ -123,12 +123,18 @@ describe('Content Schedule', () => {
expect(matchers.seasonalGear.end).to.eql(moment.utc(`2024-06-21T${String(switchoverTime).padStart(2, '0')}:00:00.000Z`).toDate());
});
it('sets the end date for a winter gala', () => {
const date = new Date('2024-12-22');
const matchers = getAllScheduleMatchingGroups(date);
expect(matchers.seasonalGear.end).to.eql(moment.utc(`2025-03-21T${String(switchoverTime).padStart(2, '0')}:00:00.000Z`).toDate());
});
it('contains content for repeating events', () => {
const date = new Date('2024-04-15');
const matchers = getAllScheduleMatchingGroups(date);
expect(matchers.premiumHatchingPotions).to.exist;
expect(matchers.premiumHatchingPotions.items.length).to.equal(4);
expect(matchers.premiumHatchingPotions.items.indexOf('Garden')).to.not.equal(-1);
expect(matchers.premiumHatchingPotions.items.length).to.equal(5);
expect(matchers.premiumHatchingPotions.items.indexOf('Veggie')).to.not.equal(-1);
expect(matchers.premiumHatchingPotions.items.indexOf('Porcelain')).to.not.equal(-1);
});
@@ -167,7 +173,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) {
@@ -245,27 +251,33 @@ describe('Content Schedule', () => {
it('allows sets matching the month', () => {
const date = new Date('2024-07-08');
const matcher = getAllScheduleMatchingGroups(date).timeTravelers;
expect(matcher.match('202307')).to.be.true;
expect(matcher.match('202207')).to.be.true;
expect(matcher.match('202307'), '202307').to.be.true;
expect(matcher.match('202207'), '202207').to.be.true;
});
it('disallows sets not matching the month', () => {
const date = new Date('2024-07-08');
const matcher = getAllScheduleMatchingGroups(date).timeTravelers;
expect(matcher.match('202306')).to.be.false;
expect(matcher.match('202402')).to.be.false;
expect(matcher.match('202306'), '202306').to.be.false;
expect(matcher.match('202402'), '202402').to.be.false;
});
it('disallows sets from current month', () => {
const date = new Date('2024-07-08');
const matcher = getAllScheduleMatchingGroups(date).timeTravelers;
expect(matcher.match('202407')).to.be.false;
expect(matcher.match('202407'), '202407').to.be.false;
});
it('disallows sets from the future', () => {
const date = new Date('2024-07-08');
const matcher = getAllScheduleMatchingGroups(date).backgrounds;
expect(matcher.match('202507')).to.be.false;
const matcher = getAllScheduleMatchingGroups(date).timeTravelers;
expect(matcher.match('202507'), '202507').to.be.false;
});
it('matches sets released in the earlier half of the year', () => {
const date = new Date('2024-07-08');
const matcher = getAllScheduleMatchingGroups(date).timeTravelers;
expect(matcher.match('202401'), '202401').to.be.true;
});
});
});
+12 -3
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;
+9 -2
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>
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

File diff suppressed because it is too large Load Diff
@@ -23,16 +23,14 @@
{{ $t('foundNewItems') }}
</h2>
<div class="d-flex justify-content-center">
<div
<Sprite
class="item-box ml-auto mr-3"
:class="eggClass"
>
</div>
<div
:image-name="eggClass"
/>
<Sprite
class="item-box mr-auto"
:class="potionClass"
>
</div>
:image-name="potionClass"
/>
</div>
<p
v-once
@@ -103,8 +101,12 @@
<script>
import closeIcon from '@/assets/svg/close.svg';
import Sprite from '@/components/ui/sprite.vue';
export default {
components: {
Sprite,
},
data () {
return {
icons: Object.freeze({
@@ -19,10 +19,10 @@
</div>
<div class="inner-content">
<div class="achievement-background d-flex align-items-center">
<div
<Sprite
class="icon"
:class="achievementClass"
></div>
:image-name="achievementClass"
/>
</div>
<h4
class="title"
@@ -99,8 +99,12 @@
import achievements from '@/../../common/script/content/achievements';
import { mapState } from '@/libs/store';
import svgClose from '@/assets/svg/close.svg';
import Sprite from '@/components/ui/sprite.vue';
export default {
components: {
Sprite,
},
props: ['data'],
data () {
return {
@@ -6,6 +6,7 @@
<div
v-for="option in items"
:key="option.key"
:id="option.imageName"
class="outer-option-background"
:class="{
premium: Boolean(option.gem),
@@ -14,18 +15,28 @@
hide: option.hide }"
@click="option.click(option)"
>
<b-popover
:target="option.imageName"
triggers="hover focus"
placement="bottom"
:prevent-overflow="false"
>
<strong> {{ option.text }} </strong>
</b-popover>
<div class="option">
<div
class="sprite customize-option"
:class="option.class"
>
<Sprite
v-if="!option.none"
class="sprite"
:prefix="option.isGear ? 'shop' : 'icon'"
:imageName="option.imageName"
:image-name="option.imageName"
/>
<div
v-if="option.none"
v-else
class="redline-outer"
>
<div class="redline"></div>
</div>
</div>
</div>
</div>
</div>
@@ -35,8 +46,12 @@
import gem from '@/assets/svg/gem.svg';
import gold from '@/assets/svg/gold.svg';
import { avatarEditorUtilities } from '../../mixins/avatarEditUtilities';
import Sprite from '@/components/ui/sprite.vue';
export default {
components: {
Sprite,
},
mixins: [
avatarEditorUtilities,
],
@@ -75,7 +90,7 @@ export default {
cursor: pointer;
&.premium {
height: 112px;
height: 120px;
width: 96px;
margin-left: 8px;
margin-right: 8px;
@@ -92,21 +107,9 @@ export default {
box-shadow: 0 2px 2px 0 rgba(26, 24, 29, 0.16), 0 1px 4px 0 rgba(26, 24, 29, 0.12);
background-color: $white;
.sprite.customize-option.shirt {
margin-left: -3px !important;
// otherwise its overriden by the .outer-option-background:not(.none) { rules
}
.sprite.customize-option.skin {
margin-left: -8px !important;
// otherwise its overriden by the .outer-option-background:not(.none) { rules
}
.option {
border: none;
border-radius: 2px;
padding-left: 6px;
padding-top: 4px;
}
&:hover {
@@ -132,14 +135,14 @@ export default {
}
.redline-outer {
height: 60px;
width: 60px;
height: 68px;
width: 68px;
position: absolute;
bottom: 0;
margin: 0 auto 0 0;
.redline {
width: 60px;
width: 68px;
height: 4px;
display: block;
background: red;
@@ -148,7 +151,6 @@ export default {
top: 0;
margin-top: 30px;
margin-bottom: 20px;
margin-left: -1px;
}
}
}
@@ -164,10 +166,9 @@ export default {
}
.option {
vertical-align: bottom;
height: 64px;
width: 64px;
height: 76px;
width: 76px;
margin: 12px 8px;
border: 4px solid transparent;
border-radius: 10px;
position: relative;
@@ -182,44 +183,6 @@ export default {
.sprite.customize-option {
margin-top: 0;
margin-left: 0;
&.skin {
margin-top: -4px;
margin-left: -4px;
}
&.chair {
margin-left: -1px;
margin-top: -1px;
&.button_chair_black {
// different sprite margin?
margin-top: -3px;
}
&.handleless {
margin-left: -5px;
margin-top: -5px;
}
}
&.color, &.bangs, &.beard, &.flower, &.mustache {
background-position-x: -6px;
background-position-y: -12px;
}
&.hair.base {
background-position-x: -6px;
background-position-y: -4px;
}
&.headAccessory {
margin-top: 0;
margin-left: -4px;
}
&.headband {
margin-top: -6px;
margin-left: -27px;
}
}
}
</style>
@@ -75,6 +75,7 @@
<script>
import appearance from '@/../../common/script/content/appearance';
import upperFirst from 'lodash/upperFirst';
import { subPageMixin } from '../../mixins/subPage';
import { userStateMixin } from '../../mixins/userState';
import { avatarEditorUtilities } from '../../mixins/avatarEditUtilities';
@@ -82,9 +83,6 @@ import customizeBanner from './customize-banner';
import customizeOptions from './customize-options';
import subMenu from './sub-menu';
const freeShirtKeys = Object.keys(appearance.shirt).filter(k => appearance.shirt[k].price === 0);
const specialShirtKeys = Object.keys(appearance.shirt).filter(k => appearance.shirt[k].price !== 0);
export default {
components: {
customizeBanner,
@@ -106,17 +104,6 @@ export default {
headAccessory: ['bearEars', 'cactusEars', 'foxEars', 'lionEars', 'pandaEars', 'pigEars', 'tigerEars', 'wolfEars'],
},
chairKeys: ['none', 'black', 'blue', 'green', 'pink', 'red', 'yellow', 'handleless_black', 'handleless_blue', 'handleless_green', 'handleless_pink', 'handleless_red', 'handleless_yellow'],
specialShirtKeys,
items: [
{
id: 'size',
label: this.$t('size'),
},
{
id: 'shirt',
label: this.$t('shirt'),
},
],
};
},
computed: {
@@ -167,6 +154,7 @@ export default {
];
const noneOption = this.createGearItem(0, 'eyewear', 'base');
noneOption.none = true;
noneOption.text = this.$t('none');
const options = [
noneOption,
];
@@ -178,42 +166,36 @@ export default {
option.active = this.user.preferences.costume
? this.user.items.gear.costume.eyewear === newKey
: this.user.items.gear.equipped.eyewear === newKey;
option.class = `eyewear_special_${key}`;
option.imageName = `eyewear_special_${key}`;
option.isGear = true;
option.click = () => {
const type = this.user.preferences.costume ? 'costume' : 'equipped';
return this.equip(newKey, type);
};
option.text = this.$t(`eyewearSpecial${upperFirst(key)}Text`);
options.push(option);
}
return options;
},
freeShirts () {
return freeShirtKeys.map(s => this.mapKeysToFreeOption(s, 'shirt'));
},
specialShirts () {
let backgroundUpdate = this.backgroundUpdate; // eslint-disable-line
const keys = this.specialShirtKeys;
const options = keys.map(key => this.mapKeysToOption(key, 'shirt'));
return options;
},
headbands () {
const keys = ['blackHeadband', 'blueHeadband', 'greenHeadband', 'pinkHeadband', 'redHeadband', 'whiteHeadband', 'yellowHeadband'];
const noneOption = this.createGearItem(0, 'headAccessory', 'base', 'headband');
const noneOption = this.createGearItem(0, 'headAccessory', 'base');
noneOption.none = true;
noneOption.text = this.$t('none');
const options = [
noneOption,
];
for (const key of keys) {
const option = this.createGearItem(key, 'headAccessory', 'special', 'headband');
const option = this.createGearItem(key, 'headAccessory', 'special');
const newKey = `headAccessory_special_${key}`;
option.click = () => {
const type = this.user.preferences.costume ? 'costume' : 'equipped';
return this.equip(newKey, type);
};
option.text = this.$t(`headAccessory${upperFirst(key)}Text`);
options.push(option);
}
@@ -227,8 +209,9 @@ export default {
option.none = true;
}
option.active = this.user.preferences.chair === key;
option.class = `button_chair_${key} chair ${key.includes('handleless_') ? 'handleless' : ''}`;
option.imageName = `chair_${key}`;
option.click = () => this.set({ 'preferences.chair': key });
option.text = appearance.chair[key].text();
return option;
});
return options;
@@ -242,8 +225,11 @@ export default {
option.none = true;
}
option.active = this.user.preferences.hair.flower === key;
option.class = `icon_hair_flower_${key} flower`;
if (key !== 0) {
option.imageName = `hair_flower_${key}`;
}
option.click = () => this.set({ 'preferences.hair.flower': key });
option.text = appearance.hair.flower[key].text();
return option;
});
return options;
@@ -271,6 +257,7 @@ export default {
const noneOption = this.createGearItem(0, category, 'base', category);
noneOption.none = true;
noneOption.text = this.$t('none');
const options = [
noneOption,
];
@@ -284,10 +271,15 @@ export default {
option.active = this.user.preferences.costume
? this.user.items.gear.costume[category] === newKey
: this.user.items.gear.equipped[category] === newKey;
option.class = `headAccessory_special_${option.key} ${category}`;
if (category === 'back') {
option.class = `icon_back_special_${option.key} back`;
option.text = this.$t(`back${upperFirst(key)}Text`);
option.imageName = `back_special_${option.key}`;
} else {
option.text = this.$t(`headAccessory${upperFirst(key)}Text`);
option.imageName = `headAccessory_special_${option.key}`;
}
option.isGear = true;
option.click = () => {
const type = this.user.preferences.costume ? 'costume' : 'equipped';
return this.equip(newKey, type);
@@ -303,7 +295,7 @@ export default {
return keys.join(',');
},
createGearItem (key, gearType, subGearType, additionalClass) {
createGearItem (key, gearType, subGearType) {
const newKey = `${gearType}_${subGearType ? `${subGearType}_` : ''}${key}`;
const option = {};
option.key = key;
@@ -311,6 +303,7 @@ export default {
const currentlyEquippedValue = this.user.items.gear[visibleGearType][gearType];
option.active = currentlyEquippedValue === newKey;
option.isGear = true;
if (key === 0) {
// if key is the "none" option check if a property
@@ -318,7 +311,7 @@ export default {
option.active = option.active || !currentlyEquippedValue;
}
option.class = `${newKey} ${additionalClass}`;
option.imageName = `${newKey}`;
option.click = () => {
const type = this.user.preferences.costume ? 'costume' : 'equipped';
const currentlyEquipped = this.user.items.gear[type][gearType];
+13 -10
View File
@@ -220,10 +220,10 @@
:class="{selected: bg.key === user.preferences.background}"
@click="unlock('background.' + bg.key)"
>
<div
<Sprite
class="background"
:class="`icon_background_${bg.key}`"
></div>
:image-name="`icon_background_${bg.key}`"
/>
<b-popover
:target="bg.key"
triggers="hover focus"
@@ -254,10 +254,10 @@
:class="{selected: bg.key === user.preferences.background}"
@click="unlock('background.' + bg.key)"
>
<div
<Sprite
class="background"
:class="`icon_background_${bg.key}`"
></div>
:image-name="`icon_background_${bg.key}`"
/>
<b-popover
:target="bg.key"
triggers="hover focus"
@@ -286,10 +286,10 @@
:class="{selected: bg.key === user.preferences.background}"
@click="unlock('background.' + bg.key)"
>
<div
<Sprite
class="background"
:class="`icon_background_${bg.key}`"
></div>
:image-name="`icon_background_${bg.key}`"
/>
<b-popover
:target="bg.key"
triggers="hover focus"
@@ -818,9 +818,10 @@
.background {
border-radius: 4px;
object-position: -4px -4px;
object-fit: none;
width: 60px;
height: 60px;
background-position: -4px -4px;
}
.deselect {
@@ -1013,6 +1014,7 @@ import arrowRight from '@/assets/svg/arrow_right.svg';
import arrowLeft from '@/assets/svg/arrow_left.svg';
import svgClose from '@/assets/svg/close.svg';
import { avatarEditorUtilities } from '../mixins/avatarEditUtilities';
import Sprite from './ui/sprite';
export default {
components: {
@@ -1024,6 +1026,7 @@ export default {
hairSettings,
skinSettings,
usernameForm,
Sprite,
},
mixins: [guide, notifications, avatarEditorUtilities],
data () {
@@ -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,
@@ -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
@@ -294,7 +297,7 @@
<div class="topbar-dropdown">
<router-link
v-if="user.permissions.fullAccess ||
user.permissions.userSupport || user.permissions.newsPoster"
user.permissions.userSupport"
class="topbar-dropdown-item dropdown-item"
:to="{name: 'adminPanel'}"
>
@@ -21,10 +21,10 @@
<slot
name="itemBadge"
:item="item"
></slot><span
></slot><Sprite
class="item-content"
:class="itemContentClass"
></span>
:image-name="itemContentClass"
/>
</div><span
v-if="label"
class="item-label"
@@ -46,8 +46,12 @@
<script>
import { v4 as uuid } from 'uuid';
import Sprite from '@/components/ui/sprite';
export default {
components: {
Sprite,
},
props: {
item: {
type: Object,
@@ -0,0 +1,113 @@
<template>
<div
ref="root"
v-if="draggedItem"
class="draggedItemInfo mouse"
v-mousePosition="30"
@mouseMoved="mouseMoved($event)">
<Sprite
class="dragging-icon"
:image-name="imageName()"
/>
<div class="popover">
<div
class="popover-content"
>
{{ $t(popoverTextKey, { [translationKey]: itemText() }) }}
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.draggedItemInfo {
position: absolute;
left: -500px;
z-index: 1080;
&.mouse {
position: fixed;
pointer-events: none
}
.dragging-icon {
width: 68px;
margin: 0 auto 8px;
display: block;
transform: scale(1.5);
}
.popover {
position: static;
width: 180px;
}
.popover-content {
color: white;
margin: 15px;
text-align: center;
}
}
</style>
<script>
import Sprite from '@/components/ui/sprite';
import MouseMoveDirective from '@/directives/mouseposition.directive';
export default {
name: 'ItemPopover',
components: {
Sprite,
},
directives: {
mousePosition: MouseMoveDirective,
},
props: {
draggedItem: {
type: Object,
default: null,
},
popoverTextKey: {
type: String,
default: '',
},
translationKey: {
type: String,
default: '',
},
},
methods: {
imageName () {
if (this.draggedItem) {
if (this.draggedItem.class) {
return this.draggedItem.class;
}
if (this.draggedItem.target) {
return `Pet_Food_${this.draggedItem.key}`;
}
}
return '';
},
mouseMoved ($event) {
if (this.$refs.root) {
this.$refs.root.style.left = `${$event.x - 60}px`;
this.$refs.root.style.top = `${$event.y + 10}px`;
}
},
itemText () {
if (this.draggedItem) {
if (this.draggedItem.text) {
if (typeof this.draggedItem.text === 'function') {
return this.draggedItem.text();
}
return this.draggedItem.text;
}
return this.draggedItem.class;
}
return '';
},
},
};
</script>
@@ -1,8 +1,6 @@
<template>
<div
v-mousePosition="30"
class="row"
@mouseMoved="mouseMoved($event)"
>
<div class="standard-sidebar d-none d-sm-block">
<filter-sidebar>
@@ -99,7 +97,7 @@
{{ context.item.text }}
</h4>
<div
v-if="currentDraggingPotion == null"
v-if="!currentDraggingPotion"
class="popover-content-text"
>
{{ context.item.notes }}
@@ -148,7 +146,7 @@
<h4 class="popover-content-title">
{{ context.item.text }}
</h4>
<div class="popover-content-text">
<div class="popover-content-text" v-if="!currentDraggingEgg">
{{ context.item.notes }}
</div>
</template>
@@ -224,120 +222,24 @@
</div>
</div>
<hatchedPetDialog />
<div
ref="draggingEggInfo"
class="eggInfo"
>
<div v-if="currentDraggingEgg != null">
<div
class="potion-icon"
:class="`Pet_Egg_${currentDraggingEgg.key}`"
></div>
<div class="popover">
<div class="popover-content">
{{ $t('dragThisEgg', {eggName: currentDraggingEgg.text }) }}
</div>
</div>
</div>
</div>
<div
v-if="eggClickMode"
ref="clickEggInfo"
class="eggInfo mouse"
>
<div v-if="currentDraggingEgg != null">
<div
class="potion-icon"
:class="`Pet_Egg_${currentDraggingEgg.key}`"
></div>
<div class="popover">
<div
class="popover-content"
>
{{ $t('clickOnPotionToHatch', {eggName: currentDraggingEgg.text }) }}
</div>
</div>
</div>
</div>
<div
ref="draggingPotionInfo"
class="hatchingPotionInfo"
>
<div v-if="currentDraggingPotion != null">
<div
class="potion-icon"
:class="`Pet_HatchingPotion_${currentDraggingPotion.key}`"
></div>
<div class="popover">
<div
class="popover-content"
>
{{ $t('dragThisPotion', {potionName: currentDraggingPotion.text }) }}
</div>
</div>
</div>
</div>
<div
v-if="potionClickMode"
ref="clickPotionInfo"
class="hatchingPotionInfo mouse"
>
<div v-if="currentDraggingPotion != null">
<div
class="potion-icon"
:class="`Pet_HatchingPotion_${currentDraggingPotion.key}`"
></div>
<div class="popover">
<div
class="popover-content"
>
{{ $t('clickOnEggToHatch', {potionName: currentDraggingPotion.text }) }}
</div>
</div>
</div>
</div>
<ItemPopover
:dragged-item="currentDraggingEgg"
popoverTextKey="clickOnPotionToHatch"
translationKey="eggName" />
<ItemPopover
:dragged-item="currentDraggingPotion"
popoverTextKey="clickOnEggToHatch"
translationKey="potionName" />
<questDetailModal :group="user.party" />
<cards-modal :card-options="cardOptions" />
</div>
</template>
<style lang="scss" scoped>
@import '~@/assets/scss/colors.scss';
.eggInfo, .hatchingPotionInfo {
position: absolute;
left: -500px;
z-index: 1080;
&.mouse {
position: fixed;
pointer-events: none
}
.potion-icon {
margin: 0 auto 8px;
transform: scale(1.5);
}
.popover {
position: inherit;
width: 180px;
}
.popover-content {
color: white;
margin: 15px;
text-align: center;
}
}
</style>
<script>
import each from 'lodash/each';
import throttle from 'lodash/throttle';
import moment from 'moment';
import ItemPopover from '@/components/inventory/itemPopover';
import Item from '@/components/inventory/item';
import ItemRows from '@/components/ui/itemRows';
import CountBadge from '@/components/ui/countBadge';
@@ -354,7 +256,6 @@ import { createAnimal } from '@/libs/createAnimal';
import notifications from '@/mixins/notifications';
import DragDropDirective from '@/directives/dragdrop.directive';
import MouseMoveDirective from '@/directives/mouseposition.directive';
import FilterGroup from '@/components/ui/filterGroup';
import Checkbox from '@/components/ui/checkbox';
import SelectTranslatedArray from '@/components/tasks/modal-controls/selectTranslatedArray';
@@ -375,8 +276,6 @@ const groups = [
allowedItems,
}));
let lastMouseMoveEvent = {};
export default {
name: 'Items',
components: {
@@ -391,10 +290,10 @@ export default {
cardsModal,
QuestInfo,
FilterSidebar,
ItemPopover,
},
directives: {
drag: DragDropDirective,
mousePosition: MouseMoveDirective,
},
mixins: [notifications],
data () {
@@ -405,9 +304,7 @@ export default {
sortBy: 'quantity', // or 'AZ'
currentDraggingEgg: null,
eggClickMode: false,
currentDraggingPotion: null,
potionClickMode: false,
cardOptions: {
cardType: '',
messageOptions: 0,
@@ -567,22 +464,13 @@ export default {
}
this.currentDraggingPotion = null;
this.potionClickMode = false;
return;
}
if (this.currentDraggingEgg === null || this.currentDraggingEgg !== egg) {
this.currentDraggingEgg = egg;
this.eggClickMode = true;
// Wait for the div.eggInfo.mouse node to be added to the DOM before
// changing its position.
this.$nextTick(() => {
this.mouseMoved(lastMouseMoveEvent);
});
} else {
this.currentDraggingEgg = null;
this.eggClickMode = false;
}
},
onPotionClicked ($event, potion) {
@@ -592,21 +480,12 @@ export default {
}
this.currentDraggingEgg = null;
this.eggClickMode = false;
return;
}
if (this.currentDraggingPotion === null || this.currentDraggingPotion !== potion) {
this.currentDraggingPotion = potion;
this.potionClickMode = true;
// Wait for the div.hatchingPotionInfo.mouse node to be added to the
// DOM before changing its position.
this.$nextTick(() => {
this.mouseMoved(lastMouseMoveEvent);
});
} else {
this.currentDraggingPotion = null;
this.potionClickMode = false;
}
},
@@ -640,23 +519,6 @@ export default {
});
}
},
mouseMoved ($event) {
// Keep track of the last mouse position even in click mode so that we
// know where to position the dragged potion/egg info on item click.
lastMouseMoveEvent = $event;
// Update the potion/egg popover if we are already dragging it.
if (this.potionClickMode) {
// dragging potioninfo is 180px wide (90 would be centered)
this.$refs.clickPotionInfo.style.left = `${$event.x - 60}px`;
this.$refs.clickPotionInfo.style.top = `${$event.y + 10}px`;
} else if (this.eggClickMode) {
// dragging eggInfo is 180px wide (90 would be centered)
this.$refs.clickEggInfo.style.left = `${$event.x - 60}px`;
this.$refs.clickEggInfo.style.top = `${$event.y + 10}px`;
}
},
},
};
</script>
@@ -13,13 +13,13 @@
:show="true"
:count="itemCount"
/>
<span
<Sprite
v-drag.food="item.key"
class="item-content"
:class="`Pet_Food_${item.key}`"
:image-name="`Pet_Food_${item.key}`"
@itemDragEnd="dragend($event)"
@itemDragStart="dragstart($event)"
></span>
/>
</div>
</div>
<b-popover
@@ -41,12 +41,14 @@
<script>
import { v4 as uuid } from 'uuid';
import DragDropDirective from '@/directives/dragdrop.directive';
import Sprite from '@/components/ui/sprite';
import CountBadge from '@/components/ui/countBadge';
export default {
components: {
CountBadge,
Sprite,
},
directives: {
drag: DragDropDirective,
@@ -20,7 +20,7 @@
</div>
<div class="inner-content">
<div class="pet-background d-flex align-items-center">
<div :class="pet.class"></div>
<Sprite :image-name="pet.imageName" />
</div>
<h4 class="title">
{{ pet.name }}
@@ -76,10 +76,11 @@
height: 112px;
border-radius: 4px;
background-color: $gray-700;
}
.Pet {
margin: auto;
img {
transform: scale(1.5);
margin: auto;
}
}
.dialog-header {
@@ -103,8 +104,12 @@
<script>
import markdownDirective from '@/directives/markdown';
import svgClose from '@/assets/svg/close.svg';
import Sprite from '@/components/ui/sprite';
export default {
components: {
Sprite,
},
directives: {
markdown: markdownDirective,
},
@@ -6,10 +6,10 @@
>
<div class="potionEggGroup">
<div class="potionEggBackground">
<div :class="`Pet_HatchingPotion_${hatchablePet.potionKey}`"></div>
<Sprite :image-name="`Pet_HatchingPotion_${hatchablePet.potionKey}`" />
</div>
<div class="potionEggBackground">
<div :class="`Pet_Egg_${hatchablePet.eggKey}`"></div>
<Sprite :image-name="`Pet_Egg_${hatchablePet.eggKey}`" />
</div>
</div>
<h4 class="title">
@@ -105,7 +105,7 @@
margin-right: 24px;
}
div {
img {
margin: 0 auto;
}
}
@@ -116,8 +116,12 @@
import svgClose from '@/assets/svg/close.svg';
import petMixin from '@/mixins/petMixin';
import Sprite from '@/components/ui/sprite';
export default {
components: {
Sprite,
},
mixins: [petMixin],
props: ['hatchablePet'],
data () {
@@ -1,8 +1,6 @@
<template>
<div
v-mousePosition="30"
class="row stable"
@mouseMoved="mouseMoved($event)"
>
<div class="standard-sidebar d-none d-sm-block">
<filter-sidebar>
@@ -265,43 +263,10 @@
</inventoryDrawer>
</div>
<hatchedPetDialog :hide-text="true" />
<div
ref="dragginFoodInfo"
class="foodInfo"
>
<div v-if="currentDraggingFood != null">
<div
class="food-icon"
:class="`Pet_Food_${currentDraggingFood.key}`"
></div>
<div class="popover">
<div
class="popover-content"
>
{{ $t('dragThisFood', {foodName: currentDraggingFood.text() }) }}
</div>
</div>
</div>
</div>
<div
v-if="foodClickMode"
ref="clickFoodInfo"
class="foodInfo mouse"
>
<div v-if="currentDraggingFood != null">
<div
class="food-icon"
:class="`Pet_Food_${currentDraggingFood.key}`"
></div>
<div class="popover">
<div
class="popover-content"
>
{{ $t('clickOnPetToFeed', {foodName: currentDraggingFood.text() }) }}
</div>
</div>
</div>
</div>
<ItemPopover
:dragged-item="currentDraggingFood"
popoverTextKey="clickOnPetToFeed"
translationKey="foodName" />
<mount-raised-modal />
<welcome-modal />
<hatching-modal :hatchable-pet.sync="hatchablePet" />
@@ -364,34 +329,6 @@
margin-bottom: 0;
}
.foodInfo {
position: absolute;
left: -500px;
z-index: 1080;
&.mouse {
position: fixed;
pointer-events: none
}
.food-icon {
margin: 0 auto 8px;
transform: scale(1.5);
}
.popover {
position: inherit;
width: 180px;
}
.popover-content {
color: white;
margin: 15px;
text-align: center;
}
}
.hatchablePopover {
width: 180px;
@@ -428,6 +365,7 @@ import _throttle from 'lodash/throttle';
import groupBy from 'lodash/groupBy';
import { mapState } from '@/libs/store';
import ItemPopover from '@/components/inventory/itemPopover';
import PetItem from './petItem';
import MountItem from './mountItem.vue';
import FoodItem from './foodItem';
@@ -440,7 +378,6 @@ import InventoryDrawer from '@/components/shared/inventoryDrawer';
import ResizeDirective from '@/directives/resize.directive';
import DragDropDirective from '@/directives/dragdrop.directive';
import MouseMoveDirective from '@/directives/mouseposition.directive';
import { createAnimal } from '@/libs/createAnimal';
@@ -482,11 +419,11 @@ export default {
WelcomeModal,
HatchingModal,
InventoryDrawer,
ItemPopover,
},
directives: {
resize: ResizeDirective,
drag: DragDropDirective,
mousePosition: MouseMoveDirective,
},
mixins: [notifications, openedItemRowsMixin, petMixin, seasonalNPC],
data () {
@@ -13,10 +13,11 @@
name="itemBadge"
:item="item"
></slot>
<span
<Sprite
class="item-content"
:class="itemClass()"
></span>
:image-name="imageName()"
/>
</div>
</div>
<b-popover
@@ -37,8 +38,12 @@
import { v4 as uuid } from 'uuid';
import { mapState } from '@/libs/store';
import { isOwned } from '../../../libs/createAnimal';
import Sprite from '@/components/ui/sprite';
export default {
components: {
Sprite,
},
props: {
item: {
type: Object,
@@ -70,7 +75,10 @@ export default {
return isOwned('mount', this.item, this.userItems);
},
itemClass () {
return this.isOwned() ? `Mount_Icon_${this.item.key}` : 'PixelPaw GreyedOut';
return this.isOwned() ? '' : 'GreyedOut';
},
imageName () {
return this.isOwned() ? `stable_Mount_Icon_${this.item.key}` : 'PixelPaw';
},
},
};
@@ -12,10 +12,10 @@
</div>
<div class="inner-content">
<div class="pet-background">
<div
<Sprite
class="mount"
:class="`Mount_Icon_${mount.key}`"
></div>
:image-name="`Mount_Icon_${mount.key}`"
/>
</div>
<h4 class="title">
{{ mount.text() }}
@@ -80,10 +80,14 @@
</style>
<script>
import { mountInfo } from '@/../../common/script/content/stable';
import stable from '@/../../common/script/content/stable';
import markdownDirective from '@/directives/markdown';
import Sprite from '@/components/ui/sprite';
export default {
components: {
Sprite,
},
directives: {
markdown: markdownDirective,
},
@@ -105,7 +109,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 () {
@@ -13,19 +13,23 @@
name="itemBadge"
:item="item"
></slot><span
v-if="mountOwned() && isHatchable() && !item.isSpecial()"
v-if="isHatchable() && !item.isSpecial()"
class="item-content hatchAgain"
><span
><Sprite
class="egg"
:class="eggClass"
></span><span
:image-name="eggClass"
/><Sprite
class="potion"
:class="potionClass"
></span></span><span
v-else
:image-name="potionClass"
/>
</span>
<Sprite
v-else
class="item-content"
:class="getPetItemClass()"
></span><span
:class="itemClass()"
:image-name="imageName()"
/>
<span
v-if="isAllowedToFeed() && progress() > 0"
class="pet-progress-background"
><div
@@ -52,9 +56,9 @@
v-html="$t('haveHatchablePet', { potion: item.potionName, egg: item.eggName })"
></div><div class="potionEggGroup">
<div class="potionEggBackground">
<div :class="potionClass"></div>
<Sprite :image-name="potionClass" />
</div><div class="potionEggBackground">
<div :class="eggClass"></div>
<Sprite :image-name="eggClass" />
</div>
</div>
</div><div v-else>
@@ -118,8 +122,12 @@ import foolPet from '@/mixins/foolPet';
import {
isAllowedToFeed, isHatchable, isOwned, isSpecial,
} from '../../../libs/createAnimal';
import Sprite from '@/components/ui/sprite';
export default {
components: {
Sprite,
},
mixins: [foolPet],
props: {
item: {
@@ -168,22 +176,28 @@ export default {
isAllowedToFeed () {
return isAllowedToFeed(this.item, this.userItems);
},
getPetItemClass () {
itemClass () {
if (this.isOwned() || this.isHatchable()) {
return '';
}
return 'GreyedOut';
},
imageName () {
if (this.isOwned() && some(
this.currentEventList,
event => moment().isBetween(event.start, event.end) && event.aprilFools && event.aprilFools === 'Fungi',
)) {
if (this.isSpecial()) return `Pet ${this.foolPet(this.item.key)}`;
if (this.isSpecial()) return `stable_${this.foolPet(this.item.key)}`;
const petString = `${this.item.eggKey}-${this.item.key}`;
return `Pet ${this.foolPet(petString)}`;
return `stable_${this.foolPet(petString)}`;
}
if (this.isOwned() || (this.mountOwned() && this.isHatchable())) {
return `Pet Pet-${this.item.key} ${this.item.eggKey}`;
return `stable_Pet-${this.item.key}`;
}
if (!this.isOwned() && this.isSpecial()) {
return 'GreyedOut PixelPaw';
return 'PixelPaw';
}
if (this.isHatchable()) {
@@ -191,11 +205,11 @@ export default {
}
if (this.mountOwned()) {
return `GreyedOut Pet Pet-${this.item.key} ${this.item.eggKey}`;
return `stable_Pet-${this.item.key}`;
}
// Can't hatch
return 'GreyedOut PixelPaw';
return 'PixelPaw';
},
progress () {
return this.userItems.pets[this.item.key];
@@ -56,11 +56,11 @@
class="list-group-item"
ng-init="inv.gear[item.key] = user.items.gear.owned[item.key]"
>
<div
<Sprite
class="pull-left"
:class="'shop_' + item.key"
:imageName="'shop_' + item.key"
style="margin-right: 10px"
></div>
/>
{{ item.text() }}
<div class="clearfix">
<label class="radio-inline">
@@ -330,9 +330,9 @@
class="list-group-item"
ng-init="inv.mounts[mount] = user.items.mounts[mount]"
>
<div
<Sprite
class="pull-left"
:class="'Mount_Icon_' + mount"
:imageName="mount.key"
style="margin-right: 10px"
></div>
{{ mount }}
@@ -363,9 +363,9 @@
class="list-group-item"
ng-init="inv.mounts[mount] = user.items.mounts[mount]"
>
<div
<Sprite
class="pull-left"
:class="'Mount_Icon_' + mount"
:imageName="mount.key"
style="margin-right: 10px"
></div>
{{ mount }}
@@ -396,9 +396,9 @@
class="list-group-item"
ng-init="inv.mounts[mount] = user.items.mounts[mount]"
>
<div
<Sprite
class="pull-left"
:class="'Mount_Icon_' + mount"
:imageName="mount.key"
style="margin-right: 10px"
></div>
{{ mount }}
@@ -429,9 +429,9 @@
class="list-group-item"
ng-init="inv.mounts[mount] = user.items.mounts[mount]"
>
<div
<Sprite
class="pull-left"
:class="'Mount_Icon_' + mount"
:imageName="mount.key"
style="margin-right: 10px"
></div>
{{ mount }}
@@ -503,11 +503,11 @@
ng-init="inv.hatchingPotions[item.key] = user.items.hatchingPotions[item.key]"
>
<div class="form-inline clearfix">
<div
<Sprite
class="pull-left"
:class="'Pet_HatchingPotion_' + item.key"
style="margin-right: 10px"
></div>
/>
<p>{{ item.text() }}</p>
<input
class="form-control"
@@ -565,11 +565,11 @@
ng-init="inv.eggs[item.key] = user.items.eggs[item.key]"
>
<div class="form-inline clearfix">
<div
<Sprite
class="pull-left"
:class="'Pet_Egg_' + item.key"
:image-name="'Pet_Egg_' + item.key"
style="margin-right: 10px"
></div>
/>
<p>{{ item.text() }}</p>
<input
class="form-control"
@@ -627,11 +627,11 @@
ng-init="inv.food[item.key] = user.items.food[item.key]"
>
<div class="form-inline clearfix">
<div
<Sprite
class="pull-left"
:class="'Pet_Food_' + item.key"
style="margin-right: 10px"
></div>
/>
<p>{{ item.text() }}</p>
<input
class="form-control"
@@ -690,11 +690,11 @@
ng-if="item.category !== 'world'"
>
<div class="form-inline clearfix">
<div
<Sprite
class="pull-left"
:class="'inventory_quest_scroll_' + item.key"
style="margin-right: 10px"
></div>
/>
<p>{{ item.text() }}</p>
<input
class="form-control"
@@ -730,9 +730,13 @@
import axios from 'axios';
import Content from '@/../../common/script/content';
import Sprite from '@/components/ui/sprite.vue';
import { mapState } from '@/libs/store';
export default {
components: {
Sprite,
},
data () {
const showInv = {};
const inv = {
@@ -107,7 +107,7 @@ export default {
if (lastPublishedPost) this.posts.push(lastPublishedPost);
// If the user is authorized, show any draft
if (this.user && this.user.contributor.newsPoster) {
if (this.user && (this.user.permissions.news || this.user.permissions.fullAccess)) {
this.posts.unshift(
...postsFromServer
.filter(p => !p.published || moment().isBefore(p.publishDate)),
@@ -46,10 +46,10 @@
</div>
<div class="row">
<div class="col-2">
<div
:class="currentMysterySet"
<Sprite
:image-name="currentMysterySet"
class="mt-n1"
></div>
/>
</div>
<div class="col-10">
<h3> {{ $t('monthlyMysteryItems') }} </h3>
@@ -628,6 +628,7 @@ import paymentsMixin from '../../mixins/payments';
import notificationsMixin from '../../mixins/notifications';
import subscriptionOptions from './subscriptionOptions.vue';
import Sprite from '@/components/ui/sprite';
import amazonPayLogo from '@/assets/svg/amazonpay.svg';
import applePayLogo from '@/assets/svg/apple-pay-logo.svg';
@@ -648,6 +649,7 @@ import subscriberHourglasses from '@/assets/svg/subscriber-hourglasses.svg';
export default {
components: {
subscriptionOptions,
Sprite,
},
mixins: [paymentsMixin, notificationsMixin],
data () {
@@ -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);
@@ -712,6 +715,12 @@ export default {
if (this.item.notes instanceof Function) {
return this.item.notes();
}
if (this.item.items) {
if (this.item.items[0].notes instanceof Function) {
return this.item.items[0].notes();
}
return this.item.items[0].notes;
}
return this.item.notes;
},
gemsLeft () {
@@ -109,6 +109,7 @@
</style>
<script>
import find from 'lodash/find';
import shops from '@/../../common/script/libs/shops';
import throttle from 'lodash/throttle';
import { mapState } from '@/libs/store';
@@ -145,9 +146,16 @@ export default {
return Object.values(this.viewOptions).some(g => g.selected);
},
imageURLs () {
const currentEvent = find(this.currentEventList, event => Boolean(event.season));
if (!currentEvent) {
return {
background: 'url(/static/npc/normal/customizations_background.png)',
npc: 'url(/static/npc/normal/customizations_npc.png)',
};
}
return {
background: 'url(/static/npc/normal/customizations_background.png)',
npc: 'url(/static/npc/normal/customizations_npc.png)',
background: `url(/static/npc/${currentEvent.season}/customizations_background.png)`,
npc: `url(/static/npc/${currentEvent.season}/customizations_npc.png)`,
};
},
categories () {
@@ -17,10 +17,10 @@
:emptyItem="emptyItem"
></slot>
<div class="image">
<div
<Sprite
v-once
:class="item.class"
></div>
:image-name="item.class"
/>
<slot
name="itemImage"
:item="item"
@@ -157,9 +157,11 @@
<script>
import { v4 as uuid } from 'uuid';
import Sprite from '@/components/ui/sprite';
export default {
components: {
Sprite,
},
props: {
item: {
@@ -38,26 +38,6 @@
}
</style>
<style>
.key_to_pets {
background-image: url('~@/assets/images/keys/key-to-the-pet-kennels.png');
width: 68px;
height: 68px;
}
.key_to_mounts {
background-image: url('~@/assets/images/keys/key-to-the-mount-kennels.png');
width: 68px;
height: 68px;
}
.key_to_both {
background-image: url('~@/assets/images/keys/keys-to-the-kennels.png');
width: 68px;
height: 68px;
}
</style>
<script>
import { beastCount, mountMasterProgress } from '@/../../common/script/count';
import { mapState } from '@/libs/store';
@@ -28,6 +28,12 @@
:item="item"
:abbreviated="true"
/>
<div
v-if="item.addlNotes"
class="mx-4 mb-3"
>
{{ item.addlNotes }}
</div>
<quest-rewards :quest="item" />
<div
v-if="!item.locked"
@@ -52,12 +58,6 @@
<div class="how-many-to-buy">
<strong>{{ $t('howManyToBuy') }}</strong>
</div>
<div
v-if="item.addlNotes"
class="mb-3"
>
{{ item.addlNotes }}
</div>
<div>
<number-increment
@updateQuantity="selectedAmountToBuy = $event"
@@ -82,7 +82,7 @@
v-if="priceType === 'gems'
&& !enoughCurrency(priceType, item.value * selectedAmountToBuy)
&& !item.locked"
class="btn btn-primary"
class="btn btn-primary mb-3"
@click="purchaseGems()"
>
{{ $t('purchaseGems') }}
@@ -177,7 +177,6 @@
.inner-content {
margin: 33px auto auto;
padding: 0px 24px;
}
.item-notes {
@@ -233,8 +232,6 @@
}
.purchase-amount {
margin-top: 24px;
.how-many-to-buy {
margin-bottom: 16px;
}
@@ -501,38 +498,6 @@ export default {
hideDialog () {
this.$root.$emit('bv::hide::modal', 'buy-quest-modal');
},
getDropIcon (drop) {
switch (drop.type) {
case 'gear':
return `shop_${drop.key}`;
case 'hatchingPotions':
return `Pet_HatchingPotion_${drop.key}`;
case 'food':
return `Pet_Food_${drop.key}`;
case 'eggs':
return `Pet_Egg_${drop.key}`;
case 'quests':
return `inventory_quest_scroll_${drop.key}`;
default:
return '';
}
},
getDropName (drop) {
switch (drop.type) {
case 'gear':
return this.content.gear.flat[drop.key].text();
case 'quests':
return this.content.quests[drop.key].text();
case 'hatchingPotions':
return this.$t('namedHatchingPotion', { type: this.content.hatchingPotions[drop.key].text() });
case 'food':
return this.content.food[drop.key].text();
case 'eggs':
return this.content.eggs[drop.key].text();
default:
return `Unknown type: ${drop.type}`;
}
},
purchaseGems () {
this.$root.$emit('bv::show::modal', 'buy-gems');
},
@@ -19,9 +19,9 @@ export const QuestHelperMixin = {
case 'quests':
return `inventory_quest_scroll_${drop.key}`;
case 'mounts':
return `rewards_mount Mount_Icon_${drop.key}`;
return `Mount_Icon_${drop.key}`;
case 'pets':
return `rewards_pet Pet-${drop.key}`;
return `stable_Pet-${drop.key}`;
default:
return `shop_${drop.key}`;
}
@@ -2,7 +2,7 @@
<div class="quest-content">
<div
class="quest-image"
:class="'quest_' + item.key"
:class="item.purchaseType === 'bundles' ? `quest_bundle_${item.key}` : `quest_${item.key}`"
></div>
<h3 class="text-center">
{{ itemText }}
@@ -17,7 +17,7 @@
<user-label :user="leader" />
</div>
<div
class="text"
class="mx-4"
v-html="itemNotes"
></div>
<questInfo
@@ -42,12 +42,6 @@
margin-top: 24px;
}
.text {
margin: 16px 16px;
overflow-y: auto;
text-overflow: ellipsis;
}
.leader-label {
font-size: 14px;
font-weight: bold;
@@ -1,7 +1,7 @@
<template>
<div>
<div
class="row"
class="row mt-3"
>
<div
v-if="quest.collect"
@@ -25,7 +25,10 @@
<dt>{{ $t('bossHP') + ':' }}</dt>
<dd>{{ quest.boss.hp }}</dd>
</div>
<div class="table-row">
<div
class="table-row"
v-if="quest.purchaseType !== 'bundles'"
>
<dt>{{ $t('difficulty') + ':' }}</dt>
<dd>
<div
@@ -39,7 +42,6 @@
</div>
<div
v-if="quest.end && !abbreviated"
class="m-auto"
>
{{ limitedString }}
</div>
@@ -1,7 +1,7 @@
<template>
<div
v-if="quest.drop"
class="quest-rewards"
class="quest-rewards mb-3"
>
<div
class="header d-flex align-items-center"
@@ -39,7 +39,7 @@
label-class="purple"
>
<div slot="itemImage">
<div :class="getDropIcon(drop)"></div>
<Sprite :image-name="getDropIcon(drop)" />
</div>
<div slot="popoverContent">
<quest-popover :item="drop" />
@@ -92,7 +92,7 @@
:count="drop.amount"
/>
<div slot="itemImage">
<div :class="getDropIcon(drop)"></div>
<Sprite :image-name="getDropIcon(drop)" />
</div>
<div slot="popoverContent">
<equipmentAttributesPopover
@@ -133,6 +133,7 @@ import { QuestHelperMixin } from './quest-helper.mixin';
import EquipmentAttributesPopover from '@/components/inventory/equipment/attributesPopover';
import QuestPopover from './questPopover';
import CountBadge from '../../ui/countBadge';
import Sprite from '../../ui/sprite';
export default {
components: {
@@ -141,6 +142,7 @@ export default {
ItemWithLabel,
SectionButton,
EquipmentAttributesPopover,
Sprite,
},
mixins: [QuestHelperMixin],
props: ['quest'],
@@ -480,7 +480,7 @@ export default {
});
await this.triggerGetWorldState();
this.currentEvent = _find(this.currentEventList, event => Boolean(['winter', 'spring', 'summer', 'fall'].includes(event.season)));
this.currentEvent = _find(this.currentEventList, event => Boolean(event.season));
this.imageURLs.background = `url(/static/npc/${this.currentEvent.season}/seasonal_shop_opened_background.png)`;
this.imageURLs.npc = `url(/static/npc/${this.currentEvent.season}/seasonal_shop_opened_npc.png)`;
},
@@ -41,10 +41,10 @@
class="suggestedDot"
></span>
<div class="image">
<div
<Sprite
v-once
:class="item.class"
></div>
:image-name="item.class"
/>
<slot
name="itemImage"
:item="item"
@@ -281,11 +281,13 @@ import svgClock from '@/assets/svg/clock.svg';
import EquipmentAttributesPopover from '@/components/inventory/equipment/attributesPopover';
import QuestInfo from './quests/questInfo.vue';
import Sprite from '@/components/ui/sprite';
export default {
components: {
EquipmentAttributesPopover,
QuestInfo,
Sprite,
},
props: {
item: {
@@ -8,10 +8,10 @@
v-if="notification.type === 'drop'"
class="icon-item"
>
<div
:class="notification.icon"
<Sprite
:image-name="notification.icon"
class="icon-negative-margin"
></div>
/>
</div>
<div
@@ -231,9 +231,13 @@ import star from '@/assets/svg/star.svg';
import mana from '@/assets/svg/mana.svg';
import sword from '@/assets/svg/sword.svg';
import CloseIcon from '../shared/closeIcon';
import Sprite from '@/components/ui/sprite';
export default {
components: { CloseIcon },
components: {
CloseIcon,
Sprite,
},
props: ['notification', 'visibleAmount'],
data () {
return {
@@ -8,10 +8,10 @@
<div class="spell">
<div class="spell-border">
<div class="mana">
<div
class="img"
:class="`shop_${spell.key} shop-sprite item-img`"
></div>
<Sprite
class="img"
:imageName="`shop_${spell.key}`"
/>
</div>
</div>
<div class="details">
@@ -75,10 +75,9 @@
class="spell"
>
<div class="details">
<div
class="img"
:class="`shop_${skill.key} shop-sprite item-img`"
></div>
<Sprite
:imageName="`shop_${skill.key}`"
/>
</div>
<div
v-if="user.stats.lvl < skill.lvl"
@@ -401,10 +400,12 @@ import {
setLocalSetting,
getLocalSetting,
} from '@/libs/userlocalManager';
import Sprite from '@/components/ui/sprite';
export default {
components: {
Drawer,
Sprite,
},
directives: {
mousePosition: MouseMoveDirective,
@@ -0,0 +1,50 @@
<template>
<img
class="pixel-art"
v-if="imageName && imageName !== ''"
:src="imageUrl()"
>
</template>
<style>
.pixel-art {
image-rendering: pixelated;
}
</style>
<script>
import GIF_SPRITES from '@/../../common/script/content/constants/gifSprites';
export default {
props: {
imageName: {
type: String,
},
prefix: {
type: String,
},
},
methods: {
getFileType (name) {
if (GIF_SPRITES.includes(name)) {
return 'gif';
}
return 'png';
},
imageUrl () {
if (!this.imageName) {
return '';
}
let name = this.imageName;
if (name.indexOf(' ') !== -1) {
const components = name.split(' ');
name = components[components.length - 1];
}
if (this.prefix) {
name = `${this.prefix}_${name}`;
}
return `https://habitica-assets.s3.amazonaws.com/mobileApp/images/${name}.${this.getFileType(name)}`;
},
},
};
</script>
@@ -18,9 +18,9 @@
v-if="label !== 'skip'"
:id="key"
class="gear box"
:class="{white: equippedItems[key] && equippedItems[key].indexOf('base_0') === -1}"
:class="{white: isUsed(equippedItems, key)}"
>
<div :class="`shop_${equippedItems[key]}`"></div>
<Sprite v-if="isUsed(equippedItems, key)" :image-name="`shop_${equippedItems[key]}`"/>
</div>
<b-popover
v-if="label !== 'skip'
@@ -64,9 +64,9 @@
v-if="label !== 'skip'"
:id="key + 'C'"
class="gear box"
:class="{white: costumeItems[key] && costumeItems[key].indexOf('base_0') === -1}"
:class="{white: isUsed(costumeItems, key)}"
>
<div :class="`shop_${costumeItems[key]}`"></div>
<Sprite v-if="isUsed(costumeItems, key)" :image-name="`shop_${costumeItems[key]}`"/>
</div>
<!-- Show background on 8th tile rather than a piece of equipment.-->
<div
@@ -75,7 +75,7 @@
:class="{white: user.preferences.background}"
style="overflow:hidden"
>
<div :class="'icon_background_' + user.preferences.background"></div>
<Sprite :image-name="'icon_background_' + user.preferences.background" />
</div>
<b-popover
v-if="label !== 'skip'
@@ -124,10 +124,10 @@
class="box"
:class="{white: user.items.currentPet}"
>
<div
class="Pet"
:class="`Pet-${user.items.currentPet}`"
></div>
<Sprite
:image-name="user.items.currentPet ?
`stable_Pet-${user.items.currentPet}` : ''"
/>
</div>
</div>
<div class="pet-mount-well-text">
@@ -156,10 +156,10 @@
class="box"
:class="{white: user.items.currentMount}"
>
<div
class="mount"
:class="`Mount_Icon_${user.items.currentMount}`"
></div>
<Sprite
:image-name="user.items.currentMount ?
`stable_Mount_Icon_${user.items.currentMount}` : ''"
/>
</div>
</div>
<div class="pet-mount-well-text">
@@ -330,6 +330,7 @@ import statsComputed from '@/../../common/script/libs/statsComputed';
import { mapState } from '@/libs/store';
import attributesGrid from '@/components/inventory/equipment/attributesGrid';
import toggleSwitch from '@/components/ui/toggleSwitch';
import Sprite from '@/components/ui/sprite';
const DROP_ANIMALS = keys(Content.pets);
const TOTAL_NUMBER_OF_DROP_ANIMALS = DROP_ANIMALS.length;
@@ -337,6 +338,7 @@ export default {
components: {
toggleSwitch,
attributesGrid,
Sprite,
},
props: ['user', 'showAllocation'],
data () {
@@ -417,6 +419,9 @@ export default {
},
methods: {
isUsed (items, key) {
return items[key] && items[key].indexOf('base_0') === -1;
},
getGearTitle (key) {
return this.flatGear[key].text();
},
+1
View File
@@ -37,6 +37,7 @@ export function createAnimal (egg, potion, type, _content, userItems) {
return {
key: animalKey,
class: type === 'pet' ? `Pet Pet-${animalKey}` : `Mount_Icon_${animalKey}`,
imageName: type === 'pet' ? `stable_Pet-${animalKey}` : `stable_Mount_Icon_${animalKey}`,
eggKey: egg.key,
eggName: getText(egg.text),
potionKey: potion.key,
@@ -5,6 +5,7 @@ import unlock from '@/../../common/script/ops/unlock';
import buy from '@/../../common/script/ops/buy/buy';
import appearanceSets from '@/../../common/script/content/appearance/sets';
import appearances from '@/../../common/script/content/appearance';
import { getScheduleMatchingGroup } from '@/../../common/script/content/constants/schedule';
import { userStateMixin } from './userState';
@@ -31,8 +32,11 @@ export const avatarEditorUtilities = { // eslint-disable-line import/prefer-defa
option.key = key;
option.pathKey = pathKey;
option.active = userPreference === key;
option.class = this.createClass(type, subType, key);
option.imageName = this.createImageName(type, subType, key);
option.click = optionParam => (option.gemLocked ? this.unlock(`${optionParam.pathKey}.${key}`) : this.set({ [`preferences.${optionParam.pathKey}`]: optionParam.key }));
option.text = subType ? appearances[type][subType][key].text()
: appearances[type][key].text();
return option;
},
mapKeysToOption (key, type, subType, set) {
@@ -56,8 +60,8 @@ export const avatarEditorUtilities = { // eslint-disable-line import/prefer-defa
return option;
},
createClass (type, subType, key) {
let str = `${type} ${subType} `;
createImageName (type, subType, key) {
let str = '';
switch (type) {
case 'shirt': {
@@ -70,14 +74,14 @@ export const avatarEditorUtilities = { // eslint-disable-line import/prefer-defa
}
case 'hair': {
if (subType === 'color') {
str += `icon_hair_bangs_${this.user.preferences.hair.bangs || 1}_${key}`;
str += `color_hair_bangs_${this.user.preferences.hair.bangs || 1}_${key}`;
} else {
str += `icon_hair_${subType}_${key}_${this.user.preferences.hair.color}`;
str += `hair_${subType}_${key}_${this.user.preferences.hair.color}`;
}
break;
}
case 'skin': {
str += `skin skin_${key}`;
str += `skin_${key}`;
break;
}
default: {
-1
View File
@@ -189,7 +189,6 @@ const router = new VueRouter({
meta: {
privilegeNeeded: [ // any one of these is enough to give access
'userSupport',
'newsPoster',
],
},
children: [
+1 -1
View File
@@ -125,7 +125,7 @@
"paymentSubBillingWithMethod": "Tvé předplatné <strong>$<%= amount %> bude účtováno </strong> každé/CZ <strong><%= months %> měsíce/ů </strong> skrze <strong><%= paymentMethod %></strong>.",
"invalidUnlockSet": "Tento set předmětů je prošlý a nemůže být odemčen.",
"amountExp": "<%= amount %> Zk",
"limitedAvailabilityDays": "K získání na <%= dny %>d <%= hodin%>h <%= minut %>m",
"limitedAvailabilityDays": "K získání na <%= day %>d <%= hours%>h <%= minutes %>m",
"nGemsGift": "<%= nGems %> Drahokamy (Dárek)",
"nMonthsSubscriptionGift": "<%= nMonths %> Měsíční odběr (Dárek)",
"nGems": "<%= nGems %> Drahokamy",
+9 -2
View File
@@ -214,7 +214,7 @@
"backgroundStormyRooftopsNotes": "Schleiche über stürmische Hausdächer.",
"backgroundWindyAutumnText": "Windiger Herbst",
"backgroundWindyAutumnNotes": "Jage Laub an einem windigen Herbsttag.",
"incentiveBackgrounds": "Einfaches Hintergründe-Set",
"incentiveBackgrounds": "Standard Hintergründe",
"backgroundVioletText": "Violett",
"backgroundVioletNotes": "Ein vital-violetter Hintergrund.",
"backgroundBlueText": "Blau",
@@ -871,5 +871,12 @@
"backgroundPottersStudioText": "Töpfer Atelier",
"backgroundPottersStudioNotes": "Erschaffe Kunst im Töpfer Atelier.",
"backgrounds052024": "SET 120: Veröffentlicht im Mai 2024",
"backgroundDragonsBackNotes": "Segle durch den Himmel auf einem Drachenrücken."
"backgroundDragonsBackNotes": "Segle durch den Himmel auf einem Drachenrücken.",
"backgrounds062024": "SET 121: Veröffentlicht im Juni 2024",
"backgroundShellGateText": "Muscheltor",
"backgroundShellGateNotes": "Spaziere durch das korallenverzierte Muscheltor.",
"backgrounds072024": "SET 122: Veröffentlicht im Juli 2024",
"backgroundRiverBottomText": "Flussgrund",
"backgroundRiverBottomNotes": "Erkunde den Grund eines Flusses.",
"monthlyBackgrounds": "Hintergrund des Monats"
}
+6 -1
View File
@@ -189,5 +189,10 @@
"notEnoughGold": "Nicht genügend Gold.",
"chatCastSpellPartyTimes": "<%= username %> verwendet <%= spell %> <%= times %> Male für Deine Party <%= times %>.",
"chatCastSpellUserTimes": "<%= username %> spricht <%= times %> mal <%= spell %> auf <%= target %>.",
"nextReward": "Nächste Anmelde-Belohnung"
"nextReward": "Nächste Anmelde-Belohnung",
"skins": "Hautfarben",
"titleHaircolor": "Haarfarben",
"titleFacialHair": "Bärte",
"titleHairbase": "Frisuren",
"customizations": "Individualisierungen"
}
@@ -8,13 +8,13 @@
"commGuideHeadingInteractions": "Interaktionen in Habitica",
"commGuidePara015": "Habitica hat verschiedene Orte wo du mit anderen Spielern in Kontakt kommen kannst. Darunter sind die Chats (Privatnachrichten oder Party Chats) und außerdem die Möglichkeit nach Parties und Herausforderungen zu suchen.",
"commGuidePara016": "Wenn Du dich durch die sozialen Aspekte von Habitica bewegst, gibt es ein paar allgemeine Regeln, damit jeder sicher und glücklich ist.",
"commGuideList02A": "<strong>Respektiert einander</strong>. Sei höflich, freundlich und hilfsbereit. Vergiss nicht: Habiticaner kommen aus den verschiedensten Hintergründen und haben sehr unterschiedliche Erfahrungen gemacht. Das macht Habitica so eigenartig! Es ist wichtig, dass man beim Aufbauen einer Community seine Unterschiede und Ähnlichkeiten respektieren, aber natürlich auch feiern kann.",
"commGuideList02A": "<strong>Respektiert einander</strong>. Sei höflich, freundlich und hilfsbereit. Vergiss nicht: Habiticaner kommen aus den verschiedensten Hintergründen und haben sehr unterschiedliche Erfahrungen gemacht.",
"commGuideList02B": "<strong>Halte Dich an die <a href='/static/terms' target='_blank'>allgemeinen Geschäftsbedingungen</a></strong>, sowohl in öffentlichen als auch in privaten Bereichen.",
"commGuideList02C": "<strong>Poste keine Bilder oder Texte, die Gewalt darstellen, andere einschüchtern, oder eindeutig/indirekt sexuell sind, die Diskriminierung, Fanatismus, Rassismus, Sexismus, Hass, Belästigungen oder Hetze gegen jedwede Individuen oder Gruppen beinhalten.</strong> Auch nicht als Scherz oder Meme. Das bezieht sowohl Sprüche als auch Stellungnahmen mit ein. Nicht jeder hat den gleichen Humor, etwas, was Du als Witz wahrnimmst, kann für jemand anderen verletzend sein.",
"commGuideList02D": "<strong>Halte die Diskussionen für alle Altersgruppen angemessen</strong>. Das heißt, Erwachsenenthemen in öffentlichen Bereichen zu vermeiden. Viele junge Habiticaner und Menschen mit verschiedenen Hintergründen nutzen diese Seite. Wir wollen unsere Gemeinschaft so angenehm und inklusiv wie möglich gestalten.",
"commGuideList02D": "<strong>Sei dir bewusst, dass Habiticaner Menschen unterschiedlichen Alters und mit verschiedenen Hintergründen sind.</strong> Wettbewerbe und Spielerprofile sollten den Jugendschutz beachten, sowie Schimpfwörter, Streitigkeiten und Konflikte vermeiden.",
"commGuideList02E": "<strong>Vermeide vulgäre Ausdrücke. Dazu gehören auch mildere, religiöse Ausdrücke, die anderswo möglicherweise akzeptiert werden, oder verschleierte Schimpfwörter</strong>. Unter uns sind Menschen aus allen religiösen und kulturellen Hintergründen und wir wollen, dass sich alle im öffentlichen Raum wohl fühlen. <strong>Wenn Dir ein Moderator oder Mitarbeiter mitteilt, dass ein bestimmter Ausdruck in Habitica nicht erlaubt ist, selbst wenn er Dir vielleicht nicht problematisch vorkommt, ist diese Entscheidung endgültig</strong>. Zusätzlich werden verbale Angriffe jeder Art strenge Konsequenzen haben, da sie auch unsere Nutzungsbedingungen verletzen.",
"commGuideList02F": "Vermeide längere Diskussionen über spaltende Themen in der Taverne und wenn sie außerhalb des Themenbereichs liegen. Wenn jemand etwas sagt, das zwar von den Richtlinien her erlaubt ist, das Dich aber verletzt, dann ist es in Ordnung, diese Person höflich darauf hinzuweisen. Wenn Dir eine Person sagt, dass ihr Dein Verhalten unangenehm ist, nimm Dir Zeit, darüber zu reflektieren, anstatt im Zorn zu antworten. Aber wenn Du das Gefühl hast, dass ein Gespräch hitzig, übermäßig emotional, oder verletzend wird, dann <strong>lass dich nicht darauf ein. Melde stattdessen die Beiträge, um uns darüber in Kenntnis zu setzen.</strong> Moderatoren werden so schnell wie möglich antworten. Du kannst auch eine E-Mail an <a href='mailto:admin@habitica.com' target='_blank'>admin@habitica.com</a> senden und gegebenenfalls Screenshots anhängen.",
"commGuideList02G": "<strong>Erfülle alle Mitarbeitenden-Anfragen sofort</strong>. Diese könnten Folgendes beinhalten, ist aber nicht darauf beschränkt: Dich aufzufordern, deine Beiträge in einem bestimmten Bereich zu begrenzen, dein Profil zu bearbeiten, um ungeeignete Inhalte zu entfernen, dich zu bitten, deine Diskussion in einen geeigneteren Bereich zu verschieben, etc. Diskutiere nicht mit Mitarbeitenden. Solltest du mit einer Entscheidung unzufrieden sein, oder anderes Feedback zur Mitarbeitenden haben, sende eine E-mail an <a href='mailto:admin@habitica.com' target='_blank'>admin@habitica.com</a> um unseren Community Manager zu kontaktieren.",
"commGuideList02G": "<strong>Erfülle alle Mitarbeitenden-Anfragen sofort</strong>. Diese könnten Folgendes beinhalten, ist aber nicht darauf beschränkt: Dich aufzufordern, deine Beiträge in einem bestimmten Bereich zu begrenzen, dein Profil zu bearbeiten, um ungeeignete Inhalte zu entfernen, etc. Diskutiere nicht mit Mitarbeitenden. Solltest du mit einer Entscheidung unzufrieden sein, oder anderes Feedback zur Mitarbeitenden haben, sende eine E-mail an <a href='mailto:admin@habitica.com' target='_blank'>admin@habitica.com</a>, um unseren Community Manager zu kontaktieren.",
"commGuideList02J": "<strong>Poste keinen Spam</strong>. Spamming kann Folgendes beinhalten, ist aber nicht beschränkt auf: das Posten desselben Kommentars oder derselben Frage an mehreren Stellen, <strong>das Posten von Links ohne Erklärung oder Kontext</strong>, das Posten unsinniger Nachrichten, das Posten mehrerer Werbebotschaften für eine Gilde, Party, oder Herausforderung, oder das Posten vieler Nachrichten hintereinander. Wenn Du irgendeinen Nutzen daraus ziehst, wenn jemand auf einen Link klickt, musst Du das im Text Deiner Nachricht offenlegen, sonst wird sie auch als Spam betrachtet. Mods können gegebenenfalls nach ihrem Ermessen entscheiden, was Spam ausmacht.",
"commGuideList02K": "<strong>Bitte vermeide große Überschriften in öffentlichen Chats, vor allem in der Taverne.</strong> Ähnlich wie bei GROSSBUCHSTABEN liest sich der Text, als ob Du schreien würdest, und beeinträchtigt die gemütliche Atmosphäre.",
"commGuideList02L": "<strong>Wir raten Dir dringend davon ab, persönliche Informationen - besonders solche, mit denen Du identifiziert werden könntest - in öffentlichen Chats zu teilen.</strong> Zu den identifizierenden Informationen gehören unter anderem: Deine Adresse, Deine E-Mail-Adresse und Dein API-Token/Passwort. Dies dient nur Deiner Sicherheit! Mitarbeiter oder Moderatoren werden solche Beiträge nach eigenem Ermessen entfernen. Wenn Du nach persönlichen Informationen in einer privaten Gilde, Party oder per PN gefragt wirst, empfehlen wir dringend, dass Du höflich ablehnst und Mitarbeiter und Moderatoren informierst, indem Du entweder 1) den Beitrag über das Fähnchen meldest, oder 2) eine E-Mail an <a href='mailto:admin@habitica.com' target='_blank'>admin@habitica.com</a> schreibst und Screenshots anhängst.",
@@ -130,7 +130,7 @@
"commGuideList02M": "Frage nicht nach oder bettle nicht um Edelsteine, Abonnements oder die Mitgliedschaft in Gruppenplänen. Wenn Du ungewollte Nachrichten erhältst, in denen man Dich um bezahlte Artikel fragt, melde sie bitte. Wiederholte Betteleien nach Edelsteinen oder Abonnements, vor allem nachdem bereits eine Warnung ausgesprochen wurde, können zu einer Kontosperre führen.",
"commGuideList09D": "Entfernung oder Herabstufung des Mitwirkenden-Ranges",
"commGuideList05H": "Schwerwiegende oder wiederholte Versuche, andere Spielende zu betrügen oder zu bedrängen, um an Gegenstände zu kommen, die echtes Geld kosten",
"commGuideList02N": "<strong>Markiere und melde Nachrichten, in denen diese Richtlinien oder die Nutzungsbedingungen nicht eingehalten werden.</strong> Wir werden uns so schnell wie möglich darum kümmern. Alternativ kannst du Mitarbeiter:innen über <a href='mailto:admin@habitica.com' target='_blank'>admin@habitica.com</a> benachrichtigen, doch die Markierung ist der schnellste Weg, um Hilfe zu erhalten.",
"commGuideList02N": "<strong>Melde Nachrichten, in denen diese Richtlinien oder die Nutzungsbedingungen nicht eingehalten werden.</strong> Melde eine Nachricht direkt oder informiere Mitarbeiter:innen über <a href='mailto:admin@habitica.com' target='_blank'>admin@habitica.com</a>, um Verstöße in Profilen oder Wettbewerben zu melden. Wir werden uns schnellstmöglich darum kümmern. Kontaktiere uns in deiner Muttersprache, wenn dir das leichter fällt. Es kann sein, dass wir Google Translate nutzen müssen, aber wir wollen, dass du dich sicher fühlst, uns zu kontaktieren, falls bei dir ein Problem auftreten sollte.",
"commGuideList02H": "<strong>Alle Anzeigenamen und @Benutzernamen müssen den Service-Bedingungen entsprechen</strong>. Um deinen Anzeigenamen und/oder @Benutzernamen zu ändern: wähle in der mobilen App Menü > Einstellungen > Account. Auf der Webseite navigierst du über das Benutzer-Icon in der oberen Navigationsleiste.",
"commGuideList02I": "<strong>Namen von Herausforderungen sollten für alle Bereiche angemessen sein, weil sie im öffentlichen Profil der Gewinner erscheinen</strong>. Behalte das in Erinnerung beim Erstellen von Herausforderungen, weil wir gezwungen sein könnten, den Eintrag in ihrem Profil zu ändern, falls es eine Meldung gibt.",
"commGuideList02P": "<strong>Wir raten davon ab, unaufgefordert private Nachrichten zu verschicken</strong>. Wenn du ungewollt eine Nachricht empfängst, die dir unangenehm ist, oder die gegen diese Richtlinien oder die Nutzungsbedingungen verstößt, sperre bitte den Absender und melde sie, um den Mitarbeiterstab darauf aufmerksam zu machen.",
+8 -1
View File
@@ -376,5 +376,12 @@
"hatchingPotionRoseGold": "Rotgold",
"hatchingPotionPinkMarble": "Pink Marmor",
"hatchingPotionTeaShop": "Teeladen",
"hatchingPotionFungi": "Fungus"
"hatchingPotionFungi": "Fungus",
"questEggGiraffeMountText": "Giraffe",
"questEggChameleonText": "Chamäleon",
"questEggChameleonMountText": "Chamäleon",
"hatchingPotionKoi": "Koi",
"questEggGiraffeText": "Giraffe",
"questEggGiraffeAdjective": "eine riesengroße",
"questEggChameleonAdjective": "ein chaotisches"
}
+41 -1
View File
@@ -2885,5 +2885,45 @@
"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.",
"gearItemsCompleted": "Du besitzt alle <%= klass %> Ausrüstungsteile! Neue Ausrüstung wird während den saisonalen Galas veröffentlicht.",
"moreArmoireGearAvailable": "Bis dahin kannst du <%= armoireCount %> Ausrüstungsteile im Verzauberten Schrank finden!",
"moreArmoireGearComing": "Der Verzauberte Schrank bekommt jeden Monat neuen Vorrat!",
"weaponSpecialSummer2024RogueText": "Nacktkiemerschnecke Dreizack",
"weaponSpecialSummer2024RogueNotes": "Wende die scharfen Stacheln anderer gegen sie selbst! Erhöht Stärke um <%= str %>. Limitierte Ausgabe 2024 Sommerausrüstung.",
"weaponSpecialSummer2024WarriorText": "Walhai-Zahn Schneider",
"weaponSpecialSummer2024WarriorNotes": "Einige ausgefallene Haizähne verwandeln dies in eine Waffe, die aus jeder Richtung Schaden verursachen kann. Erhöht Stärke um <%= str %>. Limitierte Ausgabe 2024 Sommerausrüstung.",
"weaponSpecialSummer2024HealerText": "Meeresschnecken Stab",
"weaponSpecialSummer2024MageText": "Seeanemonen Zauberstab",
"weaponSpecialSummer2024MageNotes": "Diese grandiosen Tentakel können Magie gleichzeitig abhalten, ablenken und steuern. Erhöht Intelligenz um <%= int %> und Wahrnehmung um <%= per %>. Limitierte Ausgabe 2024 Sommerausrüstung.",
"weaponSpecialSummer2024HealerNotes": "Du wirst erstaunt sein zu entdecken, wie hart die Muschel am Ende des Stabs ist. Erhöht Intelligenz um <%= int %>. Limitierte Ausgabe 2024 Sommerausrüstung.",
"weaponArmoireCorsairsBladeNotes": "Ob du sie zum Plündern oder zum Schutz trägst - du kannst froh sein, daß du diese grimmige Klinge mit dir zur See gebracht hast. Achte nur darauf, daß sie sicher verstaut ist, wenn nicht in Benutzung. Erhöht Stärke um <%= str %>. Verzauberter Schrank: Korsaren Set (Gegenstand 3 von 3)",
"weaponArmoireCorsairsBladeText": "Korsarenklinge",
"armorSpecialFall2023MageText": "Scharlachrote Hexenmeister Robe",
"armorSpecialFall2023MageNotes": "Mit scharlachrotem Garn und goldenen Akzenten ist dieses Outfit ein Wunder für die Sinne. Erhöht Intelligenz um <%= int %>. Limitierte Ausgabe 2023 Herbstausrüstung.",
"weaponArmoireRollingPinText": "Wellholz",
"weaponArmoireRollingPinNotes": "Rolle deinen Teig zwischendrin so dünn wie du möchtest, während du schlechte Gewohnheiten auf den Kopf haust, sobald sie um dich herum aufploppen, wie bei einem gewissen Nagetier-Kloppen Spiel. Erhöht Stärke um <%= str %>. Verzauberter Schrank: Küchenwerkzeugset 2 (Gegenstand 2 von 2).",
"armorSpecialFall2023HealerText": "Sumpfkreatur-Body",
"armorSpecialFall2023HealerNotes": "Mit Moos, Fels, Holz und Sumpfwasser reingemischt, ist dieses Outfit manchmal tough und manchmal schwammig (aber immer einschüchternd). Erhöht Ausdauer um <%= con %>. Limitierte Ausgabe 2023 Herbstausrüstung.",
"armorSpecialWinter2024RogueText": "Verschneite Eulen Roben",
"armorSpecialWinter2024RogueNotes": "Wuuuuu wer wirst du sein, wenn du diese Roben trägst? In Federn und Flaum gehüllt, wirst du sowohl warm als auch getarnt sein! Erhöht Wahrnehmung um <%= per %>. Limitierte Ausgabe 2023-2024 Winterausrüstung.",
"armorSpecialWinter2024WarriorNotes": "Es stellt sich heraus, daß Schokolade, Pfefferminz und Zuckerguß stabilere Materialien sind, als man denkt. Erhöht Ausdauer um <%= con %>. Limitierte Ausgabe 2023-2024 Winterausrüstung.",
"armorSpecialWinter2024WarriorText": "Pfefferminz Plätzchen Rüstung",
"armorSpecialWinter2024MageNotes": "Sowohl praktisch als auch hübsch, werden diese Roben dich angenehm warm halten, während du deine magischen Fähigkeiten draußen in der Kälte ausübst. Erhöht Intelligenz um <%= int %>. Limitierte Ausgabe 2023-2024 Winterausrüstung.",
"armorSpecialWinter2024MageText": "Narwal Zauberer Roben",
"armorSpecialWinter2024HealerText": "Gefrorene Rüstung",
"armorSpecialWinter2024HealerNotes": "Dieser glitzernde Block aus magischem Eis ist zumindest schützend, während du deine Flucht ausknobelst. Erhöht Ausdauer um <%= con %>. Limitierte Ausgabe 2023-2024 Winterausrüstung.",
"armorSpecialSpring2024RogueNotes": "Diese rustikale Robe verbirgt dich, sogar wenn die Jahreszeiten rings um dich herum wechseln. Erhöht Wahrnehmung um <%= per %>. Limitierte Ausgabe 2024 Frühlingsausrüstung.",
"armorSpecialSpring2024RogueText": "Schmelzende Schnee Robe",
"armorSpecialSpring2024WarriorText": "Fluorit Rüstung",
"armorSpecialSpring2024WarriorNotes": "Diese stabilisierende Steinrüstung wird helfen, dich zu erden, während du alles blendest, dem du entgegentrittst. Erhöht Ausdauer um <%= con %>. Limitierte Ausgabe 2024 Frühlingsausrüstung.",
"armorSpecialSpring2024MageText": "Hibiskus Roben",
"armorSpecialSpring2024MageNotes": "Diese hübschen Blüten werden dir helfen, stilvoll mit deinen Kräften zu posieren. Erhöht Intelligenz um <%= int %>. Limitierte Ausgabe 2024 Frühlingsausrüstung.",
"headSpecialSpring2024HealerText": "Blaukehlchen Helm",
"armorSpecialSpring2024HealerNotes": "Diese fabelhaften Federn werden helfen, deinen glücklichsten Träumen Flügel zu verleihen. Erhöht Ausdauer um <%= con %>. Limitierte Ausgabe 2024 Frühlingsausrüstung.",
"armorSpecialSummer2024RogueText": "Nacktkiemerschnecken-Schwanz",
"armorSpecialSummer2024RogueNotes": "Du magst vielleicht eine Seeschnecke ohne Schneckenhaus sein, aber du bist eine Seeschnecke mit See-Schwingen! Erhöht Wahrnehmung um <%= per %>. Limitierte Ausgabe 2024 Sommerausrüstung.",
"armorSpecialSpring2024HealerText": "Blaukehlchen Anzug"
}
+2 -1
View File
@@ -238,5 +238,6 @@
"viewAdminPanel": "Admin Panel anzeigen",
"mutePlayer": "Stumm",
"skipExternalLinkModal": "Halte STRG (Windows) oder Command (Mac) beim Anklicken eines Links, um dieses Modal zu überspringen.",
"shadowMute": "Unsichtbare Stummschaltung"
"shadowMute": "Unsichtbare Stummschaltung",
"titleCustomizations": "Individualisierungen"
}
+29 -29
View File
@@ -1,8 +1,8 @@
{
"tavern": "Tavernen-Chat",
"tavernChat": "Tavernen-Chat",
"innCheckOutBanner": "Du bist derzeit im Gasthaus eingecheckt. Deine Tagesaufgaben können Dir nicht schaden und Du erzielst keinen Fortschritt bei Deinen Quests.",
"innCheckOutBannerShort": "Du bist im Gasthaus eingecheckt.",
"innCheckOutBanner": "Du hast derzeit Schaden pausiert. Deine Tagesaufgaben können Dir nicht schaden und Du erzielst keinen Fortschritt bei Deinen Quests.",
"innCheckOutBannerShort": "Du hast Schaden derzeit pausiert.",
"resumeDamage": "Schaden fortsetzen",
"helpfulLinks": "Weiterführende Links",
"communityGuidelinesLink": "Community-Richtlinien",
@@ -20,7 +20,7 @@
"dataTool": "Werkzeug zur Datenanzeige",
"resources": "Ressourcen",
"communityGuidelines": "Community-Richtlinien",
"bannedWordUsed": "Hoppla! Es sieht so aus, als würde dieser Beitrag ein Schimpfwort enthalten, oder sich auf Suchtstoffe oder nicht-jugendfreie Themen beziehen (<%= swearWordsUsed %>). Habitica achtet darauf, unsere Chats frei von diesen Dingen zu halten. Du kannst Deine Nachricht gerne überarbeiten und sie wieder posten! Die betroffenen Wörter musst Du allerdings löschen, nicht einfach zensieren.",
"bannedWordUsed": "Hoppla! Es sieht so aus, als würde dieser Beitrag ein Schimpfwort enthalten, oder sich auf Suchtstoffe oder nicht-jugendfreie Themen beziehen (<%= swearWordsUsed %>). Habitica achtet darauf, unsere Chats frei von diesen Dingen zu halten. Du kannst Deine Nachricht gerne überarbeiten und sie wieder posten! Die betroffenen Wörter musst Du allerdings löschen, nicht einfach nur zensieren.",
"bannedSlurUsed": "Dein Beitrag enthielt unangebrachte Inhalte, daher wurden Dir Deine Chat-Privilegien entzogen.",
"party": "Party",
"usernameCopied": "Benutzername in die Zwischenablage kopiert.",
@@ -30,8 +30,8 @@
"invite": "Einladen",
"leave": "Verlassen",
"invitedToParty": "Du wurdest in die Party <span class=\"notification-bold\"><%- party %></span> eingeladen",
"invitedToPrivateGuild": "Du wurdest eingeladen, der privaten Gilde <span class=\"notification-bold\"><%- guild %></span> beizutreten",
"invitedToPublicGuild": "Du wurdest eingeladen, der Gilde <span class=\"notification-bold-blue\"><%- guild %></span> beizutreten",
"invitedToPrivateGuild": "Du wurdest eingeladen, der privaten Gruppe<span class=\"notification-bold\"><%- guild %></span> beizutreten",
"invitedToPublicGuild": "Du wurdest eingeladen, der Gruppe<span class=\"notification-bold-blue\"><%- guild %></span> beizutreten",
"invitationAcceptedHeader": "Deine Einladung wurde angenommen",
"invitationAcceptedBody": "<%= username %> hat Deine Einladung zu <%= groupName %> angenommen!",
"systemMessage": "Systemmeldung",
@@ -57,7 +57,7 @@
"createGuild2": "Erstellen",
"guild": "Gilde",
"guilds": "Gilden",
"sureKick": "Willst Du dieses Mitglied wirklich aus der Party/Gilde entfernen?",
"sureKick": "Willst Du dieses Mitglied wirklich aus der Party oder Gruppe entfernen?",
"optionalMessage": "Optionale Nachricht",
"yesRemove": "Ja, entferne sie",
"sortBackground": "Nach Hintergrund sortieren",
@@ -85,9 +85,9 @@
"PMDisabledOptPopoverText": "Private Nachrichten sind deaktiviert. Aktiviere diese Option, damit andere User Dich über Dein Profil erreichen können.",
"PMDisabledCaptionTitle": "Private Nachrichten sind deaktiviert",
"PMDisabledCaptionText": "Du kannst weiterhin Nachrichten versenden, aber Dir können keine zugeschickt werden.",
"block": "Sperren",
"unblock": "Entsperren",
"blockWarning": "Sperre - Dies hat keine Auswirkung, wenn der Spieler jetzt Moderator ist oder in Zukunft Moderator wird.",
"block": "Spieler sperren",
"unblock": "Spieler entsperren",
"blockWarning": "Dies hat keine Auswirkung, wenn der Spieler ein Administrator ist.",
"inbox": "Postfach",
"messageRequired": "Eine Nachricht wird benötigt.",
"toUserIDRequired": "Eine Benutzer-ID wird benötigt",
@@ -98,10 +98,10 @@
"badAmountOfGemsToSend": "Die Menge muss zwischen 1 und Deiner aktuellen Edelsteinanzahl liegen.",
"report": "Melden",
"abuseFlagModalHeading": "Melde einen Verstoß",
"abuseFlagModalBody": "Möchtest Du diesen Beitrag wirklich melden? Du solltest <strong>ausschließlich</strong> Beiträge melden, die unsere <%= firstLinkStart %>Community-Richtlinien<%= linkEnd %> und/oder unsere <%= secondLinkStart %>Nutzungsbedingungen<%= linkEnd %> verletzen. Das ungerechtfertigte Melden von Beiträgen stellt eine Verletzung der Community-Richtlinien dar und kann geahndet werden.",
"abuseFlagModalBody": "Du solltest <strong>ausschließlich</strong> Beiträge melden, die unsere <%= firstLinkStart %>Community-Richtlinien<%= linkEnd %> und/oder unsere <%= secondLinkStart %>Nutzungsbedingungen<%= linkEnd %> verletzen. Das ungerechtfertigte Melden von Beiträgen stellt eine Verletzung der Community-Richtlinien dar.",
"abuseReported": "Danke, dass Du diesen Verstoß gemeldet hast. Die Moderatoren wurden benachrichtigt.",
"whyReportingPost": "Wieso meldest Du diesen Post?",
"whyReportingPostPlaceholder": "Bitte hilf unseren Moderatoren und gib einen Grund an, warum Du diesen Beitrag als Verstoß gemeldet hast, z.B. Spam, Fluchen, Religiöse Schwüre, Intoleranz, Beleidigungen, Nicht jugendfreie Themen, Gewalt.",
"whyReportingPostPlaceholder": "Grund für die Beschwerde",
"optional": "Optional",
"needsTextPlaceholder": "Gib Deine Nachricht hier ein.",
"copyMessageAsToDo": "Nachricht als To-Do übernehmen",
@@ -126,7 +126,7 @@
"sendGiftMessagePlaceholder": "Füge eine Geschenknachricht hinzu",
"sendGiftSubscription": "<%= months %> Monat(e): $<%= price %> USD",
"gemGiftsAreOptional": "Bitte nimm zur Kenntnis, dass Habitica niemals von Dir verlangen wird, anderen Spielern Edelsteine zu schenken. Bei anderen Spielern um Edelsteine zu betteln ist ein <strong>Verstoss gegen die Community-Richtlinien</strong>, und jedes Vorkommnis sollte bei <%= hrefTechAssistanceEmail %> gemeldet werden.",
"battleWithFriends": "Besiege mit Freunden Monster",
"battleWithFriends": "Spiele Habitica zusammen mit anderen",
"startAParty": "Erstelle eine Party",
"partyUpName": "Party!",
"partyOnName": "Riesenparty!",
@@ -221,42 +221,42 @@
"badAmountOfGemsToPurchase": "Die Anzahl muss mindestens 1 sein.",
"groupPolicyCannotGetGems": "Die Regeln einer Gruppe in der Du Mitglied bist verhindern, dass die Gruppenmitglieder Edelsteine erhalten.",
"viewParty": "Party ansehen",
"newGuildPlaceholder": "Gib den Namen Deiner Gilde ein.",
"guildBank": "Gildenbankkonto",
"chatPlaceholder": "Füge die Botschaft an Gildenmitglieder hier ein",
"newGuildPlaceholder": "Gib den Namen deiner Gruppe ein.",
"guildBank": "Bankkonto",
"chatPlaceholder": "Füge die Botschaft an Gruppenmitglieder hier ein",
"partyChatPlaceholder": "Füge die Botschaft an Partymitglieder hier ein",
"fetchRecentMessages": "Neue Nachrichten abrufen",
"like": "Like",
"liked": "Liked",
"inviteToGuild": "In Gilde einladen",
"inviteToGuild": "In Gruppe einladen",
"inviteToParty": "In die Party einladen",
"inviteEmailUsername": "Via E-Mail oder Benutzernamen einladen",
"inviteEmailUsernameInfo": "Einladung von Benutzern über eine gültige E-Mailadresse oder Benutzernamen. Wenn eine E-Mail noch nicht registriert ist, werden wir sie einladen, beizutreten.",
"emailOrUsernameInvite": "E-Mailadresse oder Benutzername",
"messageGuildLeader": "Gildenleiter benachrichtigen",
"messageGuildLeader": "Gruppenleiter benachrichtigen",
"donateGems": "Edelsteine spenden",
"updateGuild": "Gilde aktualisieren",
"updateGuild": "Gruppe aktualisieren",
"viewMembers": "Mitglieder ansehen",
"memberCount": "Anzahl Mitglieder",
"recentActivity": "Kürzliche Aktivitäten",
"myGuilds": "Meine Gilden",
"guildsDiscovery": "Gilden entdecken",
"role": "Rolle",
"guildLeader": "Gildenleiter",
"guildLeader": "Gruppenleiter",
"member": "Mitglied",
"guildSize": "Gildengröße",
"guildSize": "Gruppengröße",
"goldTier": "Gold",
"silverTier": "Silber",
"bronzeTier": "Bronze",
"privacySettings": "Datenschutzeinstellungen",
"onlyLeaderCreatesChallenges": "Nur der Leiter kann Herausforderungen erstellen",
"onlyLeaderCreatesChallengesDetail": "Wenn diese Option ausgewählt ist, können gewöhnliche Gruppenmitglieder keine Herausforderungen für die Gruppe erstellen.",
"privateGuild": "Private Gilde",
"privateGuild": "Private Gruppe",
"charactersRemaining": "<%= characters %> Zeichen übrig",
"guildSummary": "Zusammenfassung",
"guildSummaryPlaceholder": "Schreibe eine Kurzbeschreibung um Deine Gilde anderen Habiticanern bekannt zu machen. Was ist der Hauptzweck der Gilde und warum sollten Leute ihr beitreten? Verwende hilfreiche Schlüsselwörter in der Beschreibung, um die Suche für andere Habiticaner zu erleichtern!",
"guildSummaryPlaceholder": "Schreibe eine Kurzbeschreibung über deine Gruppe.. Was ist der Hauptzweck der Gruppe und was werden die Gruppenmitglieder tun?",
"groupDescription": "Beschreibung",
"guildDescriptionPlaceholder": "Nutze diesen Abschnitt um alles, was Mitglieder der Gilde über Deine Gilde wissen sollten, ausführlicher darzustellen. Nützliche Tipps, hilfreiche Links und ermutigende Worte gehören hier hin!",
"guildDescriptionPlaceholder": "Nutze diesen Abschnitt um alles, was Mitglieder über Deine Gruppe wissen sollten, ausführlicher darzustellen. Nützliche Tipps, hilfreiche Links und ermutigende Worte gehören hier hin!",
"markdownFormattingHelp": "[Markdown Formatierungshilfe](https://habitica.fandom.com/wiki/Markdown_Cheat_Sheet)",
"partyDescriptionPlaceholder": "Das ist unsere Partybeschreibung. Sie beschreibt, was wir in unserer Party so tun. Wenn Du mehr darüber wissen willst, was wir in unserer Party so machen, lies die Beschreibung. Party on!",
"guildGemCostInfo": "Eine Edelstein-Gebühr fördert die Qualität der Gilden und wird der Gildenbank gutgeschrieben.",
@@ -265,7 +265,7 @@
"noGuildsParagraph2": "Klicke auf den \"Gilden entdecken\"-Reiter, um basierend auf Deinen Interessen empfohlene Gilden zu sehen, stöbere durch Habiticas öffentliche Gilden, oder erstelle Deine eigene Gilde.",
"noGuildsMatchFilters": "Wir haben keine passenden Gilden gefunden.",
"privateDescription": "Private Gilden werden nicht in Habiticas Gildenübersicht angezeigt. Neue Mitglieder können nur durch eine Einladung hinzugefügt werden.",
"removeInvite": "Einladung entfernen",
"removeInvite": "Einladung löschen",
"removeMember": "Mitglied entfernen",
"sendMessage": "Nachricht senden",
"promoteToLeader": "Gruppenleitung übertragen",
@@ -353,7 +353,7 @@
"PMCanNotReply": "Du kannst auf diese Nachricht nicht antworten",
"PMUnblockUserToSendMessages": "Entblocke diese Person, um wieder Nachrichten versenden und empfangen zu können.",
"PMUserDoesNotReceiveMessages": "Diese Person empfängt keine privaten Nachrichten mehr",
"newPartyPlaceholder": "Gib den Namen Deiner Party ein.",
"newPartyPlaceholder": "Gib den Namen deiner Party ein.",
"chooseTeamMember": "Wähle ein Teammitglied",
"unassigned": "Nicht zugewiesen",
"claimRewards": "Belohnung einfordern",
@@ -362,7 +362,7 @@
"managerNotes": "Manager-Notizen",
"thisTaskApproved": "Dieser Aufgabe wurde zugestimmt",
"onlyPrivateGuildsCanUpgrade": "Nur bei privaten Gilden kann ein Upgrade zu einem Gruppenplan durchgeführt werden.",
"bannedWordsAllowedDetail": "Durch Auswahl dieser Option, wird das Verwenden verbotener Wörter in dieser Gilde zugelassen.",
"bannedWordsAllowedDetail": "Durch Auswahl dieser Option, wird das Verwenden verbotener Wörter in dieser Gruppe zugelassen.",
"bannedWordsAllowed": "Verbotene Wörter zulassen",
"languageSettings": "Spracheinstellungen",
"cannotRemoveQuestOwner": "Du kannst die Person, welche die aktive Quest besitzt, nicht entfernen. Breche erst die Quest ab.",
@@ -372,11 +372,11 @@
"blockYourself": "Du kannst Dich nicht selbst blockieren",
"invitedToThisQuest": "Du wurdest zu dieser Quest eingeladen!",
"messagePartyLeader": "Partyleitung benachrichtigen",
"joinGuild": "Gilde beitreten",
"joinGuild": "Gruppe beitreten",
"joinParty": "Party beitreten",
"editGuild": "Gilde bearbeiten",
"editGuild": "Gruppe bearbeiten",
"editParty": "Party bearbeiten",
"leaveGuild": "Gilde verlassen",
"leaveGuild": "Gruppe verlassen",
"viewDetails": "Details ansehen",
"upgradeToGroup": "Auf Gruppenplan upgraden",
"sendGiftTotal": "Insgesamt:",
+18 -14
View File
@@ -130,7 +130,7 @@
"winter2019PyrotechnicSet": "Pyrotechniker (Magier)",
"winter2019WinterStarSet": "Winterstern (Heiler)",
"winter2019PoinsettiaSet": "Weihnachtsstern (Schurke)",
"winterPromoGiftHeader": "VERSCHENK EIN ABO, BEKOMME EINS UMSONST!",
"winterPromoGiftHeader": "VERSCHENK EIN ABO, BEKOMME EINS UMSONST!",
"winterPromoGiftDetails1": "Nur bis zum 6. Januar: wenn Du jemandem ein Abonnement schenkst, erhältst Du das gleiche Abonnement gratis für Dich!",
"winterPromoGiftDetails2": "Bitte bedenke, dass das geschenkte Abonnement, falls Du oder Deine beschenkte Person bereits über ein sich wiederholendes Abonnement verfügen, erst dann startet, wenn das alte Abonnement gekündigt wird oder ausläuft. Herzlichen Dank für Deine Unterstützung! <3",
"discountBundle": "Paket",
@@ -144,22 +144,22 @@
"summer2019WaterLilyMageSet": "Seerose (Magier)",
"summer2019ConchHealerSet": "Trompetenschnecke (Heiler)",
"summer2019HammerheadRogueSet": "Hammerkopf (Schurke)",
"june2018": "Juni 2018",
"june2018": "Juni 2018",
"fall2019LichSet": "Lich (Heiler)",
"september2018": "September 2018",
"september2017": "September 2017",
"fall2019RavenSet": "Rabe (Krieger)",
"fall2019CyclopsSet": "Zyklop (Magier)",
"fall2019OperaticSpecterSet": "Opernhaftes Gespenst (Schurke)",
"winter2020LanternSet": "Laterne (Schurke)",
"winter2020LanternSet": "Laterne (Schurke)",
"winter2020WinterSpiceSet": "Wintergewürz (Heiler)",
"winter2020CarolOfTheMageSet": "Weihnachtslied des Magiers (Magier)",
"winter2020EvergreenSet": "Immergrün (Krieger)",
"spring2020BeetleWarriorSet": "Nashornkäfer (Krieger)",
"spring2020LapisLazuliRogueSet": "Lapislazuli (Schurke)",
"spring2020BeetleWarriorSet": "Nashornkäfer (Krieger)",
"spring2020LapisLazuliRogueSet": "Lapislazuli (Schurke)",
"spring2020IrisHealerSet": "Iris (Heiler)",
"spring2020PuddleMageSet": "Pfütze (Magier)",
"summer2020CrocodileRogueSet": "Krokodil (Schurke)",
"summer2020CrocodileRogueSet": "Krokodil (Schurke)",
"summer2020SeaGlassHealerSet": "Meerglas (Heiler)",
"summer2020OarfishMageSet": "Riemenfisch (Magier)",
"summer2020RainbowTroutWarriorSet": "Regenbogenforelle (Krieger)",
@@ -167,8 +167,8 @@
"fall2020ThirdEyeMageSet": "Drittes Auge (Magier)",
"fall2020DeathsHeadMothHealerSet": "Totenkopfschwärmer (Heiler)",
"fall2020WraithWarriorSet": "Gespenst (Krieger)",
"royalPurpleJackolantern": "Purpurne Kürbislaterne",
"g1g1Limitations": "Dies ist eine zeitlich beschränkte Aktion, die am 16. Dezember um 13:00 Uhr (GMT) startet und am 6. Januar um 01:00 Nachts (GMT) endet. Dieses Angebot ist nur gültig, wenn Du einen anderen Habiticaner beschenkst. Wenn Du oder die beschenkte Person bereits ein Abo haben, wird dieses, sobald es abläuft oder gekündigt wird, um die Zeit des Geschenkes verlängert werden.",
"royalPurpleJackolantern": "Purpurne Kürbislaterne",
"g1g1Limitations": "Dies ist eine zeitlich beschränkte Aktion, die am 16. Dezember um 13:00 Uhr (GMT) startet und am 6. Januar um 01:00 Nachts (GMT) endet. Dieses Angebot ist nur gültig, wenn Du einen anderen Habiticaner beschenkst. Wenn Du oder die beschenkte Person bereits ein Abo haben, wird dieses, sobald es abläuft oder gekündigt wird, um die Zeit des Geschenkes verlängert werden.",
"limitations": "Einschränkungen",
"g1g1HowItWorks": "Gebe den Benutzernamen ein, welchem Du das Geschenk machen willst. Dann wähle die Länge des Abos, das Du verschenken möchtest und schließe den Vorgang ab. Dein Account wird automatisch mit dem selben Abo belohnt, das Du gerade verschenkt hast.",
"howItWorks": "So funktioniert es",
@@ -196,15 +196,15 @@
"winter2022StockingWarriorSet": "Strumpf (Krieger)",
"winter2022IceCrystalHealerSet": "Eiskristall (Heiler)",
"winter2022PomegranateMageSet": "Granatapfel (Magier)",
"spring2022MagpieRogueSet": "Elster (Schurke)",
"spring2022MagpieRogueSet": "Elster (Schurke)",
"spring2022RainstormWarriorSet": "Gewitterregen (Krieger)",
"spring2022ForsythiaMageSet": "Forsythie (Magier)",
"spring2022PeridotHealerSet": "Abendsmaragd (Heiler)",
"summer2022WaterspoutWarriorSet": "Wasserspeier (Krieger)",
"summer2022WaterspoutWarriorSet": "Wasserspeier (Krieger)",
"summer2022AngelfishHealerSet": "Kaiserfisch (Heiler)",
"summer2022CrabRogueSet": "Krabbe (Schurke)",
"summer2022CrabRogueSet": "Krabbe (Schurke)",
"summer2022MantaRayMageSet": "Mantarochen (Magier)",
"fall2022KappaRogueSet": "Kappa (Schurke)",
"fall2022KappaRogueSet": "Kappa (Schurke)",
"fall2022OrcWarriorSet": "Ork (Krieger)",
"fall2022HarpyMageSet": "Harpyie (Magier)",
"fall2022WatcherHealerSet": "Beobachter (Heiler)",
@@ -213,7 +213,7 @@
"winter2023WalrusWarriorSet": "Walross (Krieger)",
"winter2023FairyLightsMageSet": "Feenlichter (Magier)",
"winter2023CardinalHealerSet": "Kardinal (Heiler)",
"anniversaryLimitedDates": "30. Januar bis 8. Februar",
"anniversaryLimitedDates": "30. Januar bis 8. Februar",
"limitedEvent": "Limitiertes Event",
"winter2023RibbonRogueSet": "Schleife (Schurke)",
"spring2024MeltingSnowRogueSet": "Schmelzendes Schnee Set (Schurke)",
@@ -261,5 +261,9 @@
"fourForFreeText": "Um die Party am Laufen zu halten, verschenken wir Party Gewänder, 20 Edelsteine, und eine limitierte Geburtstags-Hintergrund Ausgabe und ein Gegenstände Set, das ein Cape, ein Schulterstück und eine Augenmaske enthält.",
"partyRobes": "Party Gewänder",
"twentyGems": "20 Edelsteine",
"dayOne": "Tag 1"
"dayOne": "Tag 1",
"summer2024WhaleSharkWarriorSet": "Walhai Set (Krieger)",
"summer2024SeaAnemoneMageSet": "Seeanemonen Set (Magier)",
"summer2024SeaSnailHealerSet": "Meeresschnecken Set (Heiler)",
"summer2024NudibranchRogueSet": "Nacktkiemerschnecken Set (Schurke)"
}
+3 -1
View File
@@ -135,5 +135,7 @@
"helpSupportHabitica": "Hilf Habitica zu unterstützen",
"groupsPaymentSubBilling": "Dein nächstes Rechnungsdatum ist <strong><%= renewalDate %></strong>.",
"groupsPaymentAutoRenew": "Dieses Abonnement läuft automatisch weiter, bis es gekündigt wird. Du kannst es im Gruppen-Abrechnungs-Tab kündigen.",
"sellItems": "Items verkaufen"
"sellItems": "Items verkaufen",
"customizationsShopText": "Willst du deinen Style ändern? Hier bist du richtig! Wir haben die frischesten Looks, passend zur Saison, auf Lager.",
"notAvailable": "Dieser Gegenstand ist nicht verfügbar."
}
+2 -1
View File
@@ -115,5 +115,6 @@
"notEnoughFood": "Du hast nicht genug Futter",
"invalidAmount": "Ungültige Menge Futter, positiver Integer benötigt",
"jubilantGryphatrice": "Jubelnder Greifatrice",
"veteranDragon": "Veterandrache"
"veteranDragon": "Veterandrache",
"veteranCactus": "Veterankaktus"
}
+7 -1
View File
@@ -772,5 +772,11 @@
"questFungiDropFungiPotion": "Pilz Schlüpfelixier",
"questFungiUnlockText": "Schaltet den Kauf von Pilz Schlüpfelixieren auf dem Marktplatz frei.",
"questFungiNotes": "Es war ein verregneter Frühling in Habitica und der Boden um die Ställe ist schwammig und feucht. Du bemerkst, dass einige Pilze entlang den hölzernen Stallwänden und Zäunen aufgetaucht sind. Nebel hängt in der Luft, der die Sonne nicht so richtig durchscheinen lässt, und es fühlt sich ein wenig entmutigend an.<br><br>Durch den Nebel siehst du die Umrisse des April-Scherzkekses, der nicht so hüpfig ist wie sonst.<br><br>\"Ich hatte gehofft, euch allen ein paar köstliche Magische Pilz Schlüpfelixiere zu bringen, so dass ihr eure Pilzfreunde für immer von meinem Ehrentag fernhalten könnt,\" sagt er mit einem bedenklich ernsten Gesichtsausdruck. \"Aber dieser kalte Nebel macht mir echt zu schaffen, er lässt mich zu müde und trübselig fühlen, um meine gewohnte Magie zu wirken.\"<br><br>\"Oh nein, tut mir leid, das zu hören,\" sagst du, und bemerkst deine eigene, zunehmend düstere Stimmung. \"Dieser Nebel macht den Tag wirklich bedrückend. Ich frage mich, woher er kommt...\"<br><br>Ein tiefes Grollen ertönt über die Felder, und du siehst einen Umriss aus dem Nebel erscheinen. Erschrocken siehst du eine riesengroß und unglücklich aussehende Pilzkreatur, von welcher der Nebel auszuströmen scheint.<br><br>\"Aha,\" sagt der Scherzkeks, \"ich denke, dieser pilzige Kerl könnte der Ursprung unserer Niedergeschlagenheit sein. Lasst uns schauen, ob wir ein bisschen Freude für unseren Freund hier und für uns selbst herbeirufen können.\"",
"questFungiCompletion": "Du und der April-Scherzkeks schaut einander mit einem Ausdruck der Erleichterung an, als sich der Pilz in den Wald zurückzieht.<br><br>\"Ah,\" ruft der Scherzkeks aus, \"das war eine wahre myzelische Melancholie. Ich bin froh, daß wir seine Laune verbessern konnten, und unsere eigene auch! Ich spüre meine Energie zurückkehren. Komm mit mir, und wir bringen zusammen diese Pilz Elixiere auf die Beine.\""
"questFungiCompletion": "Du und der April-Scherzkeks schaut einander mit einem Ausdruck der Erleichterung an, als sich der Pilz in den Wald zurückzieht.<br><br>\"Ah,\" ruft der Scherzkeks aus, \"das war eine wahre myzelische Melancholie. Ich bin froh, daß wir seine Laune verbessern konnten, und unsere eigene auch! Ich spüre meine Energie zurückkehren. Komm mit mir, und wir bringen zusammen diese Pilz Elixiere auf die Beine.\"",
"QuestGiraffeUnlockText": "Schält Giraffe Ei zum Kauf im Marktplatz frei.",
"questChameleonText": "Das chaotische Chamäleon",
"questChameleonBoss": "Chaotisches Chamäleon",
"questChameleonDropChameleonEgg": "Chamäleon (Ei)",
"QuestChameleonUnlockText": "Schält Chamäleon Eier zum Kauf im Marktplatz frei",
"questGiraffeDropGiraffeEgg": "Giraffe (Ei)"
}
+2 -1
View File
@@ -240,5 +240,6 @@
"mysterySet202303": "Mähniges Hauptfigur Set",
"mysterySet202403": "Glückliches Legenden Set",
"mysterySet202405": "Vergoldetes Drachen Set",
"mysterySet202406": "Phantom-Seeräuber Set"
"mysterySet202406": "Phantom-Seeräuber Set",
"mysterySet202407": "Liebenswertes Axolotl Set"
}
@@ -983,6 +983,14 @@
"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.",
"backgrounds082024": "SET 123: Released August 2024",
"backgroundSavannaText": "Hazy Grasslands",
"backgroundSavannaNotes": "Hike through Hazy Grasslands.",
"timeTravelBackgrounds": "Steampunk Backgrounds",
"backgroundAirshipText": "Airship",
"backgroundAirshipNotes": "Become a sky sailor on board your very own Airship.",
+8
View File
@@ -255,6 +255,14 @@
"questEggGiraffeMountText": "Giraffe",
"questEggGiraffeAdjective": "a towering",
"questEggChameleonText": "Chameleon",
"questEggChameleonMountText": "Chameleon",
"questEggChameleonAdjective": "a chaotic",
"questEggCrabText": "Crab",
"questEggCrabMountText": "Crab",
"questEggCrabAdjective": "a fiddling",
"eggNotes": "Find a hatching potion to pour on this egg, and it will hatch into <%= eggAdjective(locale) %> <%= eggText(locale) %>.",
"hatchingPotionBase": "Base",
+39 -10
View File
@@ -3,25 +3,35 @@
"2b43f6": "Blue",
"6bd049": "Green",
"800ed0": "Purple",
"98461a": "Skin Tone 6",
"915533": "Skin Tone 1",
"98461a": "Skin Tone 6",
"allCustomizationsOwned": "You own all of these items. You can try them on by <a href=''>customizing your avatar</a>.",
"allEquipmentOwned": "You own all of these items. You can find them in your <a href='/inventory/equipment'>Equipment</a>. Be sure to check back later for next month's options!",
"aurora": "Aurora",
"bear": "Bear",
"black": "Black",
"blond": "Blond",
"blue": "Blue",
"blueEarrings": "Blue Earrings",
"blueFlower": "Blue Flower",
"blunt": "Blunt",
"braid": "Braid",
"broad": "Broad",
"brown": "Brown",
"c06534": "Skin Tone 5",
"c3e1dc": "Cyan",
"cactus": "Cactus",
"candycane": "Candy Cane",
"candycorn": "Candy Corn",
"checkNextMonth": "Be sure to check back later for next month's options!",
"checkNextSeason": "Be sure to check back later for next season's options!",
"clownfish": "Clownfish",
"convict": "Referee",
"cross": "Cross",
"curly": "Curly",
"curlyLong": "Curly Long",
"curlyShort": "Curly Short",
"customizationsNPC": "Felicitus Fennec",
"d7a9f7": "Lavender",
"dapper": "Dapper",
"ddc994": "Skin Tone 2",
@@ -43,18 +53,31 @@
"ghost": "Ghost",
"ghostwhite": "Ghost White",
"goatee": "Goatee",
"goldEarringLeft": "Gold Earring Left",
"goldEarringRight": "Gold Earring Right",
"goldEarrings": "Gold Earrings",
"green": "Green",
"greenEarrings": "Green Earrings",
"greenFlower": "Green Flower",
"halloween": "Halloween",
"handleless_black": "Black Handleless",
"handleless_blue": "Blue Handleless",
"handleless_green": "Green Handleless",
"handleless_pink": "Pink Handleless",
"handleless_red": "Red Handleless",
"handleless_yellow": "Yellow Handleless",
"highPonytailLeft": "High Ponytail Left",
"highPonytailRight": "High Ponytail Right",
"holly": "Holly",
"hollygreen": "Holly Green",
"hoopEarrings": "Hoop Earrings",
"horizon": "Horizon",
"largeMustache": "Large Mustache",
"lava": "Lava",
"leftBun": "Left Bun",
"lion": "Lion",
"longBeard": "Long Beard",
"lookingForMore": "Looking for more?",
"merblue": "Merblue",
"mergold": "Mergold",
"mergreen": "Mergreen",
@@ -63,8 +86,10 @@
"midnight": "Midnight",
"mohawk": "Mohawk",
"monster": "Monster",
"noItemsOwned": "You don't own any of these items",
"ocean": "Ocean",
"ogre": "Ogre",
"orangeFlower": "Orange Flower",
"orchid": "Orchid",
"panda": "Panda",
"pastelBlue": "Pastel Blue",
@@ -81,6 +106,9 @@
"pgreen": "Special Pastel Green",
"pgreen2": "Pastel Green",
"pig": "Pig",
"pink": "Pink",
"pinkEarrings": "Pink Earrings",
"pinkFlower": "Pink Flower",
"polar": "Polar",
"ponytail": "Ponytail",
"porange": "Special Pastel Orange",
@@ -92,11 +120,14 @@
"pumpkin": "Pumpkin",
"pumpkin2": "Jack O' Lantern",
"purple": "Purple",
"purpleEarrings": "Purple Earrings",
"purpleFlower": "Purple Flower",
"pyellow": "Special Pastel Yellow",
"pyellow2": "Pastel Yellow",
"rainbow": "Rainbow",
"red": "Red",
"redblue": "Red and Blue",
"redEarrings": "Red Earrings",
"reptile": "Reptile",
"rightBun": "Right Bun",
"sandnsea": "Sand 'n' Sea",
@@ -105,8 +136,10 @@
"shadow2": "Shade",
"shark": "Shark",
"shortBeard": "Short Beard",
"sideswept": "Sideswept",
"skeleton": "Skeleton",
"skeleton2": "Bones",
"slim": "Slim",
"smallMustache": "Small Mustache",
"snowy": "Snowy",
"straightLong": "Straight Long",
@@ -121,21 +154,17 @@
"tropicalwater": "Tropical Water",
"TRUred": "Crimson",
"updo": "Updo",
"visitCustomizationsShop": "Head over to the <a href='/shops/customizations'>Customizations Shop</a> to browse the many ways you can customize your avatar!",
"wavyLong": "Wavy Long",
"wavyShort": "Wavy Short",
"white": "White",
"whiteEarrings": "White Earrings",
"winternight": "Winter Night",
"winterstar": "Winter Star",
"wispy": "Wispy",
"wolf": "Wolf",
"yellow": "Yellow",
"yellowFlower": "Yellow Flower",
"zombie": "Zombie",
"zombie2": "Undead",
"allCustomizationsOwned": "You own all of these items. You can try them on by <a href=''>customizing your avatar</a>.",
"checkNextMonth": "Be sure to check back later for next month's options!",
"checkNextSeason": "Be sure to check back later for next season's options!",
"noItemsOwned": "You don't own any of these items",
"visitCustomizationsShop": "Head over to the <a href='/shops/customizations'>Customizations Shop</a> to browse the many ways you can customize your avatar!",
"lookingForMore": "Looking for more?",
"allEquipmentOwned": "You own all of these items. You can find them in your <a href='/inventory/equipment'>Equipment</a>. Be sure to check back later for next month's options!",
"customizationsNPC": "Felicitus Fennec"
"zombie2": "Undead"
}
+20
View File
@@ -562,6 +562,8 @@
"weaponMystery202403Notes": "Carrying the biggest sword around is surely a way to create your own luck! Confers no benefit. March 2024 Subscriber Item.",
"weaponMystery202404Text": "Mycelial Magus Staff",
"weaponMystery202404Notes": "This staff will bestow upon you an ancient wisdom as ageless as the rocks and trees. Confers no benefit. April 2024 Subscriber Item.",
"weaponMystery202408Text": "Arcane Aegis",
"weaponMystery202408Notes": "A magic bubble shield that protects you from enemy spells or helps you float in the air or water. Confers no benefit. August 2024 Subscriber Item.",
"weaponMystery301404Text": "Steampunk Cane",
"weaponMystery301404Notes": "Excellent for taking a turn about town. March 3015 Subscriber Item. Confers no benefit.",
@@ -770,6 +772,10 @@
"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)",
"weaponArmoireDragonKnightsLanceText": "Dragon Knight Lance",
"weaponArmoireDragonKnightsLanceNotes": "This red and silver lance has unseated many opponents from their mounts. Increases Constitution by <%= con %>. Enchanted Armoire: Dragon Knight Set (Item 3 of 3)",
"armor": "armor",
"armorCapitalized": "Armor",
@@ -1400,6 +1406,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 +1624,10 @@
"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)",
"armorArmoireDragonKnightsArmorText": "Dragon Knight Armor",
"armorArmoireDragonKnightsArmorNotes": "Channel the strength and power of a dragon with this armor made of silver and shed scales. Increases Strength by <%= str %>. Enchanted Armoire: Dragon Knight Set (Item 2 of 3)",
"headgear": "helm",
"headgearCapitalized": "Headgear",
@@ -2279,6 +2291,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 +2489,10 @@
"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)",
"headArmoireDragonKnightsHelmText": "Dragon Knight Helm",
"headArmoireDragonKnightsHelmNotes": "With the fiery features on this helmet, dragons might mistake you for one of their own. Increases Intelligence by <%= int %>. Enchanted Armoire: Dragon Knight Set (Item 1 of 3)",
"offhand": "off-hand item",
"offHandCapitalized": "Off-Hand Item",
@@ -2773,6 +2791,8 @@
"shieldMystery202011Notes": "Harness the power of the autumn wind with this staff. Use for arcane magic or to make awesome leaf piles, the choice is yours! Confers no benefit. November 2020 Subscriber Item.",
"shieldMystery202209Text": "Mound o' Magic Books",
"shieldMystery202209Notes": "Building your sorcery knowledge takes a lot of reading, but you're sure to enjoy your education. Confers no benefit. September 2022 Subscriber Item.",
"shieldMystery202408Text": "Arcane Sparkles",
"shieldMystery202408Notes": "Magic lights will illuminate the inside of your bubble hideout, or anywhere else you need a little light! Confers no benefit. August 2024 Subscriber Item.",
"shieldMystery301405Text": "Clock Shield",
"shieldMystery301405Notes": "Time is on your side with this towering clock shield! Confers no benefit. June 3015 Subscriber Item.",
"shieldMystery301704Text": "Fluttery Fan",
+35 -19
View File
@@ -576,7 +576,7 @@
"questMayhemMistiflying3DropWeapon": "Roguish Rainbow Message (Main-Hand Item)",
"featheredFriendsText": "Feathered Friends Quest Bundle",
"featheredFriendsNotes": "Contains 'Help! Harpy!', 'The Night-Owl', and 'The Birds of Preycrastination'.",
"featheredFriendsNotes": "Contains Quests to obtain Owl, Parrot, and Hawk Pet eggs: The Night-Owl, Help! Harpy!, and The Birds of Preycrastination.",
"questNudibranchText": "Infestation of the NowDo Nudibranchs",
"questNudibranchNotes": "You finally get around to checking your To Do's on a lazy day in Habitica. Bright against your deepest red tasks are a gaggle of vibrant blue sea slugs. You are entranced! Their sapphire colors make your most intimidating tasks look as easy as your best Habits. In a feverish stupor you get to work, tackling one task after the other in a ceaseless frenzy...<br><br>The next thing you know, @LilithofAlfheim is pouring cold water over you. “The NowDo Nudibranchs have been stinging you all over! You need to take a break!”<br><br>Shocked, you see that your skin is as bright red as your To Do list was. \"Being productive is one thing,\" @beffymaroo says, \"but you've also got to take care of yourself. Hurry, let's get rid of them!\"",
@@ -586,7 +586,7 @@
"questNudibranchUnlockText": "Unlocks Nudibranch Eggs for purchase in the Market",
"splashyPalsText": "Splashy Pals Quest Bundle",
"splashyPalsNotes": "Contains 'The Dilatory Derby', 'Guide the Turtle', and 'Wail of the Whale'.",
"splashyPalsNotes": "Contains Quests to obtain Turtle, Whale, and Seahorse Pet eggs: Guide the Turtle, Wail of the Whale, and The Dilatory Derby.",
"questHippoText": "What a Hippo-Crite",
"questHippoNotes": "You and @awesomekitty collapse into the shade of a palm tree, exhausted. The sun beats down over the Sloensteadi Savannah, scorching the ground below. Its been a productive day so far, conquering your Dailies, and this oasis looks like a nice place to take a break and refresh. Stooping near the water to get a drink, you stumble back in shock as a massive hippopotamus rises. “Resting so soon? Dont be so lazy, get back to work.” You try and protest that youve been working hard and need a break, but the hippo isnt having any of it.<br><br>@khdarkwolf whispers to you, “Notice how its lounging around all day but has the nerve to call you lazy? Its the Hippo-Crite!”<br><br>Your friend @jumorales nods. “Lets show it what hard work looks like!”",
@@ -596,10 +596,10 @@
"questHippoUnlockText": "Unlocks Hippo Eggs for purchase in the Market",
"farmFriendsText": "Farm Friends Quest Bundle",
"farmFriendsNotes": "Contains 'The Mootant Cow', 'Ride the Night-Mare', and 'The Thunder Ram'.",
"farmFriendsNotes": "Contains Quests to obtain Horse, Sheep, and Cow Pet eggs: Ride the Night-Mare, The Thunder Ram, and The Mootant Cow.",
"witchyFamiliarsText": "Witchy Familiars Quest Bundle",
"witchyFamiliarsNotes": "Contains 'The Rat King', 'The Icy Arachnid', and 'Swamp of the Clutter Frog'.",
"witchyFamiliarsNotes": "Contains Quests to obtain Frog, Spider, and Rat Pet eggs: Swamp of the Clutter Frog, The Icy Arachnid, and The Rat King.",
"questGroupLostMasterclasser": "Mystery of the Masterclassers",
"questUnlockLostMasterclasser": "To unlock this quest, complete the final quests of these quest chains: 'Dilatory Distress', 'Mayhem in Mistiflying', 'Stoïkalm Calamity', and 'Terror in the Taskwoods'.",
@@ -650,7 +650,7 @@
"questYarnUnlockText": "Unlocks Yarn Eggs for purchase in the Market",
"winterQuestsText": "Winter Quest Bundle",
"winterQuestsNotes": "Contains 'Trapper Santa', 'Find the Cub', and 'The Fowl Frost'. Note that Trapper Santa and Find the Cub have stackable quest achievements but give a rare pet and mount that can only be obtained once each.",
"winterQuestsNotes": "Contains Quests to obtain the Polar Bear Pet, the Polar Bear Mount, and Penguin Pet eggs: Find the Cub, Trapper Santa, and The Fowl Frost.",
"questPterodactylText": "The Pterror-dactyl",
"questPterodactylNotes": "You're taking a stroll along the peaceful Stoïkalm Cliffs when an evil screech rends the air. You turn to find a hideous creature flying towards you and are overcome by a powerful terror. As you turn to flee, @Lilith of Alfheim grabs you. \"Don't panic! It's just a Pterror-dactyl.\"<br><br>@Procyon P nods. \"They nest nearby, but they're attracted to the scent of negative Habits and undone Dailies.\"<br><br>\"Don't worry,\" @Katy133 says. \"We just need to be extra productive to defeat it!\" You are filled with a renewed sense of purpose and turn to face your foe.",
@@ -689,7 +689,7 @@
"dysheartenerArtCredit": "Artwork by @AnnDeLune",
"hugabugText": "Hug a Bug Quest Bundle",
"hugabugNotes": "Contains 'The CRITICAL BUG', 'The Snail of Drudgery Sludge', and 'Bye, Bye, Butterfry'.",
"hugabugNotes": "Contains Quests to obtain Beetle, Caterpillar, and Snail Pet eggs: The CRITICAL BUG, Bye Bye Butterfry, and The Snail of Drudgery Sludge.",
"questSquirrelText": "The Sneaky Squirrel",
"questSquirrelNotes": "You wake up and find youve overslept! Why didnt your alarm go off? … How did an acorn get stuck in the ringer?<br><br>When you try to make breakfast, the toaster is stuffed with acorns. When you go to retrieve your mount, @Shtut is there, trying unsuccessfully to unlock their stable. They look into the keyhole. “Is that an acorn in there?”<br><br>@randomdaisy cries out, “Oh no! I knew my pet squirrels had gotten out, but I didnt know theyd made such trouble! Can you help me round them up before they make any more of a mess?”<br><br>Following the trail of mischievously placed oak nuts, you track and catch the wayward sciurines, with @Cantras helping secure each one safely at home. But just when you think your task is almost complete, an acorn bounces off your helm! You look up to see a mighty beast of a squirrel, crouched in defense of a prodigious pile of seeds.<br><br>“Oh dear,” says @randomdaisy, softly. “Shes always been something of a resource guarder. Well have to proceed very carefully!” You circle up with your party, ready for trouble!",
@@ -699,10 +699,10 @@
"questSquirrelUnlockText": "Unlocks Squirrel Eggs for purchase in the Market",
"cuddleBuddiesText": "Cuddle Buddies Quest Bundle",
"cuddleBuddiesNotes": "Contains 'The Killer Bunny', 'The Nefarious Ferret', and 'The Guinea Pig Gang'.",
"cuddleBuddiesNotes": "Contains Quests to obtain Rabbit, Ferret, and Guinea Pig Pet eggs: The Killer Bunny, The Nefarious Ferret, and The Guinea Pig Gang.",
"aquaticAmigosText": "Aquatic Amigos Quest Bundle",
"aquaticAmigosNotes": "Contains 'The Magical Axolotl', 'The Kraken of Inkomplete', and 'The Call of Octothulu'.",
"aquaticAmigosNotes": "Contains Quests to obtain Cuttlefish, Octopus, and Axolotl Pet eggs: The Kraken of Inkomplete, The Call of Octothulu, and The Magical Axolotl.",
"questSeaSerpentText": "Danger in the Depths: Sea Serpent Strike!",
"questSeaSerpentNotes": "Your streaks have you feeling lucky—its the perfect time for a trip to the seahorse racetrack. You board the submarine at Diligent Docks and settle in for the trip to Dilatory, but youve barely submerged when an impact rocks the sub, sending its occupants tumbling. “Whats going on?” @AriesFaries shouts.<br><br>You glance through a nearby porthole and are shocked by the wall of shimmering scales passing by it. “Sea serpent!” Captain @Witticaster calls through the intercom. “Brace yourselves, its coming round again!” As you grip the arms of your seat, your unfinished tasks flash before your eyes. Maybe if we work together and complete them, you think, we can drive this monster away!",
@@ -719,7 +719,7 @@
"questKangarooUnlockText": "Unlocks Kangaroo Eggs for purchase in the Market",
"forestFriendsText": "Forest Friends Quest Bundle",
"forestFriendsNotes": "Contains 'The Spirit of Spring', 'The Hedgebeast', and 'The Tangle Tree'.",
"forestFriendsNotes": "Contains Quests to obtain Treeling, Deer, and Hedgehog Pet eggs: The Tangle Tree, The Spirit of Spring, and The Hedgebeast.",
"questAlligatorText": "The Insta-Gator",
"questAlligatorNotes": "“Crikey!” exclaims @gully. “An Insta-Gator in its natural habitat! Careful, it distracts its prey with things that seem urgent THIS INSTANT, and it feeds on the unchecked Dailies that result.” You fall silent to avoid attracting its attention, but to no avail. The Insta-Gator spots you and charges! Distracting voices rise up from Swamps of Stagnation, grabbing for your attention: “Read this post! See this photo! Pay attention to me THIS INSTANT!” You scramble to mount a counterattack, completing your Dailies and bolstering your good Habits to fight off the dreaded Insta-Gator.",
@@ -729,10 +729,10 @@
"questAlligatorUnlockText": "Unlocks Alligator Eggs for purchase in the Market",
"oddballsText": "Oddballs Quest Bundle",
"oddballsNotes": "Contains 'The Jelly Regent', 'Escape the Cave Creature', and 'A Tangled Yarn'.",
"oddballsNotes": "Contains Quests to obtain Slime, Yarn, and Rock Pet eggs: The Jelly Regent, A Tangled Yarn, and Escape the Cave Creature.",
"birdBuddiesText": "Bird Buddies Quest Bundle",
"birdBuddiesNotes": "Contains 'The Fowl Frost', 'Rooster Rampage', and 'The Push-and-Pull Peacock'.",
"birdBuddiesNotes": "Contains Quests to obtain Peacock, Penguin, and Rooster Pet eggs: The Push-and-Pull Peacock, The Fowl Frost, and Rooster Rampage.",
"questVelociraptorText": "The Veloci-Rapper",
"questVelociraptorNotes": "Youre sharing honey cakes with @*~Seraphina~*, @Procyon P, and @Lilith of Alfheim by a lake in the Stoïkalm Steppes. Suddenly, a mournful voice interrupts your picnic.<br><br><em>My Habits took a hit, I missed my Dailies,<br>Im losing it, sinking with doubt and maybes,<br>At the top of my game I used to be so fly,<br>But now I just let my Due Dates go by.</em><br><br>@*~Seraphina~* peers behind a stand of grass. “Its the Veloci-Rapper. It seems... distraught?”<br><br>You pump a fist in determination. “There's only one thing to do. Rap battle time!”",
@@ -742,7 +742,7 @@
"questVelociraptorUnlockText": "Unlocks Velociraptor Eggs for purchase in the Market",
"mythicalMarvelsText": "Mythical Marvels Quest Bundle",
"mythicalMarvelsNotes": "Contains 'Convincing the Unicorn Queen', 'The Fiery Gryphon', and 'Danger in the Depths: Sea Serpent Strike!'",
"mythicalMarvelsNotes": "Contains Quests to obtain Unicorn, Gryphon, and Sea Serpent Pet eggs: Convincing the Unicorn Queen, The Fiery Gryphon, and Danger in the Depths: Sea Serpent Strike!",
"questBronzeText": "Brazen Beetle Battle",
"questBronzeNotes": "On a refreshing break between tasks, you and some friends take a stroll through the forest trails of the Taskwoods. You come upon a large hollow log and a sparkle from inside catches your attention.<br><br>Why, it's a cache of Magic Hatching Potions! The shimmering bronze liquid swirls gently in the bottles, and @Hachiseiko reaches to pick one up to examine it.<br><br>“Halt!” hisses a voice from behind you. It's a gigantic beetle with a carapace of gleaming bronze, raising her clawed feet in a fighting stance. “Those are my potions, and if you wish to earn them, you must prove yourself in a gentlefolks' duel!”",
@@ -777,10 +777,10 @@
"questRobotUnlockText": "Unlocks purchasable Robot Eggs in the Market",
"rockingReptilesText": "Rocking Reptiles Quest Bundle",
"rockingReptilesNotes": "Contains 'The Insta-Gator', 'The Serpent of Distraction', and 'The Veloci-Rapper'.",
"rockingReptilesNotes": "Contains Quests to obtain Alligator, Velociraptor, and Snake Pet eggs: The Insta-Gator, The Veloci-Rapper, and The Serpent of Distraction.",
"delightfulDinosText": "Delightful Dinos Quest Bundle",
"delightfulDinosNotes": "Contains 'The Pterror-dactyl', 'The Trampling Triceratops', and 'The Dinosaur Unearthed'.",
"delightfulDinosNotes": "Contains Quests to obtain Triceratops, T-Rex, and Pterodactyl Pet eggs: The Trampling Triceratops, The Dinosaur Unearthed, and The Pterror-dactyl.",
"questAmberText": "The Amber Alliance",
"questAmberNotes": "Youre sitting in the Tavern with @beffymaroo and @-Tyr- when @Vikte bursts through the door and excitedly tells you about the rumors of another type of Magic Hatching Potion hidden in the Taskwoods. Having completed your Dailies, the three of you immediately agree to help @Vikte on their search. After all, whats the harm in a little adventure?<br><br>After walking through the Taskwoods for hours, youre beginning to regret joining such a wild chase. Youre about to head home, when you hear a surprised yelp and turn to see a huge lizard with shiny amber scales coiled around a tree, clutching @Vikte in her claws. @beffymaroo reaches for her sword.<br><br>“Wait!” cries @-Tyr-. “Its the Trerezin! Shes not dangerous, just dangerously clingy!”",
@@ -809,7 +809,7 @@
"questWaffleUnlockText": "Unlocks Confection Hatching Potions for purchase in the Market",
"jungleBuddiesText": "Jungle Buddies Quest Bundle",
"jungleBuddiesNotes": "Contains 'Monstrous Mandrill and the Mischief Monkeys', 'The Somnolent Sloth', and 'The Tangle Tree'.",
"jungleBuddiesNotes": "Contains Quests to obtain Monkey, Treeling, and Sloth Pet eggs: Monstrous Mandrill and the Mischief Monkeys, The Tangle Tree, and The Somnolent Sloth.",
"questFluoriteText": "A Bright Fluorite Fright",
"questFluoriteNotes": "Unusual minerals are in high demand these days, so you and a few friends have trekked deep into the mines of the Meandering Mountains, in search of exciting ores. Its a long and boring expedition, until @-Tyr- stumbles over a large rock, sitting right in the middle of the tunnel.<br><br>“This should help brighten things up,” says @nirbhao, before conjuring up an orb of light.<br><br>A warm brightness fills the tunnel, but something odd starts happening to that large rock. Feeding on the magical light, it begins to glow with fluorescent blues, greens and purples. Then it rears upright into a vaguely humanoid shape, complete with glowing red eyes fixed right on you! You jump into action with flashing spells and shining weapons.",
@@ -835,7 +835,7 @@
"questTurquoiseUnlockText": "Unlocks Turquoise Hatching Potions for purchase in the Market",
"sandySidekicksText": "Sandy Sidekicks Quest Bundle",
"sandySidekicksNotes": "Contains 'The Indulgent Armadillo', 'The Serpent of Distraction', and 'The Icy Arachnid'.",
"sandySidekicksNotes": "Contains Quests to obtain Spider, Armadillo, and Snake Pet eggs: The Icy Arachnid, The Indulgent Armadillo, and The Serpent of Distraction.",
"questBlackPearlText": "A Startling Starry Idea",
"questBlackPearlNotes": "Youve been feeling uninspired lately, so when @jjgame83 suggests a trip to Lively Lake, you jump at the chance for a change of scenery. As @QuartzFox lays out a picnic on the shore, you find something glinting in the shallows. A strange black pearl.<br><br>“I wish I had a new idea,” you sigh.<br><br>A chill washes over the shore. The lake turns to black ink. The stars rise as noon becomes midnight in a heartbeat.<br><br>“Those arent good signs,” says @PixelStormArt.<br><br>A towering mass of arms bursts from the lake in a spray of foam, and from its beak, it booms: “BEHOLD ASTEROIDEA, THE IDEA FROM BEYOND THE STARS!”<br><br>A tentacle slams down onto the picnic basket. Good idea or not, you leap into action.",
@@ -887,15 +887,31 @@
"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",
"QuestPinkMarbleUnlockText": "Unlocks Pink Marble Hatching Potions for purchase in the Market.",
"questPinkMarbleUnlockText": "Unlocks Pink Marble Hatching Potions for purchase in the Market.",
"questGiraffeText": "The Gear-affe",
"questGiraffeNotes": "Youre strolling across the tall grass of the Sloenstedi Savannah, enjoying a nice walk in nature as a break from your tasks. As you pass through the rolling landscape, you notice a collection of items in the distance. Its a pile of musical instruments, art supplies, electronic equipment, and more! You venture near for a better look.<br><br>“Hey, what do you think youre doing?” yells a voice from behind an acacia. A tall and imposing giraffe emerges, wearing a fancy pair of shades. a guitar, and a fancy camera around its long neck. “This is all my gear, be careful and dont touch anything!”<br><br>You notice dust on many of the items. “Wow, you sure have a lot of hobbies!” you say. “Can you show me some art or play me a tune?”<br><br>The giraffes face falls as he looks at all his supplies. “I have so much of this stuff but dont know where to begin! Why don't you give me some of your motivation so I can have the productive energy I need to finally get started!”",
"questGiraffeCompletion": "After helping the Gear-Affe with some basic organization of his stash, youre both feeling more energized and upbeat!<br><br>He grabs his guitar and a book of beginner exercises and strums a few notes. “It feels good to take a step in the right direction, even a small one. Thanks for helping me out! Take these, I hear you have a stash of pets and these fellas could be a nice addition!”",
"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.",
"questGiraffeUnlockText": "Unlocks Giraffe Eggs 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",
"questCrabText": "The Fiddling Crab",
"questCrabNotes": "Its a warm sunny morning, and youre enjoying a visit to the beach to catch up on some of the books on your summer reading list. Youre startled when you nearly step on a shiny crystal near a shallow hole in the sand.<br><br>“Ey, watch where youre goin! Im makin a burrow here!” says a voice. A surprisingly large crab with a decorative shell runs out in front of your toes, snapping her claw as she speaks.<br><br>“Hm, is this a burrow?” you ask, looking at the shallow depression. There are shells and crystals arranged around it, but its not much in the way of a hiding place.<br><br>The crab stammers. \"Ey, this is a judgment free zone! I'm gettin' to it, I'm gettin' to it... I just got caught up on decorating. Sometimes a crab's gotta fiddle,\" she says, adjusting a shell.<br><br>\"Why don't you lend a claw and help if you've got some big ideas on what a burrow should look like?\"",
"questCrabCompletion": "You and the crab figure out how to work together to get everything in just the right place, ending up with a fine sandy burrow. The crab happily nestles in.<br><br>\"Thank ya!\" she says, making herself comfy. \"Now this is a hole that's made just for me. I can finally enjoy all my perfectly placed decorations. Here, take these lil guys as a token of my appreciation. It's an offer you can't refuse!\"",
"questCrabBoss": "Fiddling Crab",
"questCrabRageTitle": "Distracting Fiddling",
"questCrabRageDescription": "This bar fills when you don't complete your Dailies. When it's full, the Fiddling Crab will take away some of your party's MP!",
"questCrabRageEffect": "The Fiddling Crab distracts you with decorating, slowing your work on digging and draining some of your magic. The party's MP is reduced!",
"questCrabDropCrabEgg": "Crab (Egg)",
"questCrabUnlockText": "Unlocks Crab 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.”",

Some files were not shown because too many files have changed in this diff Show More