updated milestones

This commit is contained in:
Arjun S
2025-08-04 08:14:53 +00:00
parent cd2f49af9a
commit 5898f04950
5 changed files with 103 additions and 68 deletions

View File

@@ -25,13 +25,21 @@ export interface MascotTier {
rarity: number;
}
interface GameState {
totalClicks: number;
users: Record<string, { name: string; clicks: number; lastSeen: number; bonusMultiplier: number; lastClickTime?: number }>;
interface UserState {
name: string;
clicks: number;
lastSeen: number;
bonusMultiplier: number;
lastClickTime?: number;
upgrades: Record<string, { owned: number; cost: number }>;
milestones: Record<string, boolean>;
clickMultiplier: number;
autoClickRate: number;
}
interface GameState {
totalClicks: number;
users: Record<string, UserState>;
milestones: Record<string, boolean>;
currentBackground: string;
currentClickImage: string;
}
@@ -216,13 +224,13 @@ const MILESTONES = [
{ threshold: 5000000, id: 'mega-bozo', background: 'mega-bozo', image: 'https://media1.tenor.com/m/x8v1oNUOmg4AAAAd/spinning-rat-rat.gif' },
{ threshold: 8008008, id: 'galactic-bozo', background: 'galactic-bozo', image: 'https://cdn.discordapp.com/emojis/1297946545626288312.webp' },
{ threshold: 10000000, id: 'cosmic-bozo', background: 'cosmic-bozo', image: 'https://media.discordapp.net/stickers/1377379131649429554.gif?size=160&quality=lossless' },
{ threshold: 100000000, id: 'interdimensional-bozo', background: 'interdimensional', image: 'https://media.discordapp.net/stickers/1397981135266648064.webp?size=160&quality=lossless' },
{ threshold: 500000000, id: 'multiversal-bozo', background: 'multiversal', image: 'https://media.discordapp.net/stickers/1294812453112123453.webp?quality=lossless' },
{ threshold: 1000000000, id: 'billionaire-bozo', background: 'billionaire', image: 'https://media1.tenor.com/m/x8v1oNUOmg4AAAAd/spinning-rat-rat.gif' },
{ threshold: 10000000000, id: 'ten-billion-bozo', background: 'ten-billion', image: 'https://cdn.discordapp.com/emojis/1297946545626288312.webp' },
{ threshold: 100000000000, id: 'hundred-billion-bozo', background: 'hundred-billion', image: 'https://media.discordapp.net/stickers/1377379131649429554.gif?size=160&quality=lossless' },
{ threshold: 500000000000, id: 'half-trillion-bozo', background: 'half-trillion', image: 'https://media1.tenor.com/m/pV74fmh_NLgAAAAd/louie-rat-spinning-rat.gif' },
{ threshold: 1000000000000, id: 'trillionaire-bozo', background: 'trillionaire', image: 'https://media.discordapp.net/stickers/1397981135266648064.webp?size=160&quality=lossless' }
{ threshold: 100000000, id: 'interdimensional-bozo', background: 'interdimensional', image: 'https://tenor.com/view/horizontally-spinning-rat-gif-2222021229431992839.gif' },
{ threshold: 500000000, id: 'multiversal-bozo', background: 'multiversal', image: 'https://tenor.com/view/spinning-rat-gif-26132.gif' },
{ threshold: 1000000000, id: 'billionaire-bozo', background: 'billionaire', image: 'https://tenor.com/view/dancing-rat-rat-dance-gif-25151223.gif' },
{ threshold: 10000000000, id: 'ten-billion-bozo', background: 'ten-billion', image: 'https://tenor.com/view/horizontally-spinning-rat-gif-2222021229431992839.gif' },
{ threshold: 100000000000, id: 'hundred-billion-bozo', background: 'hundred-billion', image: 'https://tenor.com/view/spinning-rat-gif-26132.gif' },
{ threshold: 500000000000, id: 'half-trillion-bozo', background: 'half-trillion', image: 'https://tenor.com/view/dancing-rat-rat-dance-gif-25151223.gif' },
{ threshold: 1000000000000, id: 'trillionaire-bozo', background: 'trillionaire', image: 'https://tenor.com/view/dancing-rat-rat-dance-gif-25151223.gif' }
];
export default class GameServer implements Party.Server {
@@ -238,13 +246,7 @@ export default class GameServer implements Party.Server {
gameState: GameState = {
totalClicks: 0,
users: {},
upgrades: UPGRADES.reduce((acc, upgrade) => {
acc[upgrade.id] = { owned: 0, cost: upgrade.baseCost };
return acc;
}, {} as Record<string, { owned: number; cost: number }>),
milestones: {},
clickMultiplier: 1,
autoClickRate: 0,
currentBackground: 'default',
currentClickImage: 'https://media1.tenor.com/m/pV74fmh_NLgAAAAd/louie-rat-spinning-rat.gif'
};
@@ -315,7 +317,13 @@ export default class GameServer implements Party.Server {
name: currentUserName,
clicks: 0,
lastSeen: Date.now(),
bonusMultiplier: 1 // Initialize bonus multiplier
bonusMultiplier: 1, // Initialize bonus multiplier
upgrades: UPGRADES.reduce((acc, upgrade) => {
acc[upgrade.id] = { owned: 0, cost: upgrade.baseCost };
return acc;
}, {} as Record<string, { owned: number; cost: number }>),
clickMultiplier: 1,
autoClickRate: 0,
};
}
this.gameState.users[currentUserId].lastSeen = Date.now();
@@ -396,7 +404,7 @@ export default class GameServer implements Party.Server {
// Apply global click multiplier and user-specific bonus multiplier
const userBonusMultiplier = userState.bonusMultiplier || 1;
const clickValue = this.gameState.clickMultiplier * userBonusMultiplier;
const clickValue = userState.clickMultiplier * userBonusMultiplier;
this.gameState.totalClicks += clickValue;
userState.clicks += clickValue;
@@ -441,9 +449,11 @@ export default class GameServer implements Party.Server {
handlePurchaseUpgrade(data: PurchaseUpgradeMessage, authenticatedUserId: string) {
const upgradeConfig = UPGRADES.find(u => u.id === data.upgradeId);
const currentUpgradeState = this.gameState.upgrades[data.upgradeId];
const userState = this.gameState.users[authenticatedUserId];
if (!upgradeConfig || !currentUpgradeState) return;
if (!upgradeConfig || !userState) return;
const currentUpgradeState = userState.upgrades[data.upgradeId];
// Prevent purchasing one-time upgrades if already owned
if (upgradeConfig.oneTime && currentUpgradeState.owned > 0) {
@@ -451,9 +461,9 @@ export default class GameServer implements Party.Server {
return;
}
// Check affordability against totalClicks
if (this.gameState.totalClicks >= currentUpgradeState.cost) {
this.gameState.totalClicks -= currentUpgradeState.cost; // Deduct from totalClicks
// Check affordability against user's clicks
if (userState.clicks >= currentUpgradeState.cost) {
userState.clicks -= currentUpgradeState.cost; // Deduct from user's clicks
currentUpgradeState.owned += 1;
// For one-time upgrades, cost doesn't change after first purchase
@@ -461,26 +471,27 @@ export default class GameServer implements Party.Server {
currentUpgradeState.cost = Math.floor(upgradeConfig.baseCost * Math.pow(upgradeConfig.multiplier, currentUpgradeState.owned));
}
this.updateGameMultipliers();
this.updateGameMultipliers(authenticatedUserId);
}
}
updateGameMultipliers() {
this.gameState.clickMultiplier = 1;
this.gameState.autoClickRate = 0;
updateGameMultipliers(userId: string) {
const userState = this.gameState.users[userId];
if (!userState) return;
Object.entries(this.gameState.upgrades).forEach(([upgradeId, upgradeState]) => {
userState.clickMultiplier = 1;
userState.autoClickRate = 0;
Object.entries(userState.upgrades).forEach(([upgradeId, upgradeState]) => {
const config = UPGRADES.find(u => u.id === upgradeId);
if (!config) return; // Should not happen if UPGRADES is consistent
if (!config) return;
if (config.clickBonus) {
this.gameState.clickMultiplier += config.clickBonus * upgradeState.owned;
userState.clickMultiplier += config.clickBonus * upgradeState.owned;
}
if (config.autoClickRate) {
this.gameState.autoClickRate += config.autoClickRate * upgradeState.owned;
userState.autoClickRate += config.autoClickRate * upgradeState.owned;
}
// Note: clickMultiplierBonus from upgrades.ts is handled client-side for spawning frequency
// and applied per-click on the server via handleApplyMultiplierBonus
});
this.setupAutoClicker();
@@ -491,13 +502,21 @@ export default class GameServer implements Party.Server {
clearInterval(this.autoClickInterval);
}
if (this.gameState.autoClickRate > 0) {
this.autoClickInterval = setInterval(() => {
this.gameState.totalClicks += this.gameState.autoClickRate;
this.autoClickInterval = setInterval(() => {
let totalAutoClicks = 0;
Object.values(this.gameState.users).forEach(user => {
if (user.autoClickRate > 0) {
user.clicks += user.autoClickRate;
totalAutoClicks += user.autoClickRate;
}
});
if (totalAutoClicks > 0) {
this.gameState.totalClicks += totalAutoClicks;
this.checkMilestones();
this.broadcast();
}, 1000);
}
}
}, 1000);
}
checkMilestones() {