Implement retroactive achievements (for userStat types so far)
This commit is contained in:
parent
2b802cb534
commit
f653d83c14
Binary file not shown.
|
@ -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"
|
||||
|
|
|
@ -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!"
|
||||
|
|
|
@ -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 => {
|
||||
|
|
Loading…
Reference in New Issue