Add xp reward overrides (#3525) Bruception, Miodec

* Add xp reward overrides

* edge case

* switched to defined brackets instead of just min and max

* foreach

* moved type to its own interface

* updated spec

Co-authored-by: Miodec <bartnikjack@gmail.com>
This commit is contained in:
Bruce Berrios 2022-09-08 16:38:28 -04:00 committed by GitHub
parent 2fa5dd0fef
commit c894a862e4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 91 additions and 44 deletions

View file

@ -23,6 +23,7 @@ const dailyLeaderboardsConfig = {
topResultsToAnnounce: 3,
maxXpReward: 0,
minXpReward: 0,
xpRewardBrackets: [],
};
describe("Daily Leaderboards", () => {

View file

@ -72,8 +72,7 @@ export const BASE_CONFIGURATION: MonkeyTypes.Configuration = {
// GOTCHA! MUST ATLEAST BE 1, LRUCache module will make process crash and die
dailyLeaderboardCacheSize: 1,
topResultsToAnnounce: 1, // This should never be 0. Setting to zero will announce all results.
minXpReward: 0,
maxXpReward: 0,
xpRewardBrackets: [],
},
};
@ -391,15 +390,35 @@ export const CONFIGURATION_FORM_SCHEMA: ObjectSchema = {
label: "Top Results To Announce",
min: 1,
},
minXpReward: {
type: "number",
label: "Minimum XP Reward",
min: 0,
},
maxXpReward: {
type: "number",
label: "Maximum XP Reward",
min: 0,
xpRewardBrackets: {
type: "array",
label: "XP Reward Brackets",
items: {
type: "object",
label: "Bracket",
fields: {
minRank: {
type: "number",
label: "Min Rank",
min: 1,
},
maxRank: {
type: "number",
label: "Max Rank",
min: 1,
},
minReward: {
type: "number",
label: "Min Reward",
min: 0,
},
maxReward: {
type: "number",
label: "Max Reward",
min: 0,
},
},
},
},
},
},

View file

@ -828,11 +828,15 @@ function buildRewardUpdates(
}
});
const baseUpdate = {
$inc: {
xp: _.isNumber(totalXp) ? totalXp : 0,
},
};
if (inventoryIsNull) {
return {
$inc: {
xp: totalXp,
},
...baseUpdate,
$set: {
inventory: {
badges: newBadges,
@ -841,9 +845,7 @@ function buildRewardUpdates(
};
} else {
return {
$inc: {
xp: totalXp,
},
...baseUpdate,
$push: {
"inventory.badges": { $each: newBadges },
},

View file

@ -1,3 +1,4 @@
import _ from "lodash";
import { CronJob } from "cron";
import {
getCurrentDayTimestamp,
@ -50,38 +51,52 @@ async function announceDailyLeaderboard(
if (allResults.length === 0) {
return;
}
const { maxResults, xpRewardBrackets } = dailyLeaderboardsConfig;
if (inboxConfig.enabled) {
const { maxXpReward, minXpReward, maxResults } = dailyLeaderboardsConfig;
if (inboxConfig.enabled && xpRewardBrackets.length > 0) {
const mailEntries: {
uid: string;
mail: MonkeyTypes.MonkeyMail[];
}[] = [];
if (maxXpReward > 0) {
const mailEntries = allResults.map((entry) => {
const rank = entry.rank ?? maxResults;
allResults.forEach((entry) => {
const rank = entry.rank ?? maxResults;
const placementString = getOrdinalNumberString(rank);
const xpReward = Math.floor(
mapRange(rank, 1, maxResults, maxXpReward, minXpReward)
);
const placementString = getOrdinalNumberString(rank);
const rewardMail = buildMonkeyMail({
subject: "Daily leaderboard placement",
body: `Congratulations ${entry.name} on placing ${placementString} in the ${language} ${mode} ${mode2} daily leaderboard!`,
rewards: [
{
type: "xp",
item: xpReward,
},
],
});
const xpReward = _(xpRewardBrackets)
.filter((bracket) => rank >= bracket.minRank && rank <= bracket.maxRank)
.map((bracket) =>
mapRange(
rank,
bracket.minRank,
bracket.maxRank,
bracket.maxReward,
bracket.minReward
)
)
.max();
return {
uid: entry.uid,
mail: [rewardMail],
};
if (!xpReward) return;
const rewardMail = buildMonkeyMail({
subject: "Daily leaderboard placement",
body: `Congratulations ${entry.name} on placing ${placementString} in the ${language} ${mode} ${mode2} daily leaderboard!`,
rewards: [
{
type: "xp",
item: xpReward,
},
],
});
await addToInboxBulk(mailEntries, inboxConfig);
}
mailEntries.push({
uid: entry.uid,
mail: [rewardMail],
});
});
await addToInboxBulk(mailEntries, inboxConfig);
}
const topResults = allResults.slice(

View file

@ -77,11 +77,17 @@ declare namespace MonkeyTypes {
validModeRules: ValidModeRule[];
dailyLeaderboardCacheSize: number;
topResultsToAnnounce: number;
maxXpReward: number;
minXpReward: number;
xpRewardBrackets: RewardBracket[];
};
}
interface RewardBracket {
minRank: number;
maxRank: number;
minReward: number;
maxReward: number;
}
interface DecodedToken {
type: "Bearer" | "ApeKey" | "None";
uid: string;

View file

@ -187,6 +187,10 @@ export function mapRange(
outMax: number,
clamp = false
): number {
if (inMin === inMax) {
return outMin;
}
const result =
((value - inMin) * (outMax - outMin)) / (inMax - inMin) + outMin;