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: {
|
achievements: {
|
||||||
defaults: {
|
defaults: {
|
||||||
format: "|08 > |10{title} |08(|11{points} |03points|08)\r\n\r\n {message}"
|
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"
|
titleSGR: "|10"
|
||||||
pointsSGR: "|12"
|
pointsSGR: "|12"
|
||||||
textSGR: "|00|03"
|
textSGR: "|00|03"
|
||||||
|
|
|
@ -55,12 +55,11 @@
|
||||||
user_login_count: {
|
user_login_count: {
|
||||||
type: userStat
|
type: userStat
|
||||||
statName: login_count
|
statName: login_count
|
||||||
retroactive: true
|
|
||||||
match: {
|
match: {
|
||||||
2: {
|
2: {
|
||||||
title: "Return Caller"
|
title: "Return Caller"
|
||||||
globalText: "{userName} has returned to {boardName}!"
|
globalText: "{userName} has returned to {boardName}!"
|
||||||
text: "You\"ve returned to {boardName}!"
|
text: "You've returned to {boardName}!"
|
||||||
points: 5
|
points: 5
|
||||||
}
|
}
|
||||||
10: {
|
10: {
|
||||||
|
@ -93,7 +92,6 @@
|
||||||
user_post_count: {
|
user_post_count: {
|
||||||
type: userStat
|
type: userStat
|
||||||
statName: post_count
|
statName: post_count
|
||||||
retroactive: true
|
|
||||||
match: {
|
match: {
|
||||||
5: {
|
5: {
|
||||||
title: "Poster"
|
title: "Poster"
|
||||||
|
@ -125,7 +123,6 @@
|
||||||
user_upload_count: {
|
user_upload_count: {
|
||||||
type: userStat
|
type: userStat
|
||||||
statName: ul_total_count
|
statName: ul_total_count
|
||||||
retroactive: true
|
|
||||||
match: {
|
match: {
|
||||||
1: {
|
1: {
|
||||||
title: "Uploader"
|
title: "Uploader"
|
||||||
|
@ -164,7 +161,6 @@
|
||||||
user_download_count: {
|
user_download_count: {
|
||||||
type: userStat
|
type: userStat
|
||||||
statName: dl_total_count
|
statName: dl_total_count
|
||||||
retroactive: true
|
|
||||||
match: {
|
match: {
|
||||||
1: {
|
1: {
|
||||||
title: "Downloader"
|
title: "Downloader"
|
||||||
|
@ -202,7 +198,6 @@
|
||||||
user_door_runs: {
|
user_door_runs: {
|
||||||
type: userStat
|
type: userStat
|
||||||
statName: door_run_total_count
|
statName: door_run_total_count
|
||||||
retroactive: true
|
|
||||||
match: {
|
match: {
|
||||||
1: {
|
1: {
|
||||||
title: "Nostalgia Toe Dip",
|
title: "Nostalgia Toe Dip",
|
||||||
|
@ -240,7 +235,6 @@
|
||||||
user_door_total_minutes: {
|
user_door_total_minutes: {
|
||||||
type: userStat
|
type: userStat
|
||||||
statName: door_run_total_minutes
|
statName: door_run_total_minutes
|
||||||
retroactive: true
|
|
||||||
match: {
|
match: {
|
||||||
1: {
|
1: {
|
||||||
title: "Nevermind!"
|
title: "Nevermind!"
|
||||||
|
|
|
@ -37,6 +37,9 @@ const paths = require('path');
|
||||||
class Achievement {
|
class Achievement {
|
||||||
constructor(data) {
|
constructor(data) {
|
||||||
this.data = data;
|
this.data = data;
|
||||||
|
|
||||||
|
// achievements are retroactive by default
|
||||||
|
this.data.retroactive = _.get(this.data, 'retroactive', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static factory(data) {
|
static factory(data) {
|
||||||
|
@ -87,6 +90,9 @@ class Achievement {
|
||||||
class UserStatAchievement extends Achievement {
|
class UserStatAchievement extends Achievement {
|
||||||
constructor(data) {
|
constructor(data) {
|
||||||
super(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() {
|
isValid() {
|
||||||
|
@ -97,7 +103,7 @@ class UserStatAchievement extends Achievement {
|
||||||
}
|
}
|
||||||
|
|
||||||
getMatchDetails(matchValue) {
|
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) {
|
if(matchField) {
|
||||||
const match = this.data.match[matchField];
|
const match = this.data.match[matchField];
|
||||||
if(this.isValidMatchDetails(match)) {
|
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() {
|
monitorUserStatUpdateEvents() {
|
||||||
if(this.userStatEventListener) {
|
if(this.userStatEventListener) {
|
||||||
return; // already listening
|
return; // already listening
|
||||||
|
@ -287,15 +309,31 @@ class Achievements {
|
||||||
timestamp : moment(),
|
timestamp : moment(),
|
||||||
};
|
};
|
||||||
|
|
||||||
return callback(null, info);
|
const achievementsInfo = [ info ];
|
||||||
},
|
if(true === achievement.data.retroactive) {
|
||||||
(info, callback) => {
|
// For userStat, any lesser match keys(values) are also met. Example:
|
||||||
this.record(info, err => {
|
// matchKeys: [ 500, 200, 100, 20, 10, 2 ]
|
||||||
return callback(err, info);
|
// ^---- 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 => {
|
err => {
|
||||||
|
|
Loading…
Reference in New Issue