Adventure Guide Prep (#11883)
* WIP(adventure): prereqs * WIP(drops): new modal * WIP(adventure): analytics fixes etc * feat(adventure): random egg+potion on 2nd task * fix(lint): noworkies * fix(modal): correctly construct classes * fix(tests): expectations and escape * fix(first-drops): address comments * fix(first-drops): don't give random drops until first drops * fix(drops): remove more Level 3 references * refactor(drops): no need for cloning * refactor(drops): unnecessary export * fix(first-drops): force sync * fix(first-drops): move to server * fix(first-drops): escape in case we get here with >0 items * fix(lint): line length * fix(pet-food): remove unused string
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
import { drops as eggs } from '../content/eggs';
|
||||
import { drops as hatchingPotions } from '../content/hatching-potions';
|
||||
import randomVal from '../libs/randomVal';
|
||||
|
||||
export default function firstDrops (user) {
|
||||
const eggDrop = randomVal(eggs);
|
||||
const potionDrop = randomVal(hatchingPotions);
|
||||
|
||||
user.items.eggs = {
|
||||
...user.items.eggs,
|
||||
[eggDrop.key]: user.items.eggs[eggDrop.key] || 0,
|
||||
};
|
||||
user.items.eggs[eggDrop.key] += 1;
|
||||
if (user.markModified) user.markModified('items.eggs');
|
||||
|
||||
user.items.hatchingPotions = {
|
||||
...user.items.hatchingPotions,
|
||||
[potionDrop.key]: user.items.hatchingPotions[potionDrop.key] || 0,
|
||||
};
|
||||
user.items.hatchingPotions[potionDrop.key] += 1;
|
||||
if (user.markModified) user.markModified('items.hatchingPotions');
|
||||
|
||||
if (user.addNotification) user.addNotification('FIRST_DROPS', { egg: eggDrop.key, hatchingPotion: potionDrop.key });
|
||||
|
||||
return ({ egg: eggDrop.key, hatchingPotion: potionDrop.key });
|
||||
}
|
||||
@@ -4,12 +4,15 @@ import min from 'lodash/min';
|
||||
import reduce from 'lodash/reduce';
|
||||
import filter from 'lodash/filter';
|
||||
import pickBy from 'lodash/pickBy';
|
||||
import size from 'lodash/size';
|
||||
import moment from 'moment';
|
||||
import content from '../content/index';
|
||||
import i18n from '../i18n';
|
||||
import { daysSince } from '../cron';
|
||||
import { diminishingReturns } from '../statHelpers';
|
||||
import randomVal from '../libs/randomVal';
|
||||
import statsComputed from '../libs/statsComputed';
|
||||
import firstDrops from './firstDrops';
|
||||
|
||||
// TODO This is only used on the server
|
||||
// move to user model as an instance method?
|
||||
@@ -30,6 +33,14 @@ export default function randomDrop (user, options, req = {}, analytics) {
|
||||
let dropMultiplier;
|
||||
let rarity;
|
||||
|
||||
if (
|
||||
size(user.items.eggs) < 1
|
||||
&& size(user.items.hatchingPotions) < 1
|
||||
) {
|
||||
user._tmp.firstDrops = firstDrops(user);
|
||||
return;
|
||||
}
|
||||
|
||||
const predictableRandom = options.predictableRandom || trueRandom;
|
||||
const { task } = options;
|
||||
|
||||
@@ -71,7 +82,7 @@ export default function randomDrop (user, options, req = {}, analytics) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (user.flags && user.flags.dropsEnabled && predictableRandom() < chance) {
|
||||
if (predictableRandom() < chance) {
|
||||
rarity = predictableRandom();
|
||||
|
||||
if (rarity > 0.6) { // food 40% chance
|
||||
@@ -135,7 +146,7 @@ export default function randomDrop (user, options, req = {}, analytics) {
|
||||
}, req.language);
|
||||
}
|
||||
|
||||
if (analytics) {
|
||||
if (analytics && moment().diff(user.auth.timestamps.created, 'days') < 7) {
|
||||
analytics.track('dropped item', {
|
||||
uuid: user._id,
|
||||
itemKey: drop.key,
|
||||
|
||||
@@ -66,24 +66,6 @@ export default function updateStats (user, stats, req = {}, analytics) {
|
||||
if (!user.flags.itemsEnabled && (user.stats.exp > 10 || user.stats.lvl > 1)) {
|
||||
user.flags.itemsEnabled = true;
|
||||
}
|
||||
if (!user.flags.dropsEnabled && user.stats.lvl >= 3) {
|
||||
user.flags.dropsEnabled = true;
|
||||
if (user.addNotification) user.addNotification('DROPS_ENABLED');
|
||||
|
||||
if (user.items.eggs.Wolf > 0) {
|
||||
user.items.eggs = {
|
||||
...user.items.eggs,
|
||||
Wolf: user.items.eggs.Wolf + 1,
|
||||
};
|
||||
} else {
|
||||
user.items.eggs = {
|
||||
...user.items.eggs,
|
||||
Wolf: 1,
|
||||
};
|
||||
}
|
||||
|
||||
if (user.markModified) user.markModified('items.eggs');
|
||||
}
|
||||
each({
|
||||
vice1: 30,
|
||||
atom1: 15,
|
||||
|
||||
@@ -23,9 +23,16 @@ export function onOnboardingComplete (user) {
|
||||
}
|
||||
|
||||
// Add notification and awards (server)
|
||||
export function checkOnboardingStatus (user) {
|
||||
export function checkOnboardingStatus (user, analytics) {
|
||||
if (hasActiveOnboarding(user) && hasCompletedOnboarding(user) && user.addNotification) {
|
||||
user.addNotification('ONBOARDING_COMPLETE');
|
||||
if (analytics) {
|
||||
analytics.track('onboarding complete', {
|
||||
uuid: user._id,
|
||||
hitType: 'event',
|
||||
category: 'behavior',
|
||||
});
|
||||
}
|
||||
onOnboardingComplete(user);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ export class AbstractBuyOperation {
|
||||
|
||||
this.extractAndValidateParams(this.user, this.req);
|
||||
|
||||
const resultObj = this.executeChanges(this.user, this.item, this.req);
|
||||
const resultObj = this.executeChanges(this.user, this.item, this.req, this.analytics);
|
||||
|
||||
if (this.analytics) {
|
||||
this.sendToAnalytics(this.analyticsData());
|
||||
|
||||
@@ -60,7 +60,7 @@ export class BuyMarketGearOperation extends AbstractGoldItemOperation { // eslin
|
||||
}
|
||||
}
|
||||
|
||||
executeChanges (user, item, req) {
|
||||
executeChanges (user, item, req, analytics) {
|
||||
let message;
|
||||
|
||||
if (user.preferences.autoEquip) {
|
||||
@@ -70,7 +70,7 @@ export class BuyMarketGearOperation extends AbstractGoldItemOperation { // eslin
|
||||
|
||||
if (!user.achievements.purchasedEquipment && user.addAchievement) {
|
||||
user.addAchievement('purchasedEquipment');
|
||||
checkOnboardingStatus(user);
|
||||
checkOnboardingStatus(user, analytics);
|
||||
}
|
||||
|
||||
removePinnedGearAddPossibleNewOnes(user, `gear.flat.${item.key}`, item.key);
|
||||
|
||||
@@ -3,6 +3,7 @@ import findIndex from 'lodash/findIndex';
|
||||
import get from 'lodash/get';
|
||||
import keys from 'lodash/keys';
|
||||
import upperFirst from 'lodash/upperFirst';
|
||||
import moment from 'moment';
|
||||
import i18n from '../i18n';
|
||||
import content from '../content/index';
|
||||
import {
|
||||
@@ -34,7 +35,7 @@ function evolve (user, pet, req) {
|
||||
}, req.language);
|
||||
}
|
||||
|
||||
export default function feed (user, req = {}) {
|
||||
export default function feed (user, req = {}, analytics) {
|
||||
let pet = get(req, 'params.pet');
|
||||
const foodK = get(req, 'params.food');
|
||||
|
||||
@@ -94,7 +95,7 @@ export default function feed (user, req = {}) {
|
||||
|
||||
if (!user.achievements.fedPet && user.addAchievement) {
|
||||
user.addAchievement('fedPet');
|
||||
checkOnboardingStatus(user);
|
||||
checkOnboardingStatus(user, analytics);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,6 +119,16 @@ export default function feed (user, req = {}) {
|
||||
}
|
||||
});
|
||||
|
||||
if (analytics && moment().diff(user.auth.timestamps.created, 'days') < 7) {
|
||||
analytics.track('pet feed', {
|
||||
uuid: user._id,
|
||||
foodKey: food.key,
|
||||
petKey: pet.key,
|
||||
category: 'behavior',
|
||||
headers: req.headers,
|
||||
});
|
||||
}
|
||||
|
||||
return [
|
||||
user.items.pets[pet.key],
|
||||
message,
|
||||
|
||||
@@ -3,6 +3,7 @@ import forEach from 'lodash/forEach';
|
||||
import get from 'lodash/get';
|
||||
import keys from 'lodash/keys';
|
||||
import upperFirst from 'lodash/upperFirst';
|
||||
import moment from 'moment';
|
||||
import i18n from '../i18n';
|
||||
import content from '../content/index';
|
||||
import {
|
||||
@@ -13,7 +14,7 @@ import {
|
||||
import errorMessage from '../libs/errorMessage';
|
||||
import { checkOnboardingStatus } from '../libs/onboarding';
|
||||
|
||||
export default function hatch (user, req = {}) {
|
||||
export default function hatch (user, req = {}, analytics) {
|
||||
const egg = get(req, 'params.egg');
|
||||
const hatchingPotion = get(req, 'params.hatchingPotion');
|
||||
|
||||
@@ -55,7 +56,7 @@ export default function hatch (user, req = {}) {
|
||||
|
||||
if (!user.achievements.hatchedPet && user.addAchievement) {
|
||||
user.addAchievement('hatchedPet');
|
||||
checkOnboardingStatus(user);
|
||||
checkOnboardingStatus(user, analytics);
|
||||
}
|
||||
|
||||
forEach(content.animalColorAchievements, achievement => {
|
||||
@@ -78,6 +79,15 @@ export default function hatch (user, req = {}) {
|
||||
}
|
||||
});
|
||||
|
||||
if (analytics && moment().diff(user.auth.timestamps.created, 'days') < 7) {
|
||||
analytics.track('pet hatch', {
|
||||
uuid: user._id,
|
||||
petKey: pet,
|
||||
category: 'behavior',
|
||||
headers: req.headers,
|
||||
});
|
||||
}
|
||||
|
||||
return [
|
||||
user.items,
|
||||
i18n.t('messageHatched', req.language),
|
||||
|
||||
@@ -189,7 +189,7 @@ function _updateCounter (task, direction, times) {
|
||||
}
|
||||
}
|
||||
|
||||
export default function scoreTask (options = {}, req = {}) {
|
||||
export default function scoreTask (options = {}, req = {}, analytics) {
|
||||
const {
|
||||
user, task, direction, times = 1, cron = false,
|
||||
} = options;
|
||||
@@ -347,7 +347,7 @@ export default function scoreTask (options = {}, req = {}) {
|
||||
|
||||
if (!user.achievements.completedTask && cron === false && direction === 'up' && user.addAchievement) {
|
||||
user.addAchievement('completedTask');
|
||||
checkOnboardingStatus(user);
|
||||
checkOnboardingStatus(user, analytics);
|
||||
}
|
||||
|
||||
return [delta];
|
||||
|
||||
Reference in New Issue
Block a user