New 'userStatIncNewVal' achievement type

This commit is contained in:
Bryan Ashby 2019-01-24 21:53:31 -07:00
parent ae2a225e3a
commit aa9cd8899c
1 changed files with 134 additions and 8 deletions

View File

@ -52,6 +52,7 @@ class Achievement {
switch(data.type) { switch(data.type) {
case Achievement.Types.UserStatSet : case Achievement.Types.UserStatSet :
case Achievement.Types.UserStatInc : case Achievement.Types.UserStatInc :
case Achievement.Types.UserStatIncNewVal :
achievement = new UserStatAchievement(data); achievement = new UserStatAchievement(data);
break; break;
@ -67,6 +68,7 @@ class Achievement {
return { return {
UserStatSet : 'userStatSet', UserStatSet : 'userStatSet',
UserStatInc : 'userStatInc', UserStatInc : 'userStatInc',
UserStatIncNewVal : 'userStatIncNewVal',
}; };
} }
@ -74,6 +76,7 @@ class Achievement {
switch(this.data.type) { switch(this.data.type) {
case Achievement.Types.UserStatSet : case Achievement.Types.UserStatSet :
case Achievement.Types.UserStatInc : case Achievement.Types.UserStatInc :
case Achievement.Types.UserStatIncNewVal :
if(!_.isString(this.data.statName)) { if(!_.isString(this.data.statName)) {
return false; return false;
} }
@ -286,14 +289,135 @@ class Achievements {
} }
// :TODO: Make this code generic - find + return factory created object // :TODO: Make this code generic - find + return factory created object
const achievementTags = Object.keys(_.pickBy(
_.get(this.achievementConfig, 'achievements', {}),
achievement => {
if(false === achievement.enabled) {
return false;
}
const acceptedTypes = [
Achievement.Types.UserStatSet,
Achievement.Types.UserStatInc,
Achievement.Types.UserStatIncNewVal,
];
return acceptedTypes.includes(achievement.type) && achievement.statName === userStatEvent.statName;
}
));
if(0 === achievementTags.length) {
return;
}
async.eachSeries(achievementTags, (achievementTag, nextAchievementTag) => {
const achievement = Achievement.factory(this.getAchievementByTag(achievementTag));
if(!achievement) {
return nextAchievementTag(null);
}
const statValue = parseInt(
[ Achievement.Types.UserStatSet, Achievement.Types.UserStatIncNewVal ].includes(achievement.data.type) ?
userStatEvent.statValue :
userStatEvent.statIncrementBy
);
if(isNaN(statValue)) {
return nextAchievementTag(null);
}
const [ details, matchField, matchValue ] = achievement.getMatchDetails(statValue);
if(!details) {
return nextAchievementTag(null);
}
async.series(
[
(callback) => {
this.loadAchievementHitCount(userStatEvent.user, achievementTag, matchField, (err, count) => {
if(err) {
return callback(err);
}
return callback(count > 0 ? Errors.General('Achievement already acquired', ErrorReasons.TooMany) : null);
});
},
(callback) => {
const client = getConnectionByUserId(userStatEvent.user.userId);
if(!client) {
return callback(Errors.UnexpectedState('Failed to get client for user ID'));
}
const info = {
achievementTag,
achievement,
details,
client,
matchField, // match - may be in odd format
matchValue, // actual value
achievedValue : matchField, // achievement value met
user : userStatEvent.user,
timestamp : moment(),
};
const achievementsInfo = [ info ];
if(true === achievement.data.retroactive) {
// For userStat, any lesser match keys(values) are also met. Example:
// matchKeys: [ 500, 200, 100, 20, 10, 2 ]
// ^---- we met here
// ^------------^ retroactive range
//
const index = achievement.matchKeys.findIndex(v => v < matchField);
if(index > -1 && Array.isArray(achievement.matchKeys)) {
achievement.matchKeys.slice(index).forEach(k => {
const [ det, fld, val ] = achievement.getMatchDetails(k);
if(det) {
achievementsInfo.push(Object.assign(
{},
info,
{
details : det,
matchField : fld,
achievedValue : fld,
matchValue : val,
}
));
}
});
}
}
// reverse achievementsInfo so we display smallest > largest
achievementsInfo.reverse();
async.eachSeries(achievementsInfo, (achInfo, nextAchInfo) => {
return this.recordAndDisplayAchievement(achInfo, err => {
return nextAchInfo(err);
});
},
err => {
return callback(err);
});
}
],
err => {
if(err && ErrorReasons.TooMany !== err.reasonCode) {
Log.warn( { error : err.message, userStatEvent }, 'Error handling achievement for user stat event');
}
return nextAchievementTag(null); // always try the next, regardless
}
);
});
/*
const achievementTag = _.findKey( const achievementTag = _.findKey(
_.get(this.achievementConfig, 'achievements', {}), _.get(this.achievementConfig, 'achievements', {}),
achievement => { achievement => {
if(false === achievement.enabled) { if(false === achievement.enabled) {
return false; return false;
} }
return [ Achievement.Types.UserStatSet, Achievement.Types.UserStatInc ].includes(achievement.type) && const acceptedTypes = [
achievement.statName === userStatEvent.statName; Achievement.Types.UserStatSet,
Achievement.Types.UserStatInc,
Achievement.Types.UserStatIncNewVal,
];
return acceptedTypes.includes(achievement.type) && achievement.statName === userStatEvent.statName;
} }
); );
@ -306,7 +430,8 @@ class Achievements {
return; return;
} }
const statValue = parseInt(Achievement.Types.UserStatSet === achievement.data.type ? const statValue = parseInt(
[ Achievement.Types.UserStatSet, Achievement.Types.UserStatIncNewVal ].includes(achievement.data.type) ?
userStatEvent.statValue : userStatEvent.statValue :
userStatEvent.statIncrementBy userStatEvent.statIncrementBy
); );
@ -392,7 +517,7 @@ class Achievements {
Log.warn( { error : err.message, userStatEvent }, 'Error handling achievement for user stat event'); Log.warn( { error : err.message, userStatEvent }, 'Error handling achievement for user stat event');
} }
} }
); );*/
}); });
} }
@ -571,6 +696,7 @@ function getAchievementsEarnedByUser(userId, cb) {
switch(earnedInfo.type) { switch(earnedInfo.type) {
case [ Achievement.Types.UserStatSet ] : case [ Achievement.Types.UserStatSet ] :
case [ Achievement.Types.UserStatInc ] : case [ Achievement.Types.UserStatInc ] :
case [ Achievement.Types.UserStatIncNewVal ] :
earnedInfo.statName = achievement.data.statName; earnedInfo.statName = achievement.data.statName;
break; break;
} }