Merge branch 'release' into develop
This commit is contained in:
@@ -857,5 +857,9 @@
|
||||
"backgroundSteamworksText": "Steamworks",
|
||||
"backgroundSteamworksNotes": "Build mighty contraptions of vapor and steel in a Steamworks.",
|
||||
"backgroundClocktowerText": "Clock Tower",
|
||||
"backgroundClocktowerNotes": "Situate your secret lair behind the face of a Clock Tower."
|
||||
"backgroundClocktowerNotes": "Situate your secret lair behind the face of a Clock Tower.",
|
||||
|
||||
"eventBackgrounds": "Event Backgrounds",
|
||||
"backgroundBirthdayBashText": "Birthday Bash",
|
||||
"backgroundBirthdayBashNotes": "Habitica's having a birthday party, and everyone's invited!"
|
||||
}
|
||||
|
||||
@@ -801,7 +801,8 @@
|
||||
"armorSpecialBirthday2021Notes": "Happy Birthday, Habitica! Wear these Extravagant Party Robes to celebrate this wonderful day. Confers no benefit.",
|
||||
"armorSpecialBirthday2022Text": "Preposterous Party Robes",
|
||||
"armorSpecialBirthday2022Notes": "Happy Birthday, Habitica! Wear these Proposterous Party Robes to celebrate this wonderful day. Confers no benefit.",
|
||||
|
||||
"armorSpecialBirthday2023Text": "Fabulous Party Robes",
|
||||
"armorSpecialBirthday2023Notes": "Happy Birthday, Habitica! Wear these Fabulous Party Robes to celebrate this wonderful day. Confers no benefit.",
|
||||
|
||||
"armorSpecialGaymerxText": "Rainbow Warrior Armor",
|
||||
"armorSpecialGaymerxNotes": "In celebration of the GaymerX Conference, this special armor is decorated with a radiant, colorful rainbow pattern! GaymerX is a game convention celebrating LGTBQ and gaming and is open to everyone.",
|
||||
@@ -2680,6 +2681,9 @@
|
||||
"backSpecialTurkeyTailGildedNotes": "Plumage fit for a parade! Confers no benefit.",
|
||||
"backSpecialNamingDay2020Text": "Royal Purple Gryphon Tail",
|
||||
"backSpecialNamingDay2020Notes": "Happy Naming Day! Swish this fiery, pixely tail about as you celebrate Habitica. Confers no benefit.",
|
||||
"backSpecialAnniversaryText": "Habitica Hero Cape",
|
||||
"backSpecialAnniversaryNotes": "Let this proud cape fly in the wind and tell everyone that you're a Habitica Hero. Confers no benefit. Special Edition 10th Birthday Bash Item.",
|
||||
|
||||
"backBearTailText": "Bear Tail",
|
||||
"backBearTailNotes": "This tail makes you look like a brave bear! Confers no benefit.",
|
||||
"backCactusTailText": "Cactus Tail",
|
||||
@@ -2711,6 +2715,8 @@
|
||||
"bodySpecialTakeThisNotes": "These pauldrons were earned by participating in a sponsored Challenge made by Take This. Congratulations! Increases all Stats by <%= attrs %>.",
|
||||
"bodySpecialAetherAmuletText": "Aether Amulet",
|
||||
"bodySpecialAetherAmuletNotes": "This amulet has a mysterious history. Increases Constitution and Strength by <%= attrs %> each.",
|
||||
"bodySpecialAnniversaryText": "Habitica Hero Collar",
|
||||
"bodySpecialAnniversaryNotes": "Perfectly complement your royal purple ensemble! Confers no benefit. Special Edition 10th Birthday Bash Item.",
|
||||
|
||||
"bodySpecialSummerMageText": "Shining Capelet",
|
||||
"bodySpecialSummerMageNotes": "Neither salt water nor fresh water can tarnish this metallic capelet. Confers no benefit. Limited Edition 2014 Summer Gear.",
|
||||
@@ -2913,6 +2919,8 @@
|
||||
"eyewearSpecialAetherMaskNotes": "This mask has a mysterious history. Increases Intelligence by <%= int %>.",
|
||||
"eyewearSpecialKS2019Text": "Mythic Gryphon Visor",
|
||||
"eyewearSpecialKS2019Notes": "Bold as a gryphon's... hmm, gryphons don't have visors. It reminds you to... oh, who are we kidding, it just looks cool! Confers no benefit.",
|
||||
"eyewearSpecialAnniversaryText": "Habitica Hero Mask",
|
||||
"eyewearSpecialAnniversaryNotes": "Look through the eyes of a Habitica Hero - you! Confers no benefit. Special Edition 10th Birthday Bash Item.",
|
||||
|
||||
"eyewearSpecialSummerRogueText": "Roguish Eyepatch",
|
||||
"eyewearSpecialSummerRogueNotes": "It doesn't take a scallywag to see how stylish this is! Confers no benefit. Limited Edition 2014 Summer Gear.",
|
||||
|
||||
@@ -209,6 +209,7 @@
|
||||
"dateEndOctober": "October 31",
|
||||
"dateEndNovember": "November 30",
|
||||
"dateEndDecember": "December 31",
|
||||
"dateStartFebruary": "February 8",
|
||||
"januaryYYYY": "January <%= year %>",
|
||||
"februaryYYYY": "February <%= year %>",
|
||||
"marchYYYY": "March <%= year %>",
|
||||
@@ -236,5 +237,33 @@
|
||||
"g1g1Limitations": "This is a limited time event that starts on December 15th at 8:00 AM ET (13:00 UTC) and will end January 8th at 11:59 PM ET (January 9th 04:59 UTC). This promotion only applies when you gift to another Habitican. If you or your gift recipient already have a subscription, the gifted subscription will add months of credit that will only be used after the current subscription is canceled or expires.",
|
||||
"noLongerAvailable": "This item is no longer available.",
|
||||
"gemSaleHow": "Between <%= eventStartMonth %> <%= eventStartOrdinal %> and <%= eventEndOrdinal %>, simply purchase any Gem bundle like usual and your account will be credited with the promotional amount of Gems. More Gems to spend, share, or save for any future releases!",
|
||||
"gemSaleLimitations": "This promotion only applies during the limited time event. This event starts on <%= eventStartMonth %> <%= eventStartOrdinal %> at 8:00 AM EDT (12:00 UTC) and will end <%= eventStartMonth %> <%= eventEndOrdinal %> at 8:00 PM EDT (00:00 UTC). The promo offer is only available when buying Gems for yourself."
|
||||
}
|
||||
"gemSaleLimitations": "This promotion only applies during the limited time event. This event starts on <%= eventStartMonth %> <%= eventStartOrdinal %> at 8:00 AM EDT (12:00 UTC) and will end <%= eventStartMonth %> <%= eventEndOrdinal %> at 8:00 PM EDT (00:00 UTC). The promo offer is only available when buying Gems for yourself.",
|
||||
"anniversaryLimitations": "This is a limited time event that starts on January 30th at 8:00 AM ET (13:00 UTC) and will end February 8th at 11:59 PM ET (04:59 UTC). The Limited Edition Jubilant Gryphatrice and ten Magic Hatching Potions will be available to buy during this time. The other Gifts listed in the Four for Free section will be automatically delivered to all accounts that were active in the 30 days prior to day the gift is sent. Accounts created after the gifts are sent will not be able to claim them.",
|
||||
"anniversaryLimitedDates": "January 30th to February 8th",
|
||||
"limitedEvent": "Limited Event",
|
||||
"celebrateAnniversary": "Celebrate Habitica's 10th Birthday with gifts and exclusive items below!",
|
||||
"celebrateBirthday": "Celebrate Habitica's 10th Birthday with gifts and exclusive items!",
|
||||
"jubilantGryphatricePromo": "Animated Jubilant Gryphatrice Pet",
|
||||
"limitedEdition": "Limited Edition",
|
||||
"anniversaryGryphatriceText": "The rare Jubilant Gryphatrice joins the birthday celebrations! Don't miss your chance to own this exclusive animated Pet.",
|
||||
"anniversaryGryphatricePrice": "Own it today for <strong>$9.99</strong> or <strong>60 gems</strong>",
|
||||
"buyNowMoneyButton": "Buy Now for $9.99",
|
||||
"buyNowGemsButton": "Buy Now for 60 Gems",
|
||||
"wantToPayWithGemsText": "Want to pay with Gems?",
|
||||
"wantToPayWithMoneyText": "Want to pay with Stripe, Paypal, or Amazon?",
|
||||
"ownJubilantGryphatrice": "<strong>You own the Jubilant Gryphatrice!</strong> Visit the Stable to equip!",
|
||||
"jubilantSuccess": "You've successfully purchased the <strong>Jubilant Gryphatrice!</strong>",
|
||||
"stableVisit": "Visit the Stable to equip!",
|
||||
"takeMeToStable": "Take me to the Stable",
|
||||
"plentyOfPotions": "Plenty of Potions",
|
||||
"plentyOfPotionsText": "We're bringing back 10 of the community's favorite Magic Hatching potions. Head over to The Market to fill out your collection!",
|
||||
"visitTheMarketButton": "Visit the Market",
|
||||
"fourForFree": "Four for Free",
|
||||
"fourForFreeText": "To keep the party going, we'll be giving away Party Robes, 20 Gems, and a limited edition birthday Background and item set that includes a Cape, Pauldrons, and an Eyemask.",
|
||||
"dayOne": "Day 1",
|
||||
"dayFive": "Day 5",
|
||||
"dayTen": "Day 10",
|
||||
"partyRobes": "Party Robes",
|
||||
"twentyGems": "20 Gems",
|
||||
"birthdaySet": "Birthday Set"
|
||||
}
|
||||
@@ -32,6 +32,7 @@
|
||||
"royalPurpleJackalope": "Royal Purple Jackalope",
|
||||
"invisibleAether": "Invisible Aether",
|
||||
"gryphatrice": "Gryphatrice",
|
||||
"jubilantGryphatrice": "Jubilant Gryphatrice",
|
||||
"potion": "<%= potionType %> Potion",
|
||||
"egg": "<%= eggType %> Egg",
|
||||
"eggs": "Eggs",
|
||||
|
||||
@@ -540,6 +540,11 @@ const backgrounds = {
|
||||
snowy_temple: { },
|
||||
winter_lake_with_swans: { },
|
||||
},
|
||||
eventBackgrounds: {
|
||||
birthday_bash: {
|
||||
price: 0,
|
||||
},
|
||||
},
|
||||
timeTravelBackgrounds: {
|
||||
airship: {
|
||||
price: 1,
|
||||
@@ -583,7 +588,9 @@ forOwn(backgrounds, (backgroundsInSet, set) => {
|
||||
forOwn(backgroundsInSet, (background, bgKey) => {
|
||||
background.key = bgKey;
|
||||
background.set = set;
|
||||
background.price = background.price || 7;
|
||||
if (background.price !== 0) {
|
||||
background.price = background.price || 7;
|
||||
}
|
||||
background.text = background.text || t(`background${upperFirst(camelCase(bgKey))}Text`);
|
||||
background.notes = background.notes || t(`background${upperFirst(camelCase(bgKey))}Notes`);
|
||||
|
||||
|
||||
@@ -10,11 +10,17 @@ const gemsPromo = {
|
||||
|
||||
export const EVENTS = {
|
||||
noEvent: {
|
||||
start: '2023-01-31T20:00-05:00',
|
||||
start: '2023-02-08T23:59-05:00',
|
||||
end: '2023-02-14T08:00-05:00',
|
||||
season: 'normal',
|
||||
npcImageSuffix: '',
|
||||
},
|
||||
birthday10: {
|
||||
start: '2023-01-30T08:00-05:00',
|
||||
end: '2023-02-08T23:59-05:00',
|
||||
season: 'birthday',
|
||||
npcImageSuffix: '_birthday',
|
||||
},
|
||||
winter2023: {
|
||||
start: '2022-12-20T08:00-05:00',
|
||||
end: '2023-01-31T23:59-05:00',
|
||||
|
||||
@@ -16,7 +16,8 @@ import t from '../../../translation';
|
||||
import { getClassName } from '../../../../libs/getClassName';
|
||||
|
||||
const CURRENT_EVENT = find(
|
||||
EVENTS, event => moment().isBetween(event.start, event.end) && Boolean(event.season),
|
||||
EVENTS, event => moment().isBetween(event.start, event.end)
|
||||
&& ['winter', 'spring', 'summer', 'fall'].includes(event.season),
|
||||
);
|
||||
|
||||
const gearEvents = pickBy(EVENTS, event => event.gear);
|
||||
@@ -798,6 +799,12 @@ const armor = {
|
||||
winter2023Healer: {
|
||||
set: 'winter2023CardinalHealerSet',
|
||||
},
|
||||
birthday2023: {
|
||||
text: t('armorSpecialBirthday2023Text'),
|
||||
notes: t('armorSpecialBirthday2023Notes'),
|
||||
value: 0,
|
||||
canOwn: ownsItem('armor_special_birthday2023'),
|
||||
},
|
||||
};
|
||||
|
||||
const armorStats = {
|
||||
@@ -923,6 +930,12 @@ const back = {
|
||||
value: 0,
|
||||
canOwn: ownsItem('back_special_namingDay2020'),
|
||||
},
|
||||
anniversary: {
|
||||
text: t('backSpecialAnniversaryText'),
|
||||
notes: t('backSpecialAnniversaryNotes'),
|
||||
value: 0,
|
||||
canOwn: ownsItem('back_special_anniversary'),
|
||||
},
|
||||
};
|
||||
|
||||
const body = {
|
||||
@@ -992,6 +1005,12 @@ const body = {
|
||||
value: 0,
|
||||
canOwn: ownsItem('body_special_namingDay2018'),
|
||||
},
|
||||
anniversary: {
|
||||
text: t('bodySpecialAnniversaryText'),
|
||||
notes: t('bodySpecialAnniversaryNotes'),
|
||||
value: 0,
|
||||
canOwn: ownsItem('body_special_anniversary'),
|
||||
},
|
||||
};
|
||||
|
||||
const eyewear = {
|
||||
@@ -1140,6 +1159,12 @@ const eyewear = {
|
||||
value: 0,
|
||||
canOwn: ownsItem('eyewear_special_ks2019'),
|
||||
},
|
||||
anniversary: {
|
||||
text: t('eyewearSpecialAnniversaryText'),
|
||||
notes: t('eyewearSpecialAnniversaryNotes'),
|
||||
value: 0,
|
||||
canOwn: ownsItem('eyewear_special_anniversary'),
|
||||
},
|
||||
};
|
||||
|
||||
const head = {
|
||||
|
||||
@@ -70,13 +70,13 @@ const premium = {
|
||||
value: 2,
|
||||
text: t('hatchingPotionShimmer'),
|
||||
limited: true,
|
||||
event: EVENTS.spring2022,
|
||||
event: EVENTS.birthday10,
|
||||
_addlNotes: t('eventAvailabilityReturning', {
|
||||
availableDate: t('dateEndMarch'),
|
||||
previousDate: t('marchYYYY', { year: 2020 }),
|
||||
availableDate: t('dateStartFebruary'),
|
||||
previousDate: t('marchYYYY', { year: 2022 }),
|
||||
}),
|
||||
canBuy () {
|
||||
return moment().isBefore(EVENTS.spring2022.end);
|
||||
return moment().isBetween(EVENTS.birthday10.start, EVENTS.birthday10.end);
|
||||
},
|
||||
},
|
||||
Fairy: {
|
||||
@@ -109,13 +109,13 @@ const premium = {
|
||||
value: 2,
|
||||
text: t('hatchingPotionAquatic'),
|
||||
limited: true,
|
||||
event: EVENTS.summer2022,
|
||||
event: EVENTS.birthday10,
|
||||
_addlNotes: t('eventAvailabilityReturning', {
|
||||
availableDate: t('dateEndJuly'),
|
||||
previousDate: t('augustYYYY', { year: 2020 }),
|
||||
availableDate: t('dateStartFebruary'),
|
||||
previousDate: t('julyYYYY', { year: 2022 }),
|
||||
}),
|
||||
canBuy () {
|
||||
return moment().isBetween(EVENTS.summer2022.start, EVENTS.summer2022.end);
|
||||
return moment().isBetween(EVENTS.birthday10.start, EVENTS.birthday10.end);
|
||||
},
|
||||
},
|
||||
Ember: {
|
||||
@@ -188,12 +188,12 @@ const premium = {
|
||||
text: t('hatchingPotionPeppermint'),
|
||||
limited: true,
|
||||
_addlNotes: t('eventAvailabilityReturning', {
|
||||
availableDate: t('dateEndJanuary'),
|
||||
previousDate: t('januaryYYYY', { year: 2018 }),
|
||||
availableDate: t('dateStartFebruary'),
|
||||
previousDate: t('januaryYYYY', { year: 2022 }),
|
||||
}),
|
||||
event: EVENTS.winter2022,
|
||||
event: EVENTS.birthday10,
|
||||
canBuy () {
|
||||
return moment().isBetween(EVENTS.winter2022.start, EVENTS.winter2022.end);
|
||||
return moment().isBetween(EVENTS.birthday10.start, EVENTS.birthday10.end);
|
||||
},
|
||||
},
|
||||
StarryNight: {
|
||||
@@ -239,13 +239,13 @@ const premium = {
|
||||
value: 2,
|
||||
text: t('hatchingPotionGlow'),
|
||||
limited: true,
|
||||
event: EVENTS.fall2021,
|
||||
event: EVENTS.birthday10,
|
||||
_addlNotes: t('eventAvailabilityReturning', {
|
||||
availableDate: t('dateEndOctober'),
|
||||
previousDate: t('septemberYYYY', { year: 2019 }),
|
||||
availableDate: t('dateStartFebruary'),
|
||||
previousDate: t('octoberYYYY', { year: 2021 }),
|
||||
}),
|
||||
canBuy () {
|
||||
return moment().isBefore(EVENTS.fall2021.end);
|
||||
return moment().isBetween(EVENTS.birthday10.start, EVENTS.birthday10.end);
|
||||
},
|
||||
},
|
||||
Frost: {
|
||||
@@ -286,13 +286,13 @@ const premium = {
|
||||
value: 2,
|
||||
text: t('hatchingPotionCelestial'),
|
||||
limited: true,
|
||||
event: EVENTS.spring2022,
|
||||
event: EVENTS.birthday10,
|
||||
_addlNotes: t('eventAvailabilityReturning', {
|
||||
availableDate: t('dateEndMarch'),
|
||||
previousDate: t('marchYYYY', { year: 2020 }),
|
||||
availableDate: t('dateStartFebruary'),
|
||||
previousDate: t('marchYYYY', { year: 2022 }),
|
||||
}),
|
||||
canBuy () {
|
||||
return moment().isBefore(EVENTS.spring2022.end);
|
||||
return moment().isBetween(EVENTS.birthday10.start, EVENTS.birthday10.end);
|
||||
},
|
||||
},
|
||||
Sunshine: {
|
||||
@@ -399,13 +399,13 @@ const premium = {
|
||||
value: 2,
|
||||
text: t('hatchingPotionSandSculpture'),
|
||||
limited: true,
|
||||
event: EVENTS.summer2021,
|
||||
event: EVENTS.birthday10,
|
||||
_addlNotes: t('eventAvailabilityReturning', {
|
||||
availableDate: t('dateEndJuly'),
|
||||
previousDate: t('juneYYYY', { year: 2020 }),
|
||||
availableDate: t('dateStartFebruary'),
|
||||
previousDate: t('julyYYYY', { year: 2021 }),
|
||||
}),
|
||||
canBuy () {
|
||||
return moment().isBetween(EVENTS.summer2021.start, EVENTS.summer2021.end);
|
||||
return moment().isBetween(EVENTS.birthday10.start, EVENTS.birthday10.end);
|
||||
},
|
||||
},
|
||||
Windup: {
|
||||
@@ -426,26 +426,26 @@ const premium = {
|
||||
value: 2,
|
||||
text: t('hatchingPotionVampire'),
|
||||
limited: true,
|
||||
event: EVENTS.fall2022,
|
||||
event: EVENTS.birthday10,
|
||||
_addlNotes: t('eventAvailabilityReturning', {
|
||||
availableDate: t('dateEndOctober'),
|
||||
previousDate: t('octoberYYYY', { year: 2021 }),
|
||||
availableDate: t('dateStartFebruary'),
|
||||
previousDate: t('octoberYYYY', { year: 2022 }),
|
||||
}),
|
||||
canBuy () {
|
||||
return moment().isBetween(EVENTS.fall2022.start, EVENTS.fall2022.end);
|
||||
return moment().isBetween(EVENTS.birthday10.start, EVENTS.birthday10.end);
|
||||
},
|
||||
},
|
||||
AutumnLeaf: {
|
||||
value: 2,
|
||||
text: t('hatchingPotionAutumnLeaf'),
|
||||
limited: true,
|
||||
event: EVENTS.potions202111,
|
||||
event: EVENTS.birthday10,
|
||||
_addlNotes: t('eventAvailabilityReturning', {
|
||||
availableDate: t('dateEndNovember'),
|
||||
previousDate: t('novemberYYYY', { year: 2020 }),
|
||||
availableDate: t('dateStartFebruary'),
|
||||
previousDate: t('novemberYYYY', { year: 2021 }),
|
||||
}),
|
||||
canBuy () {
|
||||
return moment().isBefore(EVENTS.potions202111.end);
|
||||
return moment().isBetween(EVENTS.birthday10.start, EVENTS.birthday10.end);
|
||||
},
|
||||
},
|
||||
BlackPearl: {
|
||||
@@ -460,12 +460,12 @@ const premium = {
|
||||
text: t('hatchingPotionStainedGlass'),
|
||||
limited: true,
|
||||
_addlNotes: t('eventAvailabilityReturning', {
|
||||
availableDate: t('dateEndJanuary'),
|
||||
previousDate: t('januaryYYYY', { year: 2021 }),
|
||||
availableDate: t('dateStartFebruary'),
|
||||
previousDate: t('januaryYYYY', { year: 2022 }),
|
||||
}),
|
||||
event: EVENTS.winter2022,
|
||||
event: EVENTS.birthday10,
|
||||
canBuy () {
|
||||
return moment().isBetween(EVENTS.winter2022.start, EVENTS.winter2022.end);
|
||||
return moment().isBetween(EVENTS.birthday10.start, EVENTS.birthday10.end);
|
||||
},
|
||||
},
|
||||
PolkaDot: {
|
||||
@@ -532,12 +532,13 @@ const premium = {
|
||||
value: 2,
|
||||
text: t('hatchingPotionPorcelain'),
|
||||
limited: true,
|
||||
event: EVENTS.potions202208,
|
||||
_addlNotes: t('premiumPotionAddlNotes', {
|
||||
date: t('dateEndAugust'),
|
||||
event: EVENTS.birthday10,
|
||||
_addlNotes: t('eventAvailabilityReturning', {
|
||||
availableDate: t('dateStartFebruary'),
|
||||
previousDate: t('augustYYYY', { year: 2022 }),
|
||||
}),
|
||||
canBuy () {
|
||||
return moment().isBetween(EVENTS.potions202208.start, EVENTS.potions202208.end);
|
||||
return moment().isBetween(EVENTS.birthday10.start, EVENTS.birthday10.end);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import each from 'lodash/each';
|
||||
import moment from 'moment';
|
||||
import { EVENTS } from './constants/events';
|
||||
import {
|
||||
drops as dropEggs,
|
||||
quests as questEggs,
|
||||
@@ -118,6 +120,9 @@ const canFindSpecial = {
|
||||
'Jackalope-RoyalPurple': true, // subscription
|
||||
'Wolf-Cerberus': false, // Pet once granted to backers
|
||||
'Gryphon-Gryphatrice': false, // Pet once granted to kickstarter
|
||||
|
||||
// Birthday Pet
|
||||
'Gryphatrice-Jubilant': false,
|
||||
},
|
||||
mounts: {
|
||||
// Thanksgiving pet ladder
|
||||
@@ -174,6 +179,7 @@ const specialPets = {
|
||||
'Fox-Veteran': 'veteranFox',
|
||||
'JackOLantern-Glow': 'glowJackolantern',
|
||||
'Gryphon-Gryphatrice': 'gryphatrice',
|
||||
'Gryphatrice-Jubilant': 'jubilantGryphatrice',
|
||||
'JackOLantern-RoyalPurple': 'royalPurpleJackolantern',
|
||||
};
|
||||
|
||||
@@ -207,6 +213,16 @@ each(specialPets, (translationString, key) => {
|
||||
};
|
||||
});
|
||||
|
||||
Object.assign(petInfo['Gryphatrice-Jubilant'], {
|
||||
canBuy () {
|
||||
return moment().isBetween(EVENTS.birthday10.start, EVENTS.birthday10.end);
|
||||
},
|
||||
currency: 'gems',
|
||||
event: 'birthday10',
|
||||
value: 60,
|
||||
purchaseType: 'pets',
|
||||
});
|
||||
|
||||
each(specialMounts, (translationString, key) => {
|
||||
mountInfo[key] = {
|
||||
key,
|
||||
|
||||
@@ -7,6 +7,7 @@ export default {
|
||||
missingTypeParam: '"req.params.type" is required.',
|
||||
missingKeyParam: '"req.params.key" is required.',
|
||||
itemNotFound: 'Item "<%= key %>" not found.',
|
||||
petNotFound: 'Pet "<%= key %>" not found.',
|
||||
questNotFound: 'Quest "<%= key %>" not found.',
|
||||
spellNotFound: 'Skill "<%= spellId %>" not found.',
|
||||
invalidQuantity: 'Quantity to purchase must be a positive whole number.',
|
||||
|
||||
@@ -7,28 +7,27 @@ import {
|
||||
} from '../content/constants';
|
||||
|
||||
const CURRENT_EVENT = find(
|
||||
EVENTS, event => moment().isBetween(event.start, event.end) && Boolean(event.season),
|
||||
EVENTS, event => moment().isBetween(event.start, event.end)
|
||||
&& ['winter', 'spring', 'summer', 'fall'].includes(event.season),
|
||||
);
|
||||
|
||||
const SHOP_OPEN = CURRENT_EVENT && ['winter', 'spring', 'summer', 'fall'].includes(CURRENT_EVENT.season);
|
||||
|
||||
export default {
|
||||
opened: SHOP_OPEN,
|
||||
opened: CURRENT_EVENT,
|
||||
|
||||
currentSeason: SHOP_OPEN ? upperFirst(CURRENT_EVENT.season) : 'Closed',
|
||||
currentSeason: CURRENT_EVENT ? upperFirst(CURRENT_EVENT.season) : 'Closed',
|
||||
|
||||
dateRange: {
|
||||
start: CURRENT_EVENT ? moment(CURRENT_EVENT.start) : moment().subtract(1, 'days').toDate(),
|
||||
end: CURRENT_EVENT ? moment(CURRENT_EVENT.end) : moment().subtract(1, 'seconds').toDate(),
|
||||
},
|
||||
|
||||
availableSets: SHOP_OPEN
|
||||
availableSets: CURRENT_EVENT
|
||||
? [
|
||||
...SEASONAL_SETS[CURRENT_EVENT.season],
|
||||
]
|
||||
: [],
|
||||
|
||||
pinnedSets: SHOP_OPEN
|
||||
pinnedSets: CURRENT_EVENT
|
||||
? {
|
||||
rogue: 'winter2023RibbonRogueSet',
|
||||
warrior: 'winter2023WalrusWarriorSet',
|
||||
@@ -36,13 +35,13 @@ export default {
|
||||
healer: 'winter2023CardinalHealerSet',
|
||||
}
|
||||
: {},
|
||||
availableSpells: SHOP_OPEN && moment().isBetween('2022-12-27T08:00-05:00', CURRENT_EVENT.end)
|
||||
availableSpells: CURRENT_EVENT && moment().isBetween('2022-12-27T08:00-05:00', CURRENT_EVENT.end)
|
||||
? [
|
||||
'snowball',
|
||||
]
|
||||
: [],
|
||||
|
||||
availableQuests: SHOP_OPEN && CURRENT_EVENT.season === 'winter'
|
||||
availableQuests: CURRENT_EVENT && CURRENT_EVENT.season === 'winter'
|
||||
? [
|
||||
'evilsanta',
|
||||
'evilsanta2',
|
||||
|
||||
@@ -13,6 +13,7 @@ import hourglassPurchase from './hourglassPurchase';
|
||||
import errorMessage from '../../libs/errorMessage';
|
||||
import { BuyGemOperation } from './buyGem';
|
||||
import { BuyQuestWithGemOperation } from './buyQuestGem';
|
||||
import { BuyPetWithGemOperation } from './buyPetGem';
|
||||
import { BuyHourglassMountOperation } from './buyMount';
|
||||
|
||||
// @TODO: remove the req option style. Dependency on express structure is an anti-pattern
|
||||
@@ -86,7 +87,12 @@ export default async function buy (
|
||||
break;
|
||||
}
|
||||
case 'pets':
|
||||
buyRes = hourglassPurchase(user, req, analytics);
|
||||
if (key === 'Gryphatrice-Jubilant') {
|
||||
const buyOp = new BuyPetWithGemOperation(user, req, analytics);
|
||||
buyRes = await buyOp.purchase();
|
||||
} else {
|
||||
buyRes = hourglassPurchase(user, req, analytics);
|
||||
}
|
||||
break;
|
||||
case 'quest': {
|
||||
const buyOp = new BuyQuestWithGoldOperation(user, req, analytics);
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
import get from 'lodash/get';
|
||||
import {
|
||||
BadRequest,
|
||||
NotFound,
|
||||
} from '../../libs/errors';
|
||||
import content from '../../content/index';
|
||||
|
||||
import errorMessage from '../../libs/errorMessage';
|
||||
import { AbstractGemItemOperation } from './abstractBuyOperation';
|
||||
|
||||
export class BuyPetWithGemOperation extends AbstractGemItemOperation { // eslint-disable-line import/prefer-default-export, max-len
|
||||
multiplePurchaseAllowed () { // eslint-disable-line class-methods-use-this
|
||||
return false;
|
||||
}
|
||||
|
||||
getItemKey () {
|
||||
return this.key;
|
||||
}
|
||||
|
||||
getItemValue (item) { // eslint-disable-line class-methods-use-this
|
||||
return item.value / 4;
|
||||
}
|
||||
|
||||
getItemType () { // eslint-disable-line class-methods-use-this
|
||||
return 'pet';
|
||||
}
|
||||
|
||||
extractAndValidateParams (user, req) {
|
||||
this.key = get(req, 'params.key');
|
||||
const { key } = this;
|
||||
if (!key) throw new BadRequest(errorMessage('missingKeyParam'));
|
||||
|
||||
const item = content.petInfo[key];
|
||||
|
||||
if (!item) throw new NotFound(errorMessage('petNotFound', { key }));
|
||||
|
||||
this.canUserPurchase(user, item);
|
||||
}
|
||||
|
||||
canUserPurchase (user, item) {
|
||||
if (item && user.items.pets[item.key]) {
|
||||
throw new BadRequest(this.i18n('petsAlreadyOwned'));
|
||||
}
|
||||
|
||||
super.canUserPurchase(user, item);
|
||||
}
|
||||
|
||||
async executeChanges (user, item, req) {
|
||||
user.items.pets[item.key] = 5;
|
||||
if (user.markModified) user.markModified('items.pets');
|
||||
|
||||
await this.subtractCurrency(user, item);
|
||||
|
||||
return [
|
||||
user.items.pets,
|
||||
this.i18n('messageBought', {
|
||||
itemText: item.text(req.language),
|
||||
}),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -251,9 +251,10 @@ export default async function unlock (user, req = {}, analytics) {
|
||||
return invalidSet(req);
|
||||
}
|
||||
|
||||
cost = getIndividualItemPrice(setType, item, req);
|
||||
|
||||
unlockedAlready = alreadyUnlocked(user, setType, firstPath);
|
||||
if (!unlockedAlready) {
|
||||
cost = getIndividualItemPrice(setType, item, req);
|
||||
}
|
||||
|
||||
// Since only an item is being unlocked here,
|
||||
// remove all the other items from the set
|
||||
|
||||
Reference in New Issue
Block a user