58 lines
1.3 KiB
TypeScript
Executable File
58 lines
1.3 KiB
TypeScript
Executable File
import type { AdventureItemState, XpSource } from "./types";
|
|
|
|
export const XP_AWARDS = {
|
|
daily_visit: 5,
|
|
adventure_started: 10,
|
|
adventure_partial: 25,
|
|
adventure_done: 40,
|
|
reflection: 30,
|
|
spiritual_per_check: 5,
|
|
spiritual_daily_cap: 25,
|
|
reading_per_10_pages: 15,
|
|
reading_daily_cap: 60,
|
|
exercise: 50,
|
|
exploration: 100,
|
|
weekly_review: 150,
|
|
rest_day: 15,
|
|
book_complete: 200,
|
|
} as const;
|
|
|
|
export const DAILY_SOFT_CAPS: Partial<Record<XpSource, number>> = {
|
|
adventure_item: 200,
|
|
spiritual: 25,
|
|
reading: 60,
|
|
};
|
|
|
|
export function xpForAdventureState(state: AdventureItemState): number {
|
|
switch (state) {
|
|
case "started":
|
|
return XP_AWARDS.adventure_started;
|
|
case "partial":
|
|
return XP_AWARDS.adventure_partial;
|
|
case "done":
|
|
return XP_AWARDS.adventure_done;
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
export function applyDiminishingReturns(
|
|
amount: number,
|
|
earnedToday: number,
|
|
softCap: number
|
|
): number {
|
|
if (earnedToday >= softCap) {
|
|
return Math.floor(amount * 0.25);
|
|
}
|
|
if (earnedToday + amount > softCap) {
|
|
const atFull = softCap - earnedToday;
|
|
const over = amount - atFull;
|
|
return atFull + Math.floor(over * 0.25);
|
|
}
|
|
return amount;
|
|
}
|
|
|
|
export function xpForReadingPages(pages: number): number {
|
|
return Math.floor(pages / 10) * XP_AWARDS.reading_per_10_pages;
|
|
}
|