From 6668aae89ba676163caaef76afe6b6490f27ab2a Mon Sep 17 00:00:00 2001 From: Sabe Jones Date: Tue, 12 Mar 2019 17:10:38 -0500 Subject: [PATCH] feat(event): Pi Day --- migrations/users/pi-day.js | 73 ++++++ website/common/locales/en/content.json | 31 +++ website/common/locales/en/gear.json | 4 + .../script/content/gear/sets/special/index.js | 12 + website/common/script/content/index.js | 230 +++++++++++++----- .../gear/events/piDay/head_special_piDay.png | Bin 0 -> 560 bytes .../events/piDay/shield_special_piDay.png | Bin 0 -> 616 bytes .../events/piDay/shop_head_special_piDay.png | Bin 0 -> 509 bytes .../piDay/shop_shield_special_piDay.png | Bin 0 -> 553 bytes .../stable/food/Pet_Food_Pie_Base.png | Bin 0 -> 457 bytes .../food/Pet_Food_Pie_CottonCandyBlue.png | Bin 0 -> 482 bytes .../food/Pet_Food_Pie_CottonCandyPink.png | Bin 0 -> 478 bytes .../stable/food/Pet_Food_Pie_Desert.png | Bin 0 -> 454 bytes .../stable/food/Pet_Food_Pie_Golden.png | Bin 0 -> 465 bytes .../stable/food/Pet_Food_Pie_Red.png | Bin 0 -> 477 bytes .../stable/food/Pet_Food_Pie_Shade.png | Bin 0 -> 449 bytes .../stable/food/Pet_Food_Pie_Skeleton.png | Bin 0 -> 520 bytes .../stable/food/Pet_Food_Pie_White.png | Bin 0 -> 463 bytes .../stable/food/Pet_Food_Pie_Zombie.png | Bin 0 -> 524 bytes .../spritesmith_large/promo_pi_day.png | Bin 0 -> 8056 bytes website/server/controllers/api-v3/news.js | 12 +- 21 files changed, 289 insertions(+), 73 deletions(-) create mode 100644 migrations/users/pi-day.js create mode 100644 website/raw_sprites/spritesmith/gear/events/piDay/head_special_piDay.png create mode 100644 website/raw_sprites/spritesmith/gear/events/piDay/shield_special_piDay.png create mode 100644 website/raw_sprites/spritesmith/gear/events/piDay/shop_head_special_piDay.png create mode 100644 website/raw_sprites/spritesmith/gear/events/piDay/shop_shield_special_piDay.png create mode 100644 website/raw_sprites/spritesmith/stable/food/Pet_Food_Pie_Base.png create mode 100644 website/raw_sprites/spritesmith/stable/food/Pet_Food_Pie_CottonCandyBlue.png create mode 100644 website/raw_sprites/spritesmith/stable/food/Pet_Food_Pie_CottonCandyPink.png create mode 100644 website/raw_sprites/spritesmith/stable/food/Pet_Food_Pie_Desert.png create mode 100644 website/raw_sprites/spritesmith/stable/food/Pet_Food_Pie_Golden.png create mode 100644 website/raw_sprites/spritesmith/stable/food/Pet_Food_Pie_Red.png create mode 100644 website/raw_sprites/spritesmith/stable/food/Pet_Food_Pie_Shade.png create mode 100644 website/raw_sprites/spritesmith/stable/food/Pet_Food_Pie_Skeleton.png create mode 100644 website/raw_sprites/spritesmith/stable/food/Pet_Food_Pie_White.png create mode 100644 website/raw_sprites/spritesmith/stable/food/Pet_Food_Pie_Zombie.png create mode 100644 website/raw_sprites/spritesmith_large/promo_pi_day.png diff --git a/migrations/users/pi-day.js b/migrations/users/pi-day.js new file mode 100644 index 0000000000..83b0f48c10 --- /dev/null +++ b/migrations/users/pi-day.js @@ -0,0 +1,73 @@ +/* eslint-disable no-console */ +const MIGRATION_NAME = '20190312_pi_day'; +import { v4 as uuid } from 'uuid'; + +import { model as User } from '../../website/server/models/user'; + +const progressCount = 1000; +let count = 0; + +async function updateUser (user) { + count++; + + const inc = { + 'items.food.Pie_Skeleton': 1, + 'items.food.Pie_Base': 1, + 'items.food.Pie_CottonCandyBlue': 1, + 'items.food.Pie_CottonCandyPink': 1, + 'items.food.Pie_Shade': 1, + 'items.food.Pie_White': 1, + 'items.food.Pie_Golden': 1, + 'items.food.Pie_Zombie': 1, + 'items.food.Pie_Desert': 1, + 'items.food.Pie_Red': 1, + }; + const set = {}; + + set.migration = MIGRATION_NAME; + + set['items.gear.owned.head_special_piDay'] = false; + set['items.gear.owned.shield_special_piDay'] = false; + const push = [ + {type: 'marketGear', path: 'gear.flat.head_special_piDay', _id: uuid()}, + {type: 'marketGear', path: 'gear.flat.shield_special_piDay', _id: uuid()}, + ]; + + if (count % progressCount === 0) console.warn(`${count} ${user._id}`); + + return await User.update({_id: user._id}, {$inc: inc, $set: set, $push: {pinnedItems: {$each: push}}}).exec(); +} + +module.exports = async function processUsers () { + let query = { + migration: {$ne: MIGRATION_NAME}, + 'auth.timestamps.loggedin': {$gt: new Date('2019-02-15')}, + }; + + const fields = { + _id: 1, + items: 1, + }; + + while (true) { // eslint-disable-line no-constant-condition + const users = await User // eslint-disable-line no-await-in-loop + .find(query) + .limit(250) + .sort({_id: 1}) + .select(fields) + .lean() + .exec(); + + if (users.length === 0) { + console.warn('All appropriate users found and modified.'); + console.warn(`\n${count} users processed\n`); + break; + } else { + query._id = { + $gt: users[users.length - 1], + }; + } + + await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop + } +}; diff --git a/website/common/locales/en/content.json b/website/common/locales/en/content.json index d858f1bc33..3aef3d7174 100644 --- a/website/common/locales/en/content.json +++ b/website/common/locales/en/content.json @@ -377,6 +377,37 @@ "foodCandyRedThe": "the Cinnamon Candy", "foodCandyRedA": "Cinnamon Candy", + "foodPieSkeleton": "Bone Marrow Pot Pie", + "foodPieSkeletonThe": "the Bone Marrow Pot Pie", + "foodPieSkeletonA": "a slice of Bone Marrow Pot Pie", + "foodPieBase": "Basic Apple Pie", + "foodPieBaseThe": "the Basic Apple Pie", + "foodPieBaseA": "a slice of Basic Apple Pie", + "foodPieCottonCandyBlue": "Blueberry Pie", + "foodPieCottonCandyBlueThe": "the Blueberry Pie", + "foodPieCottonCandyBlueA": "a slice of Blueberry Pie", + "foodPieCottonCandyPink": "Pink Rhubarb Pie", + "foodPieCottonCandyPinkThe": "the Pink Rhubarb Pie", + "foodPieCottonCandyPinkA": "a slice of Pink Rhubarb Pie", + "foodPieShade": "Dark Chocolate Pie", + "foodPieShadeThe": "the Dark Chocolate Pie", + "foodPieShadeA": "a slice of Dark Chocolate Pie", + "foodPieWhite": "Vanilla Pudding Pie", + "foodPieWhiteThe": "the Vanilla Pudding Pie", + "foodPieWhiteA": "a slice of Vanilla Pudding Pie", + "foodPieGolden": "Golden Banana Cream Pie", + "foodPieGoldenThe": "the Golden Banana Cream Pie", + "foodPieGoldenA": "a slice of Golden Banana Cream Pie", + "foodPieZombie": "Rotten Pie", + "foodPieZombieThe": "the Rotten Pie", + "foodPieZombieA": "a Rotten slice of Pie", + "foodPieDesert": "Desert Dessert Pie", + "foodPieDesertThe": "the Desert Dessert Pie", + "foodPieDesertA": "a slice of Desert Dessert Pie", + "foodPieRed": "Red Cherry Pie", + "foodPieRedThe": "the Red Cherry Pie", + "foodPieRedA": "a slice of Red Cherry Pie", + "foodSaddleText": "Saddle", "foodSaddleNotes": "Instantly raises one of your pets into a mount.", "foodSaddleSellWarningNote": "Hey! This is a pretty useful item! Are you familiar with how to use a Saddle with your Pets?", diff --git a/website/common/locales/en/gear.json b/website/common/locales/en/gear.json index b08a18d137..6065cea66c 100644 --- a/website/common/locales/en/gear.json +++ b/website/common/locales/en/gear.json @@ -975,6 +975,8 @@ "headSpecialTurkeyHelmBaseNotes": "Your Turkey Day look will be complete when you don this beaked helm! Confers no benefit.", "headSpecialTurkeyHelmGildedText": "Gilded Turkey Helm", "headSpecialTurkeyHelmGildedNotes": "Gobble gobble! Bling bling! Confers no benefit.", + "headSpecialPiDayText": "Pi Hat", + "headSpecialPiDayNotes": "Try to balance this slice of delicious pie on your head while walking in a circle. Or throw it at a red Daily! Or you could just eat it. Your choice! Confers no benefit.", "headSpecialNyeText": "Absurd Party Hat", "headSpecialNyeNotes": "You've received an Absurd Party Hat! Wear it with pride while ringing in the New Year! Confers no benefit.", @@ -1424,6 +1426,8 @@ "shieldSpecialWintryMirrorNotes": "How else to best admire your wintry look? Increases Intelligence by <%= int %>.", "shieldSpecialWakizashiText": "Wakizashi", "shieldSpecialWakizashiNotes": "This short sword is perfect for close-quarters battles with your Dailies! Increases Constitution by <%= con %>.", + "shieldSpecialPiDayText": "Pi Shield", + "shieldSpecialPiDayNotes": "We dare you to calculate the ratio of this shield's circumference to its deliciousness! Confers no benefit.", "shieldSpecialYetiText": "Yeti-Tamer Shield", "shieldSpecialYetiNotes": "This shield reflects light from the snow. Increases Constitution by <%= con %>. Limited Edition 2013-2014 Winter Gear.", diff --git a/website/common/script/content/gear/sets/special/index.js b/website/common/script/content/gear/sets/special/index.js index 7704437e33..98516c5a10 100644 --- a/website/common/script/content/gear/sets/special/index.js +++ b/website/common/script/content/gear/sets/special/index.js @@ -2506,6 +2506,12 @@ let head = { value: 0, canOwn: ownsItem('head_special_nye2018'), }, + piDay: { + text: t('headSpecialPiDayText'), + notes: t('headSpecialPiDayNotes'), + value: 0, + canOwn: ownsItem('head_special_piDay'), + }, }; let headAccessory = { @@ -3597,6 +3603,12 @@ let shield = { value: 70, con: 9, }, + piDay: { + text: t('shieldSpecialPiDayText'), + notes: t('shieldSpecialPiDayNotes'), + value: 0, + canOwn: ownsItem('shield_special_piDay'), + }, }; let weapon = { diff --git a/website/common/script/content/index.js b/website/common/script/content/index.js index f96800c4e5..d80ebd8153 100644 --- a/website/common/script/content/index.js +++ b/website/common/script/content/index.js @@ -370,13 +370,9 @@ api.premiumMounts = stable.premiumMounts; api.specialMounts = stable.specialMounts; api.mountInfo = stable.mountInfo; -// For seasonal events, change these booleans: -let canBuyNormalFood = true; -let canDropNormalFood = true; -let canBuyCandyFood = false; -let canDropCandyFood = false; -let canBuyCakeFood = false; -let canDropCakeFood = false; +// For seasonal events, change this constant: + +const FOOD_SEASON = 'Pie'; api.food = { Meat: { @@ -385,9 +381,9 @@ api.food = { textThe: t('foodMeatThe'), target: 'Base', canBuy () { - return canBuyNormalFood; + return FOOD_SEASON === 'Normal'; }, - canDrop: canDropNormalFood, + canDrop: FOOD_SEASON === 'Normal', }, Milk: { text: t('foodMilk'), @@ -395,9 +391,9 @@ api.food = { textThe: t('foodMilkThe'), target: 'White', canBuy () { - return canBuyNormalFood; + return FOOD_SEASON === 'Normal'; }, - canDrop: canDropNormalFood, + canDrop: FOOD_SEASON === 'Normal', }, Potatoe: { text: t('foodPotatoe'), @@ -405,9 +401,9 @@ api.food = { textThe: t('foodPotatoeThe'), target: 'Desert', canBuy () { - return canBuyNormalFood; + return FOOD_SEASON === 'Normal'; }, - canDrop: canDropNormalFood, + canDrop: FOOD_SEASON === 'Normal', }, Strawberry: { text: t('foodStrawberry'), @@ -415,9 +411,9 @@ api.food = { textThe: t('foodStrawberryThe'), target: 'Red', canBuy () { - return canBuyNormalFood; + return FOOD_SEASON === 'Normal'; }, - canDrop: canDropNormalFood, + canDrop: FOOD_SEASON === 'Normal', }, Chocolate: { text: t('foodChocolate'), @@ -425,9 +421,9 @@ api.food = { textThe: t('foodChocolateThe'), target: 'Shade', canBuy () { - return canBuyNormalFood; + return FOOD_SEASON === 'Normal'; }, - canDrop: canDropNormalFood, + canDrop: FOOD_SEASON === 'Normal', }, Fish: { text: t('foodFish'), @@ -435,9 +431,9 @@ api.food = { textThe: t('foodFishThe'), target: 'Skeleton', canBuy () { - return canBuyNormalFood; + return FOOD_SEASON === 'Normal'; }, - canDrop: canDropNormalFood, + canDrop: FOOD_SEASON === 'Normal', }, RottenMeat: { text: t('foodRottenMeat'), @@ -445,9 +441,9 @@ api.food = { textThe: t('foodRottenMeatThe'), target: 'Zombie', canBuy () { - return canBuyNormalFood; + return FOOD_SEASON === 'Normal'; }, - canDrop: canDropNormalFood, + canDrop: FOOD_SEASON === 'Normal', }, CottonCandyPink: { text: t('foodCottonCandyPink'), @@ -455,9 +451,9 @@ api.food = { textThe: t('foodCottonCandyPinkThe'), target: 'CottonCandyPink', canBuy () { - return canBuyNormalFood; + return FOOD_SEASON === 'Normal'; }, - canDrop: canDropNormalFood, + canDrop: FOOD_SEASON === 'Normal', }, CottonCandyBlue: { text: t('foodCottonCandyBlue'), @@ -465,9 +461,9 @@ api.food = { textThe: t('foodCottonCandyBlueThe'), target: 'CottonCandyBlue', canBuy () { - return canBuyNormalFood; + return FOOD_SEASON === 'Normal'; }, - canDrop: canDropNormalFood, + canDrop: FOOD_SEASON === 'Normal', }, Honey: { text: t('foodHoney'), @@ -475,9 +471,9 @@ api.food = { textThe: t('foodHoneyThe'), target: 'Golden', canBuy () { - return canBuyNormalFood; + return FOOD_SEASON === 'Normal'; }, - canDrop: canDropNormalFood, + canDrop: FOOD_SEASON === 'Normal', }, Saddle: { canBuy () { @@ -495,9 +491,9 @@ api.food = { textThe: t('foodCakeSkeletonThe'), target: 'Skeleton', canBuy () { - return canBuyCakeFood; + return FOOD_SEASON === 'Cake'; }, - canDrop: canDropCakeFood, + canDrop: FOOD_SEASON === 'Cake', }, Cake_Base: { text: t('foodCakeBase'), @@ -505,9 +501,9 @@ api.food = { textThe: t('foodCakeBaseThe'), target: 'Base', canBuy () { - return canBuyCakeFood; + return FOOD_SEASON === 'Cake'; }, - canDrop: canDropCakeFood, + canDrop: FOOD_SEASON === 'Cake', }, Cake_CottonCandyBlue: { text: t('foodCakeCottonCandyBlue'), @@ -515,9 +511,9 @@ api.food = { textThe: t('foodCakeCottonCandyBlueThe'), target: 'CottonCandyBlue', canBuy () { - return canBuyCakeFood; + return FOOD_SEASON === 'Cake'; }, - canDrop: canDropCakeFood, + canDrop: FOOD_SEASON === 'Cake', }, Cake_CottonCandyPink: { text: t('foodCakeCottonCandyPink'), @@ -525,9 +521,9 @@ api.food = { textThe: t('foodCakeCottonCandyPinkThe'), target: 'CottonCandyPink', canBuy () { - return canBuyCakeFood; + return FOOD_SEASON === 'Cake'; }, - canDrop: canDropCakeFood, + canDrop: FOOD_SEASON === 'Cake', }, Cake_Shade: { text: t('foodCakeShade'), @@ -535,9 +531,9 @@ api.food = { textThe: t('foodCakeShadeThe'), target: 'Shade', canBuy () { - return canBuyCakeFood; + return FOOD_SEASON === 'Cake'; }, - canDrop: canDropCakeFood, + canDrop: FOOD_SEASON === 'Cake', }, Cake_White: { text: t('foodCakeWhite'), @@ -545,9 +541,9 @@ api.food = { textThe: t('foodCakeWhiteThe'), target: 'White', canBuy () { - return canBuyCakeFood; + return FOOD_SEASON === 'Cake'; }, - canDrop: canDropCakeFood, + canDrop: FOOD_SEASON === 'Cake', }, Cake_Golden: { text: t('foodCakeGolden'), @@ -555,9 +551,9 @@ api.food = { textThe: t('foodCakeGoldenThe'), target: 'Golden', canBuy () { - return canBuyCakeFood; + return FOOD_SEASON === 'Cake'; }, - canDrop: canDropCakeFood, + canDrop: FOOD_SEASON === 'Cake', }, Cake_Zombie: { text: t('foodCakeZombie'), @@ -565,9 +561,9 @@ api.food = { textThe: t('foodCakeZombieThe'), target: 'Zombie', canBuy () { - return canBuyCakeFood; + return FOOD_SEASON === 'Cake'; }, - canDrop: canDropCakeFood, + canDrop: FOOD_SEASON === 'Cake', }, Cake_Desert: { text: t('foodCakeDesert'), @@ -575,9 +571,9 @@ api.food = { textThe: t('foodCakeDesertThe'), target: 'Desert', canBuy () { - return canBuyCakeFood; + return FOOD_SEASON === 'Cake'; }, - canDrop: canDropCakeFood, + canDrop: FOOD_SEASON === 'Cake', }, Cake_Red: { text: t('foodCakeRed'), @@ -585,9 +581,9 @@ api.food = { textThe: t('foodCakeRedThe'), target: 'Red', canBuy () { - return canBuyCakeFood; + return FOOD_SEASON === 'Cake'; }, - canDrop: canDropCakeFood, + canDrop: FOOD_SEASON === 'Cake', }, Candy_Skeleton: { text: t('foodCandySkeleton'), @@ -595,9 +591,9 @@ api.food = { textThe: t('foodCandySkeletonThe'), target: 'Skeleton', canBuy () { - return canBuyCandyFood; + return FOOD_SEASON === 'Candy'; }, - canDrop: canDropCandyFood, + canDrop: FOOD_SEASON === 'Candy', }, Candy_Base: { text: t('foodCandyBase'), @@ -605,9 +601,9 @@ api.food = { textThe: t('foodCandyBaseThe'), target: 'Base', canBuy () { - return canBuyCandyFood; + return FOOD_SEASON === 'Candy'; }, - canDrop: canDropCandyFood, + canDrop: FOOD_SEASON === 'Candy', }, Candy_CottonCandyBlue: { text: t('foodCandyCottonCandyBlue'), @@ -615,9 +611,9 @@ api.food = { textThe: t('foodCandyCottonCandyBlueThe'), target: 'CottonCandyBlue', canBuy () { - return canBuyCandyFood; + return FOOD_SEASON === 'Candy'; }, - canDrop: canDropCandyFood, + canDrop: FOOD_SEASON === 'Candy', }, Candy_CottonCandyPink: { text: t('foodCandyCottonCandyPink'), @@ -625,9 +621,9 @@ api.food = { textThe: t('foodCandyCottonCandyPinkThe'), target: 'CottonCandyPink', canBuy () { - return canBuyCandyFood; + return FOOD_SEASON === 'Candy'; }, - canDrop: canDropCandyFood, + canDrop: FOOD_SEASON === 'Candy', }, Candy_Shade: { text: t('foodCandyShade'), @@ -635,9 +631,9 @@ api.food = { textThe: t('foodCandyShadeThe'), target: 'Shade', canBuy () { - return canBuyCandyFood; + return FOOD_SEASON === 'Candy'; }, - canDrop: canDropCandyFood, + canDrop: FOOD_SEASON === 'Candy', }, Candy_White: { text: t('foodCandyWhite'), @@ -645,9 +641,9 @@ api.food = { textThe: t('foodCandyWhiteThe'), target: 'White', canBuy () { - return canBuyCandyFood; + return FOOD_SEASON === 'Candy'; }, - canDrop: canDropCandyFood, + canDrop: FOOD_SEASON === 'Candy', }, Candy_Golden: { text: t('foodCandyGolden'), @@ -655,9 +651,9 @@ api.food = { textThe: t('foodCandyGoldenThe'), target: 'Golden', canBuy () { - return canBuyCandyFood; + return FOOD_SEASON === 'Candy'; }, - canDrop: canDropCandyFood, + canDrop: FOOD_SEASON === 'Candy', }, Candy_Zombie: { text: t('foodCandyZombie'), @@ -665,9 +661,9 @@ api.food = { textThe: t('foodCandyZombieThe'), target: 'Zombie', canBuy () { - return canBuyCandyFood; + return FOOD_SEASON === 'Candy'; }, - canDrop: canDropCandyFood, + canDrop: FOOD_SEASON === 'Candy', }, Candy_Desert: { text: t('foodCandyDesert'), @@ -675,9 +671,9 @@ api.food = { textThe: t('foodCandyDesertThe'), target: 'Desert', canBuy () { - return canBuyCandyFood; + return FOOD_SEASON === 'Candy'; }, - canDrop: canDropCandyFood, + canDrop: FOOD_SEASON === 'Candy', }, Candy_Red: { text: t('foodCandyRed'), @@ -685,9 +681,109 @@ api.food = { textThe: t('foodCandyRedThe'), target: 'Red', canBuy () { - return canBuyCandyFood; + return FOOD_SEASON === 'Candy'; }, - canDrop: canDropCandyFood, + canDrop: FOOD_SEASON === 'Candy', + }, + Pie_Skeleton: { + text: t('foodPieSkeleton'), + textA: t('foodPieSkeletonA'), + textThe: t('foodPieSkeletonThe'), + target: 'Skeleton', + canBuy () { + return FOOD_SEASON === 'Pie'; + }, + canDrop: FOOD_SEASON === 'Pie', + }, + Pie_Base: { + text: t('foodPieBase'), + textA: t('foodPieBaseA'), + textThe: t('foodPieBaseThe'), + target: 'Base', + canBuy () { + return FOOD_SEASON === 'Pie'; + }, + canDrop: FOOD_SEASON === 'Pie', + }, + Pie_CottonCandyBlue: { + text: t('foodPieCottonCandyBlue'), + textA: t('foodPieCottonCandyBlueA'), + textThe: t('foodPieCottonCandyBlueThe'), + target: 'CottonCandyBlue', + canBuy () { + return FOOD_SEASON === 'Pie'; + }, + canDrop: FOOD_SEASON === 'Pie', + }, + Pie_CottonCandyPink: { + text: t('foodPieCottonCandyPink'), + textA: t('foodPieCottonCandyPinkA'), + textThe: t('foodPieCottonCandyPinkThe'), + target: 'CottonCandyPink', + canBuy () { + return FOOD_SEASON === 'Pie'; + }, + canDrop: FOOD_SEASON === 'Pie', + }, + Pie_Shade: { + text: t('foodPieShade'), + textA: t('foodPieShadeA'), + textThe: t('foodPieShadeThe'), + target: 'Shade', + canBuy () { + return FOOD_SEASON === 'Pie'; + }, + canDrop: FOOD_SEASON === 'Pie', + }, + Pie_White: { + text: t('foodPieWhite'), + textA: t('foodPieWhiteA'), + textThe: t('foodPieWhiteThe'), + target: 'White', + canBuy () { + return FOOD_SEASON === 'Pie'; + }, + canDrop: FOOD_SEASON === 'Pie', + }, + Pie_Golden: { + text: t('foodPieGolden'), + textA: t('foodPieGoldenA'), + textThe: t('foodPieGoldenThe'), + target: 'Golden', + canBuy () { + return FOOD_SEASON === 'Pie'; + }, + canDrop: FOOD_SEASON === 'Pie', + }, + Pie_Zombie: { + text: t('foodPieZombie'), + textA: t('foodPieZombieA'), + textThe: t('foodPieZombieThe'), + target: 'Zombie', + canBuy () { + return FOOD_SEASON === 'Pie'; + }, + canDrop: FOOD_SEASON === 'Pie', + }, + Pie_Desert: { + text: t('foodPieDesert'), + textA: t('foodPieDesertA'), + textThe: t('foodPieDesertThe'), + target: 'Desert', + canBuy () { + return FOOD_SEASON === 'Pie'; + }, + canDrop: FOOD_SEASON === 'Pie', + }, + Pie_Red: { + text: t('foodPieRed'), + textA: t('foodPieRedA'), + textThe: t('foodPieRedThe'), + target: 'Red', + canBuy () { + return FOOD_SEASON === 'Pie'; + }, + canDrop: FOOD_SEASON === 'Pie', }, /* eslint-enable camelcase */ }; diff --git a/website/raw_sprites/spritesmith/gear/events/piDay/head_special_piDay.png b/website/raw_sprites/spritesmith/gear/events/piDay/head_special_piDay.png new file mode 100644 index 0000000000000000000000000000000000000000..042a1c45f3ec0a0b55323fd97e07b08ca4a818b9 GIT binary patch literal 560 zcmeAS@N?(olHy`uVBq!ia0vp^ML-jA5L~c#`DCC7XMsm# zF#`j)FbFd;%$g$s6l5>)^mS!_%p@(yEYVWww19zuaj&O~V@SoVw>KTVLjon(9#~J* zOA=`_WOg*l5N&7KW*3Iso4>c{#q%>~_nS@3PbGKWYfGSQ_ZrS(KOz@R=xwunp z?gyt8=Bsxvl(V@l|LXkKs1>`rkG}bu@n8PirJ@uQ+ryXDJ@t~VxpalOypH#qyR&YB zXtwm#hXMNba;JK3Zv8&hIoYi5QR9nUAFK9S3(il^EYzO!`E`3bt8k~=q{+*#MeMAx z>b?1KYJmOvJ09j=OIwRfe@&xsiQulo&v&gZ>UQeW^`{l@Ien`c(9y81S` z_v4LAkLE6koFC%5B*S&fzvgq7o(gOZ-Y)lV`)j)$=8~`8?_R&>n3Hnm(u}p@n~&@2 j7iKBBY6BwgTe~DWM4fND%W# literal 0 HcmV?d00001 diff --git a/website/raw_sprites/spritesmith/gear/events/piDay/shield_special_piDay.png b/website/raw_sprites/spritesmith/gear/events/piDay/shield_special_piDay.png new file mode 100644 index 0000000000000000000000000000000000000000..c8cd7113a8c188226dcc04d71e07f94a001e32a2 GIT binary patch literal 616 zcmeAS@N?(olHy`uVBq!ia0vp^ML-jA5L~c#`DCC7XMsm# zF#`j)FbFd;%$g$s6l5>)^mS!_%p@(ytmY~a&&|NV_|?*smuaen)fS5*bEBf9e#tkrDXhrZ;S$axq^!NT zJEJxC{`Z#mN83(K|7~~viz6R<4gd4QmHq2uV}aIU0U!KJs#&aKEpPANdwWLv`Rm+Y z-+YVQb}m8D+NGcCZsw;~A5SnhH&3)*vrcXCwC&v?JIj`29bLIqq4d@|r{8@c<#U&R z-8eCNCpZ7J?@Q9&dR*-ael2(F#;=*t%eBknTTySbmMKG-u1S{|djfCbsj-pOKwBFY5Bgx6ku$0VS_SvAtZm zDfXhktkSgVUF9?q7ea_IlOpIOXzl>fW>W uWgm4~71saYy!Lhu(Jc2>VGIln`yYy%8Z_L^)p6VgiWyH=KbLh*2~7Y#2^sPL literal 0 HcmV?d00001 diff --git a/website/raw_sprites/spritesmith/gear/events/piDay/shop_head_special_piDay.png b/website/raw_sprites/spritesmith/gear/events/piDay/shop_head_special_piDay.png new file mode 100644 index 0000000000000000000000000000000000000000..ef534c7212d56346c96f11d96ac16b93efd60294 GIT binary patch literal 509 zcmeAS@N?(olHy`uVBq!ia0vp^E+EXo1|%(nCvO5$Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmP-leDOn;d!_Js~8v~)y>VW}d$as&W$e6t_n*JKz5VUo%jL|1NI;V{Ts3#u{?oZkCe^QGK9`?=&meQ; zvg`f)-dP2!*0u<}VG283YdJqY%1-O%y$}yg?w`4w+m58}$&v5i(sWfUliZyAwqEN& zu`;K_h4;l%uHG=rXSx&b5~KCRUcBg!6{o}ZB$kGQ0qP9lZd?rk(F_gCOQaaq-+n8T z{;s}yi=Oi0YrAeoi>wt94Lai_71efT{{1IA4H*u+OY2`eW%Fy7b3t#Knr41|Q}|8q z?bqas(!vj(mK|T}^zX6dk@xwVyd>=z6Z8#p?q+;tC^*$@`fZZw|A!L4nSNWfhg@AB z`#aXiP`K=jw42fTOF0`~Ftyf|ub5EuM?UENYg5K$&#!TBx_9f82t)o#=eZ%P7fpB* k^eOa=QAh_em~vH|*`?4%fqB|aU_>!^y85}Sb4q9e0Qy+j8UO$Q literal 0 HcmV?d00001 diff --git a/website/raw_sprites/spritesmith/gear/events/piDay/shop_shield_special_piDay.png b/website/raw_sprites/spritesmith/gear/events/piDay/shop_shield_special_piDay.png new file mode 100644 index 0000000000000000000000000000000000000000..0289cc564f547c22451f5047c5f9d028794a056b GIT binary patch literal 553 zcmeAS@N?(olHy`uVBq!ia0vp^E+EXo1|%(nCvO5$Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmP-leDNcvs~BwYz79#ZJsWUAr-gY-mvyQ93XM*W4-Hy zMFD#jXjH6B(hOrg==+!J(X&O}la*X$Sm&-ODJdwN;HRg@SI2(PQD6_RYfj*XkUgO~ zM^{}@>@3*wAcgtk&)k!i?JS=@>{DlVK>|yJYVz!AiZlYW%IlwNJik>PswuoI%Usyd z`YNMCu{Srv_M2;Li$aUE4ZS*~O^MIkL2XVhw5m8B$fpHF_<(l z(v~%0gE9Mo#7`^@0nrzv_Sds4C|!C#Zhp}8k14#8{a2K0Tdbjry7;Z|3g(F-1WC>V$9aI(}Zb6~?ej>UHmLKiMt*YNc{XYc}eO?7A6U$(z}0`9CKrg=#u|aSsv(gXN}_bpXQJ6FS+?r>$UK)y2q94 zj^A4NjQLni`rfRL@c(79%CV-$EZudaw5sJc?U`tD?d|gTQn^q1LZ70O?s&8aDIo#T aPn^@*8jkO{v#ARhsSKX3elF{r5}E+>jNwiI literal 0 HcmV?d00001 diff --git a/website/raw_sprites/spritesmith/stable/food/Pet_Food_Pie_Base.png b/website/raw_sprites/spritesmith/stable/food/Pet_Food_Pie_Base.png new file mode 100644 index 0000000000000000000000000000000000000000..0f068416331b22d46892d10db7f21a6c194db048 GIT binary patch literal 457 zcmeAS@N?(olHy`uVBq!ia0vp^E+EXo1|%(nCvO5$Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmP-GmnU+LjCpyRtyY`VV*9IAr-gY-rVSQ*ny$_V||wb zFKaDx{DOeeQ_dDInJv;X9Ryg^3x%vYZY;e!cP@*$JLe;%YkT$b7U=~pw=j`>=aG5v zh}y^Bxzo8>s^rTvwHbjHfk4A7t{Qv38vD2_pQUvgGgtbgdR+RMFd?o>b)~(GmB^?0 z+$S}hCvCa^R&R+2*G7v}&Bv7{M$fL_%1z$0`JL3`)9wE4POm~vlr5k6Gq13!aC)Rm zl#lj4!*%ZO?@wB?_rZz@K^jY51gAxDrvFV&ezQ)`KkU!js7YUbWlX!^;nh(Qyf#u% z|7@Si%I&)|W9037wLdlncwB64NqpgP$?;QLW$7lvnGuDbD-XE4D1QB=mpnaj{f8|@ zmwvzbxyNhqgiRtz>%Z)AJ)_m_q!s5;bt^|UYPs*dYTnk6T7J(v_v+8?c)b0yNKl9U pZ`&iE_r(0q_WZ8F1@rloWBgM4;;g?m?%xXv2v1i(mvv4FO#m%!y4wH% literal 0 HcmV?d00001 diff --git a/website/raw_sprites/spritesmith/stable/food/Pet_Food_Pie_CottonCandyBlue.png b/website/raw_sprites/spritesmith/stable/food/Pet_Food_Pie_CottonCandyBlue.png new file mode 100644 index 0000000000000000000000000000000000000000..6dd3df0dcf4b4cebcf82aefbfa44ed5624d36eb3 GIT binary patch literal 482 zcmeAS@N?(olHy`uVBq!ia0vp^E+EXo1|%(nCvO5$Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmP-GmnUsh5NVc^$ZM*`JOJ0Ar-gY-n92-N@O_x@xE)q zE*0I#3CTB7ZWMX1Uszv!MVdoutLm(-s73c0oQnh2A6mLVF=q?gV%0rQ551H+$34$E z(D8H4k2-oiWiTU9-eyDv}HY;`(TD}QNq%j?_5$#YIFJ0x1apX+$ssTuL_ zraUNKo)xKhw#0Ccmduo%$Gz8&h14jD7`=1K+B!?w^Y+)H4wH&@ih2f>+1XF}o?rR! z>2d>i#j-!QdZ!DnEm;5aN9D(#`wM3~z0pwFcd1$I;`%i*)hDKie|l?MQkR^=`=zGj z#ojjCBa>`XO5b`n;vproLLn>~)y}8kwDUjj#$NQcN zUe5m=zVd5?UH;4Icp<>s+vMIOM}Zw~+0HI{R^nH#1i1J*-o7~PR$h1XlN5{C!%siR zW$~uZyZ(Li-MzsFzdybAc?!@fFmUktIZyo8JaNC*pN)MQGxa=EJuXGAHM0=)3fdZ1 zuJOcP+-M1p=OxFTHdBK%jyzIX+Os|Ev_!m~NYCT9Q}-0s{QdMYz+)EIO|7SG?{xk2 z=Cz9%YNXlKn4J5*tJd?lU5PrZf5 z{Y+C^ONvxIFMYf>t8m}nTk|^gTb%x7O}%+?UHhbx%3?jwtb3-(mG>XH8Qz*6GA$xC z=wtLTy<~&Ki;um1{pRBiuf-FVh$Nl=lHdJfrH*aji5&5wtMwi4{>|QfEKB(N-ZrPS zzjBx2-g-^Slb-rfTrX;Uc8~n>30rLW3uDc%{f}x=c+e>c4GM+GeGJPxiq_0XQA_{{ NdAj{+wZtMPu8kj4`BjY1_qW-!@L@!HCdaj{&RRINSzImoU~=bwvV>Oavqaz zS8UZtX;|}Ss^F_1vYwY7-|fAm)9SP-=)`-YMM_FXUoJAVTQgVc@$2RM-A*F2&V9GGcdVGP^XMkS|Np*edfr<5PCbaLRb?;#&($rDCo?C<%#bh+vyu8g#lSeV z=A501e(R6B1+L-Kp7s7*U6rh%$I+@1>#_PS_xoSl&pJ%%%c}0I`Iz>)(W&TT_V=fs z>Q(?1EQvi)yxmt(^Q} m;n(%L^PYb^#sl^71l{=B8DSNVC-#YgL_A&nT-G@yGywog#=GkP literal 0 HcmV?d00001 diff --git a/website/raw_sprites/spritesmith/stable/food/Pet_Food_Pie_Golden.png b/website/raw_sprites/spritesmith/stable/food/Pet_Food_Pie_Golden.png new file mode 100644 index 0000000000000000000000000000000000000000..bff877d248c0a1e6081d008f9b3b1db4de227a00 GIT binary patch literal 465 zcmeAS@N?(olHy`uVBq!ia0vp^E+EXo1|%(nCvO5$Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmP-GmnU+Mb2%D90mr)I8PVHkcwMxZ*KHD?7-0evED_g z@M7o(S+1rD%L@cbLIv)$`1mn$-dGxZ&~;7>i#ogcLG}|`O6z2g@Wqy_P>g*vVOh~a z*Y+dJj(?wBG<}lO`^S^E2?4DFgAE}PJ0c}^+}v}ozEjme*L)?9XP4FW$1@N6Oggt) zx!vj6iOe|3ofn_aR#|zM@9X@f0Up6zn$rVC0t>F2^?tnfZKC16YA+eCjVmYIoo4>^ z=A&nZv!YxA&urMAbf&&`$)qI@o~)S`q_O1P^9hlvCHhLqdv?uR|L1|JY(M)_p{~VK z)I(QuReq0}wB+2uX@>W!U+NxVcTy}B7dpOC*>ic2n&|4~QsQwyg@esSvBefHeO{5!d;ZfD literal 0 HcmV?d00001 diff --git a/website/raw_sprites/spritesmith/stable/food/Pet_Food_Pie_Red.png b/website/raw_sprites/spritesmith/stable/food/Pet_Food_Pie_Red.png new file mode 100644 index 0000000000000000000000000000000000000000..bfc2148a4c46dd0c9f651e5b2a02d1d2e9fe9c57 GIT binary patch literal 477 zcmeAS@N?(olHy`uVBq!ia0vp^E+EXo1|%(nCvO5$Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmP-GmnUss>%oUG6n|5EKe85kcwMxZyI_Zc3^0GsP8(# zt=-SBX>-6Di>LlOUho&3xzzALtK-2Fg{0|ac%NfijsbDr!vfEAN%99GpFbJ^w{K@s=x07I(%E#gm%Tg*X8S5 zze{YQnDOiwiQ|u7I8WLl`KD)y2$$s7^*-x`__B8&yP@k_9`@&F%%m?R$b*N>8MNH*zQxMc)NV=^Ch->dB4UecY{3ueCv3FIp5kX?5~ zccW)b-R)S#*3-`KtAv0Sfq{nR{m)AGKQBtHt#1uaSoL%zkLNB4zURRcRe0T$yPf_O zD{`iKOzNxJyL5_^BKMj-Q$C8c9eW<#m)x`4+BdnT_J3la$4su9?@ffxi={u_eMITm z(JhOjlk0x{)AY3Z@_QywSLA!6{Zk9f6EPJ9#?wYH{mH)gR{;Y}; z33}ml==n_1_huh!+va{s+nje@bBV})#kJq&sl42=d+w`Z{o~<4MU!7CT`vv3o7bf9 f;200o!xQxHfA#nKn$dZGK1jsV)z4*}Q$iB}m$~)yR2_Q__?~*U&Y_EEi37>J=JpduHMOr zTQQq|$-mqDEdA!mB^ruvH?_}5aY$T$(b zx$B7kIff4vzZoRtI2k6?YchQJS(DnU|Li_vM9hsW&!8z2!op`(dET(UvF+BrfA?N> z-49a_%Cx_GH^Q@Eme8eFEh&2y8NQ_*U;EF;>aw7|3uob~Q%9Qq86C(-Sg^@lq|5a9 zS#_cPVKe8x>@fYe@dKN~xxWjwE?-QanX>BvQ%C4|CFi>St%sJ~J+a_^y6Txb)3x_z z@xMHEd0k}U=1;vdQvR4mdU-5Yc~Y&>GDzm5O^ literal 0 HcmV?d00001 diff --git a/website/raw_sprites/spritesmith/stable/food/Pet_Food_Pie_Zombie.png b/website/raw_sprites/spritesmith/stable/food/Pet_Food_Pie_Zombie.png new file mode 100644 index 0000000000000000000000000000000000000000..454cdb0987b417f2b1add565cff0cd866d0e4816 GIT binary patch literal 524 zcmeAS@N?(olHy`uVBq!ia0vp^E+EXo1|%(nCvO5$Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmP-GmnTB|9|gu3m6y}XL`CghE&{odt<*hQ=-iAkKa8D zzjSxh@td+bIVbAF9D_}!vGMLS*=n*w-sMa4tY!tJjU7EoO6v~J zdtf<5Y;TC&dRMvkS03K0d2i|Hf&ft=S}%XCT=M$=_4n>2oH>5VQyD*4iLfu&UBGpq z?Azf$#s4eTUOaVT&3(p#`kViYk1du@)6`lLnAV}0oL&B8d58b&A1^|7Z;k5^UGw$f z(cO!kqE=4W`LeI8x_j;3eO<0IlJ1Y zE#7WutTJo=x(J^QbFwxcld(S;f4#JPt<#~pX`Iu7d^hwwShKQRQcLB{Zl4P&d#*>F z=Xd-6!{Mju?)m^dm-9xt|LQwts&2i-xmrLF4l*t7OJ!6V6f8IV3XC@fPgg&ebxsLQ E06gX7*8l(j literal 0 HcmV?d00001 diff --git a/website/raw_sprites/spritesmith_large/promo_pi_day.png b/website/raw_sprites/spritesmith_large/promo_pi_day.png new file mode 100644 index 0000000000000000000000000000000000000000..294b4c6a4e7073c89602bdab0bc7ad0b25179a5a GIT binary patch literal 8056 zcmYM21ymGK+s79~1VIrg32ByAU?~v<=}wnUk!AsDBqc zSCf?CsAjKsS%ZA!oHF~(_ZXW+3P)rulBvx(Zruk7RxoAblFG^AQM?Rh#*g~IT)`X} z7G(aNK92EAhdH^HmJg^>*L`)hIVov@!N%Vqvl%O4v+qCA0Elb4s&8`FzZ)c&5yY^x zsvH{?nQwW4Lwo?ZH2^TL6ae8$OSA_mzMywHR*fe+WhMv`@#^3Ph(tGqY`7o%R!W6^ zr}{X87cmt)*!w1;PP3zMI+(b^U%q4Pl$^hvga4P@9rB8%WHPGhgDMpB^G_-1U6!Bp z{nm&*X^aLWnCDa3Rz5yDqx}=J{u~EaYEOGXUf5jEd z?41N4%0LU^=~vOYfBTCi2yldLof0I$W#rs4y7;Dt&5BrOQ)28X2l4j~4GFKg>US*# zUuXT^JP$*e{50>{3DKaS=L?#kqgpzH@Y z58b4Yx2}GO1p0|SXl)`GkLaxb&9kvk)n>KC28EwK8{%b+8hUtCMTzY|J^X@$qln9; z3E+~twSmiGe%~=j!UdoH8x>wK--Fw_IFyRGc0nYSFJDX%L`o4(;dqAFYZB2&k=f#~ zOWhH@_avzQr&t}1Q^*~2yr__MbNnWpUk~ssm;_|slQV)9i3EZMnDAE!e59^53CM4E zzKnQ4@=*G082A;BE4(O6>?`3pz1VG&AcS?^aACPX$vyZt;;Gx1 zkoKQ27v?6Kp%9|QT^9;t5{8hOMWO?bQ(YroCc=zq+(->Bn5%&7{*NW03o+B0`J|hw%+yW^jYMwv^=!yQVPt4UXe^%5>t@+#*~X5z4kD$d+{D~ZD_p(ey~@4Ngj)%t+TNTHP7%)h zF|k6LLLKdP?Wz%SJJ6=orr@UbX3mIS9=lb!09t@vz%fNSMMi+is*8g_E@VmGLQ7bS zh9ik%`4urZd`m_xKT)$a2cu*2#_A2PRlAkj8;3Wjo|xeWsltQdiOSqL>0jounv--A z-Qt&fAW(;R+5|Y%jCr3275_BR8P>}C+w?u+XI5NxxlWeMVm!05mKnc3ztLgP5?kjc z+ZY>0MPDT{DNWzij8Jz(@2-|%j=N%^hMlf~+_cIw8K1Hvxm7!g)W|C3O69OV0~jYb zvM7g3uUh&fZ41=EGZ&VjT$YU;wi)|8)-)b!?_qys|7%NZtACtm%xIj!?t$PV8bTTh znmHO!YEddq>RIYwDz^H-khqk!RKl>?&SfA-)HMyp%y^l`^5q=Ut{gzFB$w*=o#D z&|VdU5qZM5#}{CcZTApTIhs4U0xg8u71@Ps-U3mB%&Ks!o>VOio(vkS39Z%g^iXC{ zZu5%qni|sRyYi6e&sS&b-`0mzY}K6GLM#VsohmXae;^~Orfon2Uj%|5%MBZSU9OdgJs(C%WhJ3A@+Qo z=20@6dp0$0Iln?bWvEp4^CwXu@)3TM!jsQLp4V18tUua3)OJVn1(-+HH4)ZJKi_D3DbfRwd_oA5k)fY~K+e{^;DN!soJ!d&Am zo#<*>1YUUPQE0Dhc!x=Zj*_|(Olj0u#7PKiRq5plIWkr@?_2yFHuiCBLeSXI7|oeM z{4{J5ib%+SzDTx+)B4O`iFP{K8wdGG23P_=*9%nXNKss=o)CJ3!NYP4Vhn@~oU7Wa zG}aW?4_wb(Puyx()mMDh{2TGBKUC*GH{%VoyxuTOs`l9a;&Hg$FzHb8)L63RyF+_? zbZ9guZ6FsPFUM2wX3p0-dReZEAKEGgP2uoQtdXa3?M6GbV@`6ARj1tr>k7zzjYj9r zk^@^l8;p%X*&uJSh5sUd3m&#hICIfo(tm&F+s@D3x~fsT^?29Kqo$(@6P!jg_Xb5L zMVVLkUW=iffk9(n7$ z)%10`P*u?GREAOZTf~D4pC;9h$eYCVf?zzHi;sr zx*9AS8H}Tvyo=fE3VtUnyWgMp@6SGtp{B3zZ+Y(X^klyO z!T`I@;OPA^K>t#4OKa6Kulq!D`)XF~wS=qnm_Kq~X#;x4vZP|Y_09E>MbiQ2ncZsW zmh5Qm*~%s-s*o0?D^44jap)J&u%WkUhHW19KWuj%YCRd09g1pQX*E7=K8Cdwx0msn zd7LZ){F+`a7$<^twF7N-!<%t?2scFrI z9~UezHRRH38>u2EYnpX9eXWiz>%Om~)D9x{YSL^YOK*PIpE2_hG!k~QQBp>!>ATgn zC3A#8rq;k49Gp^dfpSTE3nY+uf}>nc$>f3c@3QHtmDV-(Ava+Gq~ieaWNjSVwPpr_ zBig(v@b@tmMz_?Nt;rnOMU^}*H6ONiI~2W!UsYUPr$!O|jgAYB$C{tBBJF$~p;sPX zgbifYm_d~odVS2rvTQAou`5gzfk+8pi7wndb$yH|l48XL1PuWIxLKfpP$eg6+s)a@ zmTS)LZ9%Vm+gJ?|+y1kA8mzNFeX3a!^$diK#!u|$2H&W^NGr0mzc9(jq>}&JL2wDk z>6P3_9QTV~YQ>t-na`1!<(Ty~y?_NR2y4Ec_#=+$l!0nqXv*zIO$V3Y@=?RM?y;JH zH#C30`+;rxAxnqAS*Lzc)z*l1x0?eOSJ)<(2+WV3v#9@0Xe|Sq7cW#)$ug zM>UZU&Y^TgvX|jPV3QDk)*E}R1C#U{4S!XC9OM6LGm}BH^NW@JLo5Gq1~~Cd0td9? zdSYUy$;0|lJi$#3-U1M$4%HdRFmV#=MXcFiijJ(X;-y!!owee{ebn)$&Duig9!(4g z=_;NX*Tc^3QfXZ~W}WQtx>{4CuYEoSg=jHe37I0l)%oR9d8UUre={h5NHtbWPat); zO)xj7Dh8Qd4-?F)Gln@h+%I%h+FV61?;ChUU~+DXDD5hud%5UR{mKq(+MI~+K^`S@ zJ>@mchdkBeg`QAFWIqe^ZqP60GSOdpvTHLT`02tJ77oG1zCSGvpdns`M-2+C z*?kNq^~NxbS{<~b6=~_G&Aq&E#^*HS3^pg-Z!;n@r{u5)tUB=8Yb=undK=$J&E?lM zRaw{AzVN@1L}-lU#O~v_Q954WK!`4*`tUA7oemlm1;;e>1|>&nJ?Ij& zg{;hChIjurORRP6KCfn?oJ_HFepT#h`Xa2-ZGH9PT@FwTI#9#ele#!aljfZU%b&8oD-lxzk)-~GRM(4-^xq^{xT z76Vw`4sp1ReO=oDw#mhlxpD&MDe%xwJEs~t4bZfcaee+>RJ;x*$e-Z3YuPesd_(`8-P0;@* zVp|RSz(C5XzJj3{8Q!~wbEG|#Cs|X}5u5QCI(+CWiTHB;MrFU&r1533Frv*Q|B*4| z^w2Eu8VH_0>SQQ%J!uvH+GmyN7yKlZrgDU>wf%yTBV+-)>_w~A^(mRlcg>tD>)Qk(r@k(eIMn1j6Fz(ih%&>`r^o zNsZ6KsmR-ZrCw1peNlOdVm}lgcZM|DIrEU!{j>Bme80i?MqVvc$K+GvfMI3E+}@NQ zsw{4q{MNYG_bk!T(#mQEqIQyx!A?;V7S&edr!8a# z-}~9lz}}CLi9{|c=yNlLHHv?Ro$dyDi55lgh6)Cd1fFqPfv-==A#1Y}v$@TgvzPVg zW#Ea5bBUa29)g$_Q=xt6##+7D8>@J(~3&D7wNse$UG&XL^ zpH1L|@Z8ZS%?_9f7?tLJ{HQ?dNhLin+4fU!GMWqZriS!yK3;cubm@X`Fry5yDX)}@ z(y~pGWH<7CQr2!z;n|EiC295OA*)`D>|l?2{K9YQW}2^SD>2i+qS&+ER@d8yo^N3} z$HKk*oj!5tf$2SWWXkxoLgID0B^XA(RR4(XOD|FTe|X3T<>mci_hTX}b;)55c%$kl zqr*uD8>+q+l7|w~g3I}PDE8}z2^==` z*{pd)i#s9YNS{sQcSYQa(9JnFYp=A6+xnR-tiRrhbX zF}e6TIf8uYkC9nk%E{Me&qeumdfm7;%NHP@1;e+aBG3$%1{DA55ih-dZ@>Q)vDap* zbT^qQPW%p1l!(rs<0zG{;N?9!@jO|AW zF?es6`i+P7R6SAxQ=#l{%gaf;P`y*>n+aZ(@Wp6)4+!vZ>y`}DucuHc88O%Q(`AOY z)R4ubwu3~0OwEEn92h6c`aH(LCC;Nr)CXGYbt^4e-#bVe+E1IAwNb?HfS(d!c9|B1 z(R76xG#Wp)jWs5r_id~+EYU+=LMwY}>hqehJ2&M02eEJ$Gk)=NgX7zLp~N5Eoqj#@ z->^C=uI?4PO(;qJVNzp>lUm+7w5{{l&Z4v}syI`L3CnOFV_O~8PO;XVdG@@t&E-R~ zDP&rD+rZoN14H26&rgP7cIV7tecYcES7Xu`{q=RF3^MXD>fnqEpSyFGZ_kaDl8a-9 zPZLcWx(=y(dZP3t+JVsS-1AaiiFcht?1KhPez2j3(n4i=hMZByCi=#zjlDu+&4qm? zCdd9}l{^~0zYo9TbYq0ey~O`;-5(^P(zMBSkxMnV)?V;@NYyQRL0DSj4SgBET zb995s``Y0$duco->!MG{qO``vJ3ZF#sukJ2ATGUVYj0nqYjKKKwZ7M=1>2uf>-M3v z?j3y<;P!MkuIA{1Wb`mr64A$o+6PugdDxb<{?4;35?^ml`YM2OM+#-Q?EGTOv&s<9 zG^WnoR@{>C4XDsHa?FHWmmF2*3j3QB?kMx4WbT%dlnHkyCc@j-+l4SKxKW+T93ba+A>f0-ic6*y<4gpE4OvGhG0U*=i?v6&m8u1 zd2b8s8Q4=;!&NV<#@!I?cALjScH(ZS8Bo9T+58VxxzE<^b_7_E^hL!dCg8nowlF1i zrmz%HY{%iNxf$q$scHAhI_}?PC1a47WiUBz3LRGYj_S`W6MLGg$oUaP3mf{;JDe+3 z<6jRQf{#yBbX&vQeu7TOg$oj#+_B}nL{o40TA~5$6VA0!=}&*H-_@y0KDYPw4xMAS z>%UG?w8`*}Yuk6hZ{7#Kn39{cKv!B*`#;Hy(>N8*lNy2PndL4eFO58F2}q_D;+rNM)J;ESMFgKAdCvW)tYq>lJf65kDo@qB zS0Y~uvI_}?g;l#diN6?-?i&uhkUgKBptM)PpV9tuEn59aLveX`a3Gt|5>kpJ()DF) zhOSolavZPD;N~j0KE4PnFN;2p+jYeBfRL1Hed&7f%AqdJ8?> zobpY?lb)J>+}?5b$K>P8UV_G2MOOc|-Q7K49t~|?$?(!Dl5(>w(8uJ0PMNxWtt#ao zVE_mkwMazPQ&nHV2MEn=Xbm@>a>Fk{{$1{1r>_MkM2C-zV%wKm`ADo3I6gmqP0IsU zr4%p-h6p^_Z@j)jZ_DPmJ1xqQTWe%0QB!7=_Mkp#|1L2p0>^4@gyyU%qT38yD6E3f zGv_5;dRrn;lcRUjc;$+^4}I|klDE3(GK)_cIqm&K!|Y;y8L}fDhU|#>`9~|!c9$kC zI?PV(*(YePu8io%#>Ci5)}HaqKmQAW1)v%O0JMBoxcGG?@j@)2c};&d1lF;iw++Pd z%o%C0^E$5^uosfptj8~@%_veA4{WIBbA=;Q+fxRSwiAwhF{OsJ$}^N@XopH)Q$gvg z;UA=vrr~8dn;TzLM>YLqi@OeSw5v9VwVM|CNAiMi6Qw9`)UuRASWx9iL9D(6%EUzG zUktN1qTou;mu1u%2NTsMdXgO@9kg$JayGVjaz}wAM5969+>FZNyArRZD{*z7A?oDn1gG-x#*Tzm33S{2+9<)C4U3dXbuCA3BHxS60 z@gH=LQX6%~Z7J@5S+wHRvGkplRZ^8!nOYP{N=Zr$wXN?o%?1XmW_LkjQM8IM}MG$|A}|d z+v${IVcx2{9NS}RzC8;7qZLrui=U^H*?@0Lkr+> m6WIqh%6*`K2Z$5BlvF%

${res.t('newStuff')}

-

3/5/2019 - ${LAST_ANNOUNCEMENT_TITLE}

+

3/14/2019 - ${LAST_ANNOUNCEMENT_TITLE}


-
-

We’ve added three new backgrounds to the Background Shop! Now your avatar can feed the birds at the Duck Pond, browse the Flower Market and go on the hunt for Spring goodies in a Field with Colored Eggs. Check them out under User Icon > Backgrounds!

-

Plus, there’s new Gold-purchasable equipment in the Enchanted Armoire, including the Vernal Vestment set. Better work hard on your real-life tasks to earn all the pieces! Enjoy :)

-
by AnneDeLune, GeraldThePixel, QuartzFox, Vikte, gawrone, astigmatism, and SabreCat
+
+

Hello Habiticans! In celebration of Pi Day on March 14, we've gifted everyone delicious slices of pie for you all to feed to your pets.

+

We've also given everyone a festive Pi Hat and Shield so you can celebrate in style. Enjoy them, and thanks for being a part of our community!

+
by Beffymaroo and SabreCat
`, });