forked from syntaxbullet/AuroraBot-discord
feat: Introduce new modules for class, inventory, leveling, and quests with expanded schema, refactor user service, and add verification scripts.
This commit is contained in:
58
src/modules/leveling/leveling.service.ts
Normal file
58
src/modules/leveling/leveling.service.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import { users } from "@/db/schema";
|
||||
import { eq, sql } from "drizzle-orm";
|
||||
import { DrizzleClient } from "@/lib/DrizzleClient";
|
||||
|
||||
// Simple configurable curve: Base * (Level ^ Exponent)
|
||||
const XP_BASE = 1000;
|
||||
const XP_EXPONENT = 1.5;
|
||||
|
||||
export const levelingService = {
|
||||
// Calculate XP required for a specific level
|
||||
getXpForLevel: (level: number) => {
|
||||
return Math.floor(XP_BASE * Math.pow(level, XP_EXPONENT));
|
||||
},
|
||||
|
||||
addXp: async (id: string, amount: bigint, tx?: any) => {
|
||||
const execute = async (txFn: any) => {
|
||||
// Get current state
|
||||
const user = await txFn.query.users.findFirst({
|
||||
where: eq(users.id, BigInt(id)),
|
||||
});
|
||||
|
||||
if (!user) throw new Error("User not found");
|
||||
|
||||
let newXp = (user.xp ?? 0n) + amount;
|
||||
let currentLevel = user.level ?? 1;
|
||||
let levelUp = false;
|
||||
|
||||
// Check for level up loop
|
||||
let xpForNextLevel = BigInt(levelingService.getXpForLevel(currentLevel));
|
||||
|
||||
while (newXp >= xpForNextLevel) {
|
||||
newXp -= xpForNextLevel;
|
||||
currentLevel++;
|
||||
levelUp = true;
|
||||
xpForNextLevel = BigInt(levelingService.getXpForLevel(currentLevel));
|
||||
}
|
||||
|
||||
// Update user
|
||||
const [updatedUser] = await txFn.update(users)
|
||||
.set({
|
||||
xp: newXp,
|
||||
level: currentLevel,
|
||||
})
|
||||
.where(eq(users.id, BigInt(id)))
|
||||
.returning();
|
||||
|
||||
return { user: updatedUser, levelUp, currentLevel };
|
||||
}
|
||||
|
||||
if (tx) {
|
||||
return await execute(tx);
|
||||
} else {
|
||||
return await DrizzleClient.transaction(async (t) => {
|
||||
return await execute(t);
|
||||
})
|
||||
}
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user