Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 43 additions & 16 deletions app/api/claim-pack/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,47 @@ import { NextResponse } from 'next/server';
import { id } from '@instantdb/core';
import { BLOCK_TYPES, BlockTypeId } from '../../constants/blocks';

type RarityWeights = {
common: number;
uncommon: number;
rare: number;
legendary: number;
};

// Scale rarity weights based on session duration to reward longer focus
const getRarityWeightsForDuration = (minutes: number): RarityWeights => {
if (minutes >= 45) {
return {
common: 50,
uncommon: 30,
rare: 15,
legendary: 5,
};
}

if (minutes >= 30) {
return {
common: 55,
uncommon: 30,
rare: 12,
legendary: 3,
};
}

return {
common: 60,
uncommon: 30,
rare: 8,
legendary: 2,
};
};

// Get random block types for rewards (ensuring at least one plant)
const getRandomBlockTypes = (count: number, isSupporter: boolean = false): string[] => {
const getRandomBlockTypes = (
count: number,
isSupporter: boolean = false,
minutes: number = 0
): string[] => {
const allBlockIds = Object.keys(BLOCK_TYPES);

// Filter out supporter-only blocks if user is not a supporter
Expand All @@ -26,12 +65,7 @@ const getRandomBlockTypes = (count: number, isSupporter: boolean = false): strin
const selected: string[] = [];

// Rarity weights (must sum to 100)
const rarityWeights = {
common: 60,
uncommon: 30,
rare: 8,
legendary: 2
};
const rarityWeights = getRarityWeightsForDuration(minutes);

// Get a random block based on rarity weights
const getWeightedRandomBlock = (): string => {
Expand Down Expand Up @@ -155,18 +189,11 @@ export async function POST(request: Request) {
console.log(`User ${userId} supporter status: ${isSupporter}`);
}

// Determine pack size based on session duration
let packSize = 3; // Default for < 60 mins
const minutes = Math.floor(sessionDuration / 60);

if (minutes >= 45) {
packSize = 5; // 1 hour or more
} else if (minutes >= 30) {
packSize = 3; // Still 3 for 30-59 minutes
}
const packSize = 3; // All packs now provide three blocks

// Get random block types with supporter filter
const rewardBlocks = getRandomBlockTypes(packSize, isSupporter);
const rewardBlocks = getRandomBlockTypes(packSize, isSupporter, minutes);

// Create the block transactions
const blockTransactions = rewardBlocks.map((blockType) => {
Expand Down
17 changes: 13 additions & 4 deletions app/components/MainSlideover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1664,7 +1664,13 @@ const MainSlideover = memo(function MainSlideover({
const minutes = Math.floor(
session.timeInSeconds / 60
);
const packSize = minutes >= 60 ? 6 : 3;
const packSize = 3;
const rarityBoost =
minutes >= 45
? "Best odds for rare seeds"
: minutes >= 30
? "Better odds for rare seeds"
: "Standard odds";

return (
<button
Expand Down Expand Up @@ -1710,6 +1716,9 @@ const MainSlideover = memo(function MainSlideover({
<p className="text-[10px] text-center opacity-90">
{packSize} Premium Seeds
</p>
<p className="text-[9px] text-center opacity-80 text-amber-100">
{rarityBoost}
</p>
</div>

{/* Decorative plant illustration */}
Expand Down Expand Up @@ -2065,9 +2074,9 @@ const MainSlideover = memo(function MainSlideover({
EARN PACKS
</h4>
<p className="text-xs text-neutral-600 dark:text-neutral-400 leading-relaxed">
Complete sessions to earn seed packs. Sessions
under 60 minutes give 3 seeds, 60+ minutes give
6 seeds.
Complete sessions to earn seed packs. Every
pack contains three seeds, and longer sessions
boost your odds of higher rarities.
</p>
</div>
</div>
Expand Down