diff --git a/habitica-images b/habitica-images index e8f76ad308..c1e8973a66 160000 --- a/habitica-images +++ b/habitica-images @@ -1 +1 @@ -Subproject commit e8f76ad308e256fb65306cfe880cabdc98c818cd +Subproject commit c1e8973a668cef4a52c1205ea916aceb8f7c5307 diff --git a/migrations/archive/2022/20221227_nye.js b/migrations/archive/2022/20221227_nye.js new file mode 100644 index 0000000000..8120a3c76b --- /dev/null +++ b/migrations/archive/2022/20221227_nye.js @@ -0,0 +1,144 @@ +/* eslint-disable no-console */ +const MIGRATION_NAME = '20221227_nye'; +import { model as User } from '../../../website/server/models/user'; +import { v4 as uuid } from 'uuid'; + +const progressCount = 1000; +let count = 0; + +async function updateUser (user) { + count++; + + const set = { migration: MIGRATION_NAME }; + let push; + + if (typeof user.items.gear.owned.head_special_nye2021 !== 'undefined') { + set['items.gear.owned.head_special_nye2022'] = false; + push = [ + { + type: 'marketGear', + path: 'gear.flat.head_special_nye2022', + _id: uuid(), + }, + ]; + } else if (typeof user.items.gear.owned.head_special_nye2020 !== 'undefined') { + set['items.gear.owned.head_special_nye2021'] = false; + push = [ + { + type: 'marketGear', + path: 'gear.flat.head_special_nye2021', + _id: uuid(), + }, + ]; + } else if (typeof user.items.gear.owned.head_special_nye2019 !== 'undefined') { + set['items.gear.owned.head_special_nye2020'] = false; + push = [ + { + type: 'marketGear', + path: 'gear.flat.head_special_nye2020', + _id: uuid(), + }, + ]; + } else if (typeof user.items.gear.owned.head_special_nye2018 !== 'undefined') { + set['items.gear.owned.head_special_nye2019'] = false; + push = [ + { + type: 'marketGear', + path: 'gear.flat.head_special_nye2019', + _id: uuid(), + }, + ]; + } else if (typeof user.items.gear.owned.head_special_nye2017 !== 'undefined') { + set['items.gear.owned.head_special_nye2018'] = false; + push = [ + { + type: 'marketGear', + path: 'gear.flat.head_special_nye2018', + _id: uuid(), + }, + ]; + } else if (typeof user.items.gear.owned.head_special_nye2016 !== 'undefined') { + set['items.gear.owned.head_special_nye2017'] = false; + push = [ + { + type: 'marketGear', + path: 'gear.flat.head_special_nye2017', + _id: uuid(), + }, + ]; + } else if (typeof user.items.gear.owned.head_special_nye2015 !== 'undefined') { + set['items.gear.owned.head_special_nye2016'] = false; + push = [ + { + type: 'marketGear', + path: 'gear.flat.head_special_nye2016', + _id: uuid(), + }, + ]; + } else if (typeof user.items.gear.owned.head_special_nye2014 !== 'undefined') { + set['items.gear.owned.head_special_nye2015'] = false; + push = [ + { + type: 'marketGear', + path: 'gear.flat.head_special_nye2015', + _id: uuid(), + }, + ]; + } else if (typeof user.items.gear.owned.head_special_nye !== 'undefined') { + set['items.gear.owned.head_special_nye2014'] = false; + push = [ + { + type: 'marketGear', + path: 'gear.flat.head_special_nye2014', + _id: uuid(), + }, + ]; + } else { + set['items.gear.owned.head_special_nye'] = false; + push = [ + { + type: 'marketGear', + path: 'gear.flat.head_special_nye', + _id: uuid(), + }, + ]; + } + + if (count % progressCount === 0) console.warn(`${count} ${user._id}`); + + return await User.update({_id: user._id}, {$set: set, $push: {pinnedItems: {$each: push}}}).exec(); +} + +export default async function processUsers () { + let query = { + 'auth.timestamps.loggedin': {$gt: new Date('2022-12-01')}, + migration: {$ne: MIGRATION_NAME}, + }; + + 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/client/src/assets/css/sprites/spritesmith-main.css b/website/client/src/assets/css/sprites/spritesmith-main.css index 1f4657bda7..d90ff37a04 100644 --- a/website/client/src/assets/css/sprites/spritesmith-main.css +++ b/website/client/src/assets/css/sprites/spritesmith-main.css @@ -31355,6 +31355,11 @@ width: 114px; height: 90px; } +.head_special_nye2022 { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/head_special_nye2022.png'); + width: 114px; + height: 90px; +} .head_special_ski { background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/head_special_ski.png'); width: 90px; @@ -31950,6 +31955,11 @@ width: 68px; height: 68px; } +.shop_head_special_nye2022 { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_head_special_nye2022.png'); + width: 68px; + height: 68px; +} .shop_head_special_ski { background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_head_special_ski.png'); width: 68px; @@ -32295,6 +32305,11 @@ width: 68px; height: 68px; } +.shop_weapon_special_Winter2023Rogue { + background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_weapon_special_Winter2023Rogue.png'); + width: 68px; + height: 68px; +} .shop_weapon_special_candycane { background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_weapon_special_candycane.png'); width: 68px; @@ -32480,11 +32495,6 @@ width: 68px; height: 68px; } -.shop_weapon_special_winter2023Rogue { - background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_weapon_special_winter2023Rogue.png'); - width: 68px; - height: 68px; -} .shop_weapon_special_winter2023Warrior { background-image: url('https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_weapon_special_winter2023Warrior.png'); width: 68px; diff --git a/website/common/locales/en/gear.json b/website/common/locales/en/gear.json index d78ac5111c..aa78ba0b1e 100644 --- a/website/common/locales/en/gear.json +++ b/website/common/locales/en/gear.json @@ -438,6 +438,9 @@ "headSpecialNye2021Text": "Preposterous Party Hat", "headSpecialNye2021Notes": "You've received a Preposterous Party Hat! Wear it with pride while ringing in the New Year! Confers no benefit.", + "headSpecialNye2022Text": "Fantastic Party Hat", + "headSpecialNye2022Notes": "You've received a Fantastic Party Hat! Wear it with pride while ringing in the New Year! Confers no benefit.", + "weaponSpecialSpring2022RogueText": "Giant Earring Stud", "weaponSpecialSpring2022RogueNotes": "A shiny! It’s so shiny and gleaming and pretty and nice and all yours! Increases Strength by <%= str %>. Limited Edition 2022 Spring Gear.", "weaponSpecialSpring2022WarriorText": "Inside-Out Umbrella", diff --git a/website/common/script/content/gear/sets/special/index.js b/website/common/script/content/gear/sets/special/index.js index 485e54ec83..85f7e12284 100644 --- a/website/common/script/content/gear/sets/special/index.js +++ b/website/common/script/content/gear/sets/special/index.js @@ -1932,6 +1932,12 @@ const head = { winter2023Healer: { set: 'winter2023CardinalHealerSet', }, + nye2022: { + text: t('headSpecialNye2022Text'), + notes: t('headSpecialNye2022Notes'), + value: 0, + canOwn: ownsItem('head_special_nye2022'), + }, }; const headStats = { diff --git a/website/server/models/user/hooks.js b/website/server/models/user/hooks.js index 6bafec1bd1..9106f4173a 100644 --- a/website/server/models/user/hooks.js +++ b/website/server/models/user/hooks.js @@ -150,10 +150,10 @@ function _setUpNewUser (user) { user.items.quests.dustbunnies = 1; user.purchased.background.violet = true; user.preferences.background = 'violet'; - if (moment().isBetween('2022-11-22T08:00-05:00', '2022-11-27T20:00-05:00')) { - user.migration = '20221122_harvest_feast'; - user.items.pets['Turkey-Base'] = 5; - user.items.currentPet = 'Turkey-Base'; + if (moment().isBetween('2022-12-27T08:00-05:00', '2023-01-02T20:00-05:00')) { + user.migration = '20221227_nye'; + user.items.gear.owned.head_special_nye = true; + user.items.gear.equipped.head = 'head_special_nye'; } user.markModified('items achievements');