Implement retroactive achievements (for userStat types so far)

This commit is contained in:
Bryan Ashby 2019-01-06 10:41:04 -07:00
parent 2b802cb534
commit f653d83c14
4 changed files with 49 additions and 17 deletions

View File

@ -984,7 +984,7 @@
achievements: {
defaults: {
format: "|08 > |10{title} |08(|11{points} |03points|08)\r\n\r\n {message}"
globalFformat: "|08 > |10{title} |08(|11{points} |03points|08)\r\n\r\n {message}"
globalformat: "|08 > |10{title} |08(|11{points} |03points|08)\r\n\r\n {message}"
titleSGR: "|10"
pointsSGR: "|12"
textSGR: "|00|03"

View File

@ -55,12 +55,11 @@
user_login_count: {
type: userStat
statName: login_count
retroactive: true
match: {
2: {
title: "Return Caller"
globalText: "{userName} has returned to {boardName}!"
text: "You\"ve returned to {boardName}!"
text: "You've returned to {boardName}!"
points: 5
}
10: {
@ -93,7 +92,6 @@
user_post_count: {
type: userStat
statName: post_count
retroactive: true
match: {
5: {
title: "Poster"
@ -125,7 +123,6 @@
user_upload_count: {
type: userStat
statName: ul_total_count
retroactive: true
match: {
1: {
title: "Uploader"
@ -164,7 +161,6 @@
user_download_count: {
type: userStat
statName: dl_total_count
retroactive: true
match: {
1: {
title: "Downloader"
@ -202,7 +198,6 @@
user_door_runs: {
type: userStat
statName: door_run_total_count
retroactive: true
match: {
1: {
title: "Nostalgia Toe Dip",
@ -240,7 +235,6 @@
user_door_total_minutes: {
type: userStat
statName: door_run_total_minutes
retroactive: true
match: {
1: {
title: "Nevermind!"

View File

@ -37,6 +37,9 @@ const paths = require('path');
class Achievement {
constructor(data) {
this.data = data;
// achievements are retroactive by default
this.data.retroactive = _.get(this.data, 'retroactive', true);
}
static factory(data) {
@ -87,6 +90,9 @@ class Achievement {
class UserStatAchievement extends Achievement {
constructor(data) {
super(data);
// sort match keys for quick match lookup
this.matchKeys = Object.keys(this.data.match || {}).map(k => parseInt(k)).sort( (a, b) => b - a);
}
isValid() {
@ -97,7 +103,7 @@ class UserStatAchievement extends Achievement {
}
getMatchDetails(matchValue) {
let matchField = Object.keys(this.data.match || {}).sort( (a, b) => b - a).find(v => matchValue >= v);
let matchField = this.matchKeys.find(v => matchValue >= v);
if(matchField) {
const match = this.data.match[matchField];
if(this.isValidMatchDetails(match)) {
@ -218,6 +224,22 @@ class Achievements {
});
}
recordAndDisplayAchievement(info, cb) {
async.series(
[
(callback) => {
return this.record(info, callback);
},
(callback) => {
return this.display(info, callback);
}
],
err => {
return cb(err);
}
);
}
monitorUserStatUpdateEvents() {
if(this.userStatEventListener) {
return; // already listening
@ -287,15 +309,31 @@ class Achievements {
timestamp : moment(),
};
return callback(null, info);
},
(info, callback) => {
this.record(info, err => {
return callback(err, info);
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) {
achievementsInfo.push(...achievement.matchKeys.slice(index).map(k => {
const [ d, f, v ] = achievement.getMatchDetails(k);
return Object.assign({}, info, { details : d, matchField : f, achievedValue : f, matchValue : v } );
}));
}
}
// reverse achievementsInfo so we display smallest > largest
achievementsInfo.reverse();
async.each(achievementsInfo, (achInfo, nextAchInfo) => {
return this.recordAndDisplayAchievement(achInfo, nextAchInfo);
},
err => {
return callback(err);
});
},
(info, callback) => {
return this.display(info, callback);
}
],
err => {