Merge branch 'sabrecat/kickstarter-2019' into release
67
migrations/archive/2019/20190927_kickstarter.js
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
/* eslint-disable no-console */
|
||||||
|
const MIGRATION_NAME = '20190927_kickstarter';
|
||||||
|
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 set = {};
|
||||||
|
let push = {pinnedItems: {$each: []}};
|
||||||
|
|
||||||
|
set.migration = MIGRATION_NAME;
|
||||||
|
set['achievements.ks2019'] = true;
|
||||||
|
|
||||||
|
// set['items.gear.owned.armor_special_ks2019'] = false;
|
||||||
|
// push.pinnedItems.$each.push({type: 'marketGear', path: 'gear.flat.armor_special_ks2019', _id: uuid()});
|
||||||
|
set['items.gear.owned.head_special_ks2019'] = false;
|
||||||
|
push.pinnedItems.$each.push({type: 'marketGear', path: 'gear.flat.head_special_ks2019', _id: uuid()});
|
||||||
|
// set['items.gear.owned.shield_special_ks2019'] = false;
|
||||||
|
// push.pinnedItems.$each.push({type: 'marketGear', path: 'gear.flat.shield_special_ks2019', _id: uuid()});
|
||||||
|
// set['items.gear.owned.weapon_special_ks2019'] = false;
|
||||||
|
// push.pinnedItems.$each.push({type: 'marketGear', path: 'gear.flat.weapon_special_ks2019', _id: uuid()});
|
||||||
|
set['items.gear.owned.eyewear_special_ks2019'] = false;
|
||||||
|
push.pinnedItems.$each.push({type: 'marketGear', path: 'gear.flat.eyewear_special_ks2019', _id: uuid()});
|
||||||
|
// set['items.pets.Gryphon-Gryphatrice'] = 5;
|
||||||
|
// set['items.mounts.Gryphon-Gryphatrice'] = true;
|
||||||
|
|
||||||
|
return await User.update({_id: user._id}, {$set: set, $push: push}).exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = async function processUsers () {
|
||||||
|
let query = {
|
||||||
|
migration: {$ne: MIGRATION_NAME},
|
||||||
|
'auth.local.lowerCaseUsername': {$in: []},
|
||||||
|
};
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -96,6 +96,52 @@
|
|||||||
background: url("~assets/images/BackerOnly-Pet-CerberusPup.gif") no-repeat;
|
background: url("~assets/images/BackerOnly-Pet-CerberusPup.gif") no-repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.broad_armor_special_ks2019, .slim_armor_special_ks2019, .eyewear_special_ks2019, .head_special_ks2019, .shield_special_ks2019 {
|
||||||
|
width: 117px;
|
||||||
|
height: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.broad_armor_special_ks2019, .slim_armor_special_ks2019 {
|
||||||
|
background: url("~assets/images/BackerOnly-Equip-MythicGryphonArmor.gif") no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eyewear_special_ks2019 {
|
||||||
|
background: url("~assets/images/BackerOnly-Equip-MythicGryphonVisor.gif") no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head_special_ks2019 {
|
||||||
|
background: url("~assets/images/BackerOnly-Equip-MythicGryphonHelm.gif") no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shield_special_ks2019 {
|
||||||
|
background: url("~assets/images/BackerOnly-Equip-MythicGryphonShield.gif") no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
.weapon_special_ks2019 {
|
||||||
|
background: url("~assets/images/BackerOnly-Equip-MythicGryphonGlaive.gif") no-repeat;
|
||||||
|
width: 120px;
|
||||||
|
height: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Pet-Gryphon-Gryphatrice {
|
||||||
|
background: url("~assets/images/BackerOnly-Pet-Gryphatrice.gif") no-repeat;
|
||||||
|
width: 81px;
|
||||||
|
height: 99px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Mount_Head_Gryphon-Gryphatrice, .Mount_Body_Gryphon-Gryphatrice {
|
||||||
|
width: 135px;
|
||||||
|
height: 135px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Mount_Head_Gryphon-Gryphatrice {
|
||||||
|
background: url("~assets/images/BackerOnly-Mount-Head-Gryphatrice.gif") no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Mount_Body_Gryphon-Gryphatrice {
|
||||||
|
background: url("~assets/images/BackerOnly-Mount-Body-Gryphatrice.gif") no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
/* FIXME figure out how to handle customize menu!!
|
/* FIXME figure out how to handle customize menu!!
|
||||||
.customize-menu .f_head_0 {
|
.customize-menu .f_head_0 {
|
||||||
width: 60px;
|
width: 60px;
|
||||||
|
|||||||
|
After Width: | Height: | Size: 9.6 KiB |
|
After Width: | Height: | Size: 9.1 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 992 B |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 29 KiB |
BIN
website/client/assets/images/BackerOnly-Pet-Gryphatrice.gif
Normal file
|
After Width: | Height: | Size: 17 KiB |
@@ -24,5 +24,7 @@
|
|||||||
"achievementDustDevilModalText": "You collected all the Desert Pets!",
|
"achievementDustDevilModalText": "You collected all the Desert Pets!",
|
||||||
"achievementAridAuthority": "Arid Authority",
|
"achievementAridAuthority": "Arid Authority",
|
||||||
"achievementAridAuthorityText": "Has tamed all Desert Mounts.",
|
"achievementAridAuthorityText": "Has tamed all Desert Mounts.",
|
||||||
"achievementAridAuthorityModalText": "You tamed all the Desert Mounts!"
|
"achievementAridAuthorityModalText": "You tamed all the Desert Mounts!",
|
||||||
|
"achievementKickstarter2019": "Pin Kickstarter Backer",
|
||||||
|
"achievementKickstarter2019Text": "Backed the 2019 Pin Kickstarter Project"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -122,6 +122,8 @@
|
|||||||
"weaponSpecialTachiNotes": "This light and curved sword will shred your tasks to ribbons! Increases Strength by <%= str %>.",
|
"weaponSpecialTachiNotes": "This light and curved sword will shred your tasks to ribbons! Increases Strength by <%= str %>.",
|
||||||
"weaponSpecialAetherCrystalsText": "Aether Crystals",
|
"weaponSpecialAetherCrystalsText": "Aether Crystals",
|
||||||
"weaponSpecialAetherCrystalsNotes": "These bracers and crystals once belonged to the Lost Masterclasser herself. Increases all Stats by <%= attrs %>.",
|
"weaponSpecialAetherCrystalsNotes": "These bracers and crystals once belonged to the Lost Masterclasser herself. Increases all Stats by <%= attrs %>.",
|
||||||
|
"weaponSpecialKS2019Text": "Mythic Gryphon Glaive",
|
||||||
|
"weaponSpecialKS2019Notes": "Curved as a gryphon's beak and talons, this ornate polearm reminds you to power through when the task ahead feels daunting. Increases Strength by <%= str %>.",
|
||||||
|
|
||||||
"weaponSpecialYetiText": "Yeti-Tamer Spear",
|
"weaponSpecialYetiText": "Yeti-Tamer Spear",
|
||||||
"weaponSpecialYetiNotes": "This spear allows its user to command any yeti. Increases Strength by <%= str %>. Limited Edition 2013-2014 Winter Gear.",
|
"weaponSpecialYetiNotes": "This spear allows its user to command any yeti. Increases Strength by <%= str %>. Limited Edition 2013-2014 Winter Gear.",
|
||||||
@@ -539,6 +541,8 @@
|
|||||||
"armorSpecialTurkeyArmorBaseNotes": "Keep your drumsticks warm and cozy in this feathery armor! Confers no benefit.",
|
"armorSpecialTurkeyArmorBaseNotes": "Keep your drumsticks warm and cozy in this feathery armor! Confers no benefit.",
|
||||||
"armorSpecialTurkeyArmorGildedText": "Gilded Turkey Armor",
|
"armorSpecialTurkeyArmorGildedText": "Gilded Turkey Armor",
|
||||||
"armorSpecialTurkeyArmorGildedNotes": "Strut your stuff in this seasonally shiny armor! Confers no benefit.",
|
"armorSpecialTurkeyArmorGildedNotes": "Strut your stuff in this seasonally shiny armor! Confers no benefit.",
|
||||||
|
"armorSpecialKS2019Text": "Mythic Gryphon Armor",
|
||||||
|
"armorSpecialKS2019Notes": "Glowing from within like a gryphon's noble heart, this resplendent armor encourages you to take pride in your accomplishments. Increases Constitution by <%= con %>.",
|
||||||
|
|
||||||
"armorSpecialYetiText": "Yeti-Tamer Robe",
|
"armorSpecialYetiText": "Yeti-Tamer Robe",
|
||||||
"armorSpecialYetiNotes": "Fuzzy and fierce. Increases Constitution by <%= con %>. Limited Edition 2013-2014 Winter Gear.",
|
"armorSpecialYetiNotes": "Fuzzy and fierce. Increases Constitution by <%= con %>. Limited Edition 2013-2014 Winter Gear.",
|
||||||
@@ -1067,6 +1071,8 @@
|
|||||||
"headSpecialTurkeyHelmGildedNotes": "Gobble gobble! Bling bling! Confers no benefit.",
|
"headSpecialTurkeyHelmGildedNotes": "Gobble gobble! Bling bling! Confers no benefit.",
|
||||||
"headSpecialPiDayText": "Pi Hat",
|
"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.",
|
"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.",
|
||||||
|
"headSpecialKS2019Text": "Mythic Gryphon Helm",
|
||||||
|
"headSpecialKS2019Notes": "Adorned with a gryphon's likeness and plumage, this glorious helmet symbolizes the way your skills and bearing stand as an example to others. Increases Intelligence by <%= int %>.",
|
||||||
|
|
||||||
"headSpecialNyeText": "Absurd Party Hat",
|
"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.",
|
"headSpecialNyeNotes": "You've received an Absurd Party Hat! Wear it with pride while ringing in the New Year! Confers no benefit.",
|
||||||
@@ -1563,6 +1569,8 @@
|
|||||||
"shieldSpecialWakizashiNotes": "This short sword is perfect for close-quarters battles with your Dailies! Increases Constitution by <%= con %>.",
|
"shieldSpecialWakizashiNotes": "This short sword is perfect for close-quarters battles with your Dailies! Increases Constitution by <%= con %>.",
|
||||||
"shieldSpecialPiDayText": "Pi Shield",
|
"shieldSpecialPiDayText": "Pi Shield",
|
||||||
"shieldSpecialPiDayNotes": "We dare you to calculate the ratio of this shield's circumference to its deliciousness! Confers no benefit.",
|
"shieldSpecialPiDayNotes": "We dare you to calculate the ratio of this shield's circumference to its deliciousness! Confers no benefit.",
|
||||||
|
"shieldSpecialKS2019Text": "Mythic Gryphon Shield",
|
||||||
|
"shieldSpecialKS2019Notes": "Sparkling like the shell of a gryphon egg, this magnificent shield shows you how to stand ready to help when your own burdens are light. Increases Perception by <%= per %>.",
|
||||||
|
|
||||||
"shieldSpecialYetiText": "Yeti-Tamer Shield",
|
"shieldSpecialYetiText": "Yeti-Tamer Shield",
|
||||||
"shieldSpecialYetiNotes": "This shield reflects light from the snow. Increases Constitution by <%= con %>. Limited Edition 2013-2014 Winter Gear.",
|
"shieldSpecialYetiNotes": "This shield reflects light from the snow. Increases Constitution by <%= con %>. Limited Edition 2013-2014 Winter Gear.",
|
||||||
@@ -2063,6 +2071,8 @@
|
|||||||
|
|
||||||
"eyewearSpecialAetherMaskText": "Aether Mask",
|
"eyewearSpecialAetherMaskText": "Aether Mask",
|
||||||
"eyewearSpecialAetherMaskNotes": "This mask has a mysterious history. Increases Intelligence by <%= int %>.",
|
"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.",
|
||||||
|
|
||||||
"eyewearSpecialSummerRogueText": "Roguish Eyepatch",
|
"eyewearSpecialSummerRogueText": "Roguish Eyepatch",
|
||||||
"eyewearSpecialSummerRogueNotes": "It doesn't take a scallywag to see how stylish this is! Confers no benefit. Limited Edition 2014 Summer Gear.",
|
"eyewearSpecialSummerRogueNotes": "It doesn't take a scallywag to see how stylish this is! Confers no benefit. Limited Edition 2014 Summer Gear.",
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
"hopefulHippogriffMount": "Hopeful Hippogriff",
|
"hopefulHippogriffMount": "Hopeful Hippogriff",
|
||||||
"royalPurpleJackalope": "Royal Purple Jackalope",
|
"royalPurpleJackalope": "Royal Purple Jackalope",
|
||||||
"invisibleAether": "Invisible Aether",
|
"invisibleAether": "Invisible Aether",
|
||||||
|
"gryphatrice": "Gryphatrice",
|
||||||
"rarePetPop1": "Click the gold paw to learn more about how you can obtain this rare pet through contributing to Habitica!",
|
"rarePetPop1": "Click the gold paw to learn more about how you can obtain this rare pet through contributing to Habitica!",
|
||||||
"rarePetPop2": "How to Get this Pet!",
|
"rarePetPop2": "How to Get this Pet!",
|
||||||
"potion": "<%= potionType %> Potion",
|
"potion": "<%= potionType %> Potion",
|
||||||
|
|||||||
@@ -193,6 +193,11 @@ let specialAchievs = {
|
|||||||
pluralTitleKey: 'helped',
|
pluralTitleKey: 'helped',
|
||||||
pluralTextKey: 'surveysMultiple',
|
pluralTextKey: 'surveysMultiple',
|
||||||
},
|
},
|
||||||
|
kickstarter2019: {
|
||||||
|
icon: 'achievement-kickstarter2019',
|
||||||
|
titleKey: 'achievementKickstarter2019',
|
||||||
|
textKey: 'achievementKickstarter2019Text',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
Object.assign(achievementsData, specialAchievs);
|
Object.assign(achievementsData, specialAchievs);
|
||||||
|
|
||||||
|
|||||||
@@ -1257,6 +1257,13 @@ let armor = {
|
|||||||
value: 90,
|
value: 90,
|
||||||
con: 15,
|
con: 15,
|
||||||
},
|
},
|
||||||
|
ks2019: {
|
||||||
|
text: t('armorSpecialKS2019Text'),
|
||||||
|
notes: t('armorSpecialKS2019Notes', { con: 20 }),
|
||||||
|
value: 0,
|
||||||
|
con: 20,
|
||||||
|
canOwn: ownsItem('armor_special_ks2019'),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let back = {
|
let back = {
|
||||||
@@ -1602,6 +1609,12 @@ let eyewear = {
|
|||||||
notes: t('eyewearSpecialFall2019HealerNotes'),
|
notes: t('eyewearSpecialFall2019HealerNotes'),
|
||||||
value: 20,
|
value: 20,
|
||||||
},
|
},
|
||||||
|
ks2019: {
|
||||||
|
text: t('eyewearSpecialKS2019Text'),
|
||||||
|
notes: t('eyewearSpecialKS2019Notes'),
|
||||||
|
value: 0,
|
||||||
|
canOwn: ownsItem('eyewear_special_ks2019'),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let head = {
|
let head = {
|
||||||
@@ -2865,6 +2878,13 @@ let head = {
|
|||||||
value: 60,
|
value: 60,
|
||||||
int: 7,
|
int: 7,
|
||||||
},
|
},
|
||||||
|
ks2019: {
|
||||||
|
text: t('headSpecialKS2019Text'),
|
||||||
|
notes: t('headSpecialKS2019Notes', { int: 20 }),
|
||||||
|
value: 0,
|
||||||
|
int: 20,
|
||||||
|
canOwn: ownsItem('head_special_ks2019'),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let headAccessory = {
|
let headAccessory = {
|
||||||
@@ -4079,6 +4099,13 @@ let shield = {
|
|||||||
value: 70,
|
value: 70,
|
||||||
con: 9,
|
con: 9,
|
||||||
},
|
},
|
||||||
|
ks2019: {
|
||||||
|
text: t('shieldSpecialKS2019Text'),
|
||||||
|
notes: t('shieldSpecialKS2019Notes', { per: 20 }),
|
||||||
|
value: 0,
|
||||||
|
per: 20,
|
||||||
|
canOwn: ownsItem('shield_special_ks2019'),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let weapon = {
|
let weapon = {
|
||||||
@@ -5332,6 +5359,13 @@ let weapon = {
|
|||||||
value: 90,
|
value: 90,
|
||||||
int: 9,
|
int: 9,
|
||||||
},
|
},
|
||||||
|
ks2019: {
|
||||||
|
text: t('weaponSpecialKS2019Text'),
|
||||||
|
notes: t('weaponSpecialKS2019Notes', { str: 20 }),
|
||||||
|
value: 0,
|
||||||
|
str: 20,
|
||||||
|
canOwn: ownsItem('weapon_special_ks2019'),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let specialSet = {
|
let specialSet = {
|
||||||
|
|||||||
@@ -103,6 +103,7 @@ let specialPets = {
|
|||||||
'Hippogriff-Hopeful': 'hopefulHippogriffPet',
|
'Hippogriff-Hopeful': 'hopefulHippogriffPet',
|
||||||
'Fox-Veteran': 'veteranFox',
|
'Fox-Veteran': 'veteranFox',
|
||||||
'JackOLantern-Glow': 'glowJackolantern',
|
'JackOLantern-Glow': 'glowJackolantern',
|
||||||
|
'Gryphon-Gryphatrice': 'gryphatrice',
|
||||||
};
|
};
|
||||||
|
|
||||||
let specialMounts = {
|
let specialMounts = {
|
||||||
@@ -121,6 +122,7 @@ let specialMounts = {
|
|||||||
'Aether-Invisible': 'invisibleAether',
|
'Aether-Invisible': 'invisibleAether',
|
||||||
'JackOLantern-Ghost': 'ghostJackolantern',
|
'JackOLantern-Ghost': 'ghostJackolantern',
|
||||||
'Hippogriff-Hopeful': 'hopefulHippogriffMount',
|
'Hippogriff-Hopeful': 'hopefulHippogriffMount',
|
||||||
|
'Gryphon-Gryphatrice': 'gryphatrice',
|
||||||
};
|
};
|
||||||
|
|
||||||
each(specialPets, (translationString, key) => {
|
each(specialPets, (translationString, key) => {
|
||||||
|
|||||||
@@ -300,6 +300,10 @@ function _getSpecialAchievements (user, language) {
|
|||||||
_addSimple(result, user, {path: 'originalUser', language});
|
_addSimple(result, user, {path: 'originalUser', language});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (user.achievements.kickstarter2019) {
|
||||||
|
_addSimple(result, user, {path: 'kickstarter2019', language});
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
|
After Width: | Height: | Size: 6.6 KiB |
|
After Width: | Height: | Size: 824 B |
|
After Width: | Height: | Size: 263 B |
|
After Width: | Height: | Size: 878 B |
|
After Width: | Height: | Size: 458 B |
|
After Width: | Height: | Size: 680 B |
|
After Width: | Height: | Size: 3.4 KiB |
@@ -127,6 +127,7 @@ let schema = new Schema({
|
|||||||
allYourBase: Boolean,
|
allYourBase: Boolean,
|
||||||
dustDevil: Boolean,
|
dustDevil: Boolean,
|
||||||
aridAuthority: Boolean,
|
aridAuthority: Boolean,
|
||||||
|
kickstarter2019: Boolean,
|
||||||
},
|
},
|
||||||
|
|
||||||
backer: {
|
backer: {
|
||||||
|
|||||||