diff --git a/website/client/src/assets/css/sprites/spritesmith-main.css b/website/client/src/assets/css/sprites/spritesmith-main.css
index 7d4af98323..e1bef2613a 100644
--- a/website/client/src/assets/css/sprites/spritesmith-main.css
+++ b/website/client/src/assets/css/sprites/spritesmith-main.css
@@ -37687,6 +37687,11 @@
width: 221px;
height: 213px;
}
+.quest_fungi {
+ background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/quest_fungi.png');
+ width: 219px;
+ height: 219px;
+}
.quest_ghost_stag {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/quest_ghost_stag.png');
width: 219px;
@@ -38392,6 +38397,11 @@
width: 68px;
height: 68px;
}
+.inventory_quest_scroll_fungi {
+ background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/inventory_quest_scroll_fungi.png');
+ width: 68px;
+ height: 68px;
+}
.inventory_quest_scroll_ghost_stag {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/inventory_quest_scroll_ghost_stag.png');
width: 68px;
@@ -60807,6 +60817,11 @@
width: 68px;
height: 68px;
}
+.Pet_HatchingPotion_Fungi {
+ background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/Pet_HatchingPotion_Fungi.png');
+ width: 68px;
+ height: 68px;
+}
.Pet_HatchingPotion_Ghost {
background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/Pet_HatchingPotion_Ghost.png');
width: 68px;
diff --git a/website/common/locales/en/content.json b/website/common/locales/en/content.json
index e7a32b4b88..4c93a5b871 100644
--- a/website/common/locales/en/content.json
+++ b/website/common/locales/en/content.json
@@ -313,6 +313,7 @@
"hatchingPotionPinkMarble": "Pink Marble",
"hatchingPotionTeaShop": "Tea Shop",
"hatchingPotionRoseGold": "Rose Gold",
+ "hatchingPotionFungi": "Fungi",
"hatchingPotionNotes": "Pour this on an egg, and it will hatch as a <%= potText(locale) %> pet.",
"premiumPotionAddlNotes": "Not usable on quest pet eggs. Available for purchase until <%= date(locale) %>.",
diff --git a/website/common/locales/en/questsContent.json b/website/common/locales/en/questsContent.json
index fcdc727cd5..7456cdfae1 100644
--- a/website/common/locales/en/questsContent.json
+++ b/website/common/locales/en/questsContent.json
@@ -887,5 +887,15 @@
"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.",
+
+ "questFungiText": "The Moody Mushroom",
+ "questFungiNotes": "It’s 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. There’s a fog hanging about, not quite letting the sun peek through, and it’s a bit dispiriting.
Out of the mist you see the outline of the April Fool, not at all his usual bouncy self.
”I’d 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, it’s making me feel too tired and dismal to work my usual magic.”
“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…”
A low rumble sounds across the fields, and you see an outline emerging from the mist. You’re alarmed to see a gigantic and unhappy looking mushroom creature, and the mist appears to be emanating from it.
“Aha,” says the Fool, “I think this fungal fellow may be the source of our blues. Let’s see if we can summon a little cheer for our friend here and ourselves.”",
+ "questFungiCompletion": "You and the April Fool look at each other with a sign of relief as the mushroom retreats to the forest.
“Ah,” the Fool exclaims, “that was quite a mycelial melancholy. I’m glad we could improve his mood, and ours too! I feel my energy coming back. Come with me and we’ll get those Fungi potions going together.”",
+ "questFungiBoss": "Moody Mushroom",
+ "questFungiRageTitle": "Moody Mushroom Mist",
+ "questFungiRageDescription": "This bar fills when you don't complete your Dailies. When it's full, the Moody Mushroom will take away some of your party's pending damage",
+ "questFungiRageEffect": "A Mist emanates from the Moody Mushroom and surrounds your party, dampening the mood and subduing your magic. The party's MP is reduced!",
+ "questFungiDropFungiPotion": "Fungi Hatching Potion",
+ "questFungiUnlockText": "Unlocks Fungi Hatching Potions for purchase in the Market."
}
diff --git a/website/common/script/content/constants/events.js b/website/common/script/content/constants/events.js
index e0f85d9a43..4730450c7b 100644
--- a/website/common/script/content/constants/events.js
+++ b/website/common/script/content/constants/events.js
@@ -15,6 +15,10 @@ export const EVENTS = {
season: 'normal',
npcImageSuffix: '',
},
+ aprilFoolsQuest2024: {
+ start: '2024-04-09T08:00-04:00',
+ end: '2024-04-30T23:59-04:00',
+ },
aprilFools2024: {
start: '2024-04-01T00:00-04:00',
end: '2024-04-02T08:00-04:00',
diff --git a/website/common/script/content/hatching-potions.js b/website/common/script/content/hatching-potions.js
index 10fb2957fc..80edd661ec 100644
--- a/website/common/script/content/hatching-potions.js
+++ b/website/common/script/content/hatching-potions.js
@@ -544,12 +544,12 @@ const wacky = {
Veggie: {
text: t('hatchingPotionVeggie'),
limited: true,
- event: EVENTS.spring2023,
+ event: EVENTS.aprilFoolsQuest2024,
_addlNotes: t('eventAvailability', {
date: t('dateEndApril'),
}),
canBuy () {
- return moment().isBetween('2023-04-06T08:00-04:00', EVENTS.spring2023.end);
+ return moment().isBetween(EVENTS.aprilFoolsQuest2024.start, EVENTS.aprilFoolsQuest2024.end);
},
},
Dessert: {
@@ -567,14 +567,23 @@ const wacky = {
TeaShop: {
text: t('hatchingPotionTeaShop'),
limited: true,
- event: EVENTS.spring2023,
+ event: EVENTS.aprilFoolsQuest2024,
_addlNotes: t('premiumPotionAddlNotes', {
date: t('dateEndApril'),
}),
canBuy () {
- return moment().isBetween('2023-04-06T08:00-04:00', EVENTS.spring2023.end);
+ return moment().isBetween(EVENTS.aprilFoolsQuest2024.start, EVENTS.aprilFoolsQuest2024.end);
},
},
+ Fungi: {
+ text: t('hatchingPotionFungi'),
+ limited: true,
+ event: EVENTS.aprilFoolsQuest2024,
+ _addlNotes: t('premiumPotionAddlNotes', {
+ date: t('dateEndApril'),
+ }),
+ canBuy: hasQuestAchievementFunction('fungi'),
+ },
};
each(drops, (pot, key) => {
diff --git a/website/common/script/content/quests/masterclasser.js b/website/common/script/content/quests/masterclasser.js
index b3b56bbc6f..0ee0f0bc9b 100644
--- a/website/common/script/content/quests/masterclasser.js
+++ b/website/common/script/content/quests/masterclasser.js
@@ -702,7 +702,7 @@ const QUEST_MASTERCLASSER = {
title: t('questLostMasterclasser4RageTitle'),
description: t('questLostMasterclasser4RageDescription'),
value: 15,
- mpDrain: true,
+ mpDrain: 1,
effect: t('questLostMasterclasser4RageEffect'),
},
},
diff --git a/website/common/script/content/quests/seasonal.js b/website/common/script/content/quests/seasonal.js
index d74a41b418..b78833821c 100644
--- a/website/common/script/content/quests/seasonal.js
+++ b/website/common/script/content/quests/seasonal.js
@@ -135,9 +135,9 @@ const QUEST_SEASONAL = {
},
},
waffle: {
- event: CURRENT_EVENT && CURRENT_EVENT.season === 'spring' ? CURRENT_EVENT : null,
+ event: EVENTS.aprilFoolsQuest2024,
canBuy () {
- return this.event && moment().isBetween(this.event.start, this.event.end);
+ return moment().isBetween(EVENTS.aprilFoolsQuest2024.start, EVENTS.aprilFoolsQuest2024.end);
},
text: t('questWaffleText'),
notes: t('questWaffleNotes'),
@@ -178,9 +178,9 @@ const QUEST_SEASONAL = {
},
},
virtualpet: {
- event: CURRENT_EVENT && CURRENT_EVENT.season === 'spring' ? CURRENT_EVENT : null,
+ event: EVENTS.aprilFoolsQuest2024,
canBuy () {
- return this.event && moment().isBetween(this.event.start, this.event.end);
+ return moment().isBetween(EVENTS.aprilFoolsQuest2024.start, EVENTS.aprilFoolsQuest2024.end);
},
text: t('questVirtualPetText'),
notes: t('questVirtualPetNotes'),
@@ -220,6 +220,49 @@ const QUEST_SEASONAL = {
unlock: t('questVirtualPetUnlockText'),
},
},
+ fungi: {
+ event: EVENTS.aprilFoolsQuest2024,
+ canBuy () {
+ return moment().isBetween(EVENTS.aprilFoolsQuest2024.start, EVENTS.aprilFoolsQuest2024.end);
+ },
+ text: t('questFungiText'),
+ notes: t('questFungiNotes'),
+ completion: t('questFungiCompletion'),
+ value: 4,
+ category: 'hatchingPotion',
+ boss: {
+ name: t('questFungiBoss'),
+ hp: 500,
+ str: 2,
+ rage: {
+ title: t('questFungiRageTitle'),
+ description: t('questFungiRageDescription'),
+ value: 50,
+ mpDrain: .33,
+ effect: t('questFungiRageEffect'),
+ },
+ },
+ drop: {
+ items: [
+ {
+ type: 'hatchingPotions',
+ key: 'Fungi',
+ text: t('questFungiDropFungiPotion'),
+ }, {
+ type: 'hatchingPotions',
+ key: 'Fungi',
+ text: t('questFungiDropFungiPotion'),
+ }, {
+ type: 'hatchingPotions',
+ key: 'Fungi',
+ text: t('questFungiDropFungiPotion'),
+ },
+ ],
+ gp: 40,
+ exp: 500,
+ unlock: t('questFungiUnlockText'),
+ },
+ },
};
export default QUEST_SEASONAL;
diff --git a/website/common/script/content/shop-featuredItems.js b/website/common/script/content/shop-featuredItems.js
index cd2d655548..d3585cd5d7 100644
--- a/website/common/script/content/shop-featuredItems.js
+++ b/website/common/script/content/shop-featuredItems.js
@@ -42,24 +42,24 @@ const featuredItems = {
},
{
type: 'eggs',
- path: 'eggs.Fox',
+ path: 'eggs.Dragon',
},
];
},
quests () {
- if (moment().isBetween(EVENTS.bundle202403.start, EVENTS.bundle202403.end)) {
+ if (moment().isBetween(EVENTS.aprilFoolsQuest2024.start, EVENTS.aprilFoolsQuest2024.end)) {
return [
{
- type: 'bundles',
- path: 'bundles.cuddleBuddies',
+ type: 'quests',
+ path: 'quests.fungi',
},
{
type: 'quests',
- path: 'quests.hedgehog',
+ path: 'quests.badger',
},
{
type: 'quests',
- path: 'quests.sheep',
+ path: 'quests.snake',
},
];
}
diff --git a/website/server/models/group.js b/website/server/models/group.js
index 132b5c31bd..920e93e260 100644
--- a/website/server/models/group.js
+++ b/website/server/models/group.js
@@ -1068,7 +1068,7 @@ schema.methods._processBossQuest = async function processBossQuest (options) {
}
if (group.quest.progress.hp > quest.boss.hp) group.quest.progress.hp = quest.boss.hp;
if (quest.boss.rage.mpDrain) {
- updates.$set = { 'stats.mp': 0 };
+ updates.$mul = { 'stats.mp': 1 - quest.boss.rage.mpDrain };
}
if (quest.boss.rage.progressDrain) {
updates.$mul = { 'party.quest.progress.up': quest.boss.rage.progressDrain };