forked from syntaxbullet/AuroraBot-discord
feat: Allow item effects to specify durations in hours, minutes, or seconds.
This commit is contained in:
@@ -15,8 +15,8 @@ export interface Event<K extends keyof ClientEvents> {
|
||||
export type ItemEffect =
|
||||
| { type: 'ADD_XP'; amount: number }
|
||||
| { type: 'ADD_BALANCE'; amount: number }
|
||||
| { type: 'XP_BOOST'; multiplier: number; durationSeconds: number }
|
||||
| { type: 'TEMP_ROLE'; roleId: string; durationSeconds: number }
|
||||
| { type: 'XP_BOOST'; multiplier: number; durationSeconds?: number; durationMinutes?: number; durationHours?: number }
|
||||
| { type: 'TEMP_ROLE'; roleId: string; durationSeconds?: number; durationMinutes?: number; durationHours?: number }
|
||||
| { type: 'REPLY_MESSAGE'; message: string };
|
||||
|
||||
export interface ItemUsageData {
|
||||
|
||||
@@ -7,6 +7,13 @@ import { config } from "@/lib/config";
|
||||
import { withTransaction } from "@/lib/db";
|
||||
import type { Transaction, ItemUsageData } from "@/lib/types";
|
||||
|
||||
// Helper to extract duration in seconds
|
||||
const getDuration = (effect: any): number => {
|
||||
if (effect.durationHours) return effect.durationHours * 3600;
|
||||
if (effect.durationMinutes) return effect.durationMinutes * 60;
|
||||
return effect.durationSeconds || 60; // Default to 60s if nothing provided
|
||||
};
|
||||
|
||||
export const inventoryService = {
|
||||
addItem: async (userId: string, itemId: number, quantity: bigint = 1n, tx?: Transaction) => {
|
||||
return await withTransaction(async (txFn) => {
|
||||
@@ -171,7 +178,8 @@ export const inventoryService = {
|
||||
results.push(effect.message);
|
||||
break;
|
||||
case 'XP_BOOST':
|
||||
const expiresAt = new Date(Date.now() + effect.durationSeconds * 1000);
|
||||
const boostDuration = getDuration(effect);
|
||||
const expiresAt = new Date(Date.now() + boostDuration * 1000);
|
||||
await txFn.insert(userTimers).values({
|
||||
userId: BigInt(userId),
|
||||
type: 'EFFECT',
|
||||
@@ -182,10 +190,11 @@ export const inventoryService = {
|
||||
target: [userTimers.userId, userTimers.type, userTimers.key],
|
||||
set: { expiresAt: expiresAt, metadata: { multiplier: effect.multiplier } }
|
||||
});
|
||||
results.push(`XP Boost (${effect.multiplier}x) active for ${Math.floor(effect.durationSeconds / 60)}m`);
|
||||
results.push(`XP Boost (${effect.multiplier}x) active for ${Math.floor(boostDuration / 60)}m`);
|
||||
break;
|
||||
case 'TEMP_ROLE':
|
||||
const roleExpiresAt = new Date(Date.now() + effect.durationSeconds * 1000);
|
||||
const roleDuration = getDuration(effect);
|
||||
const roleExpiresAt = new Date(Date.now() + roleDuration * 1000);
|
||||
await txFn.insert(userTimers).values({
|
||||
userId: BigInt(userId),
|
||||
type: 'ACCESS',
|
||||
@@ -196,9 +205,8 @@ export const inventoryService = {
|
||||
target: [userTimers.userId, userTimers.type, userTimers.key],
|
||||
set: { expiresAt: roleExpiresAt }
|
||||
});
|
||||
// Actual role assignment happens in the Command layer (or here if we had client, but service shouldn't depend on client ideally)
|
||||
// We return a flag to let the interaction handler know it needs to assign a role.
|
||||
results.push(`Temporary Role granted for ${Math.floor(effect.durationSeconds / 60)}m`);
|
||||
// Actual role assignment happens in the Command layer
|
||||
results.push(`Temporary Role granted for ${Math.floor(roleDuration / 60)}m`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user