From cd2f49af9a34d332d6b364f393e207b55753c9a7 Mon Sep 17 00:00:00 2001 From: Arjun S <37960163+arjunindia@users.noreply.github.com> Date: Mon, 4 Aug 2025 06:57:41 +0000 Subject: [PATCH] addded ratmsic --- package-lock.json | 69 ++++++++++++++++++++++++++++++++++++++++-- package.json | 1 + party/index.ts | 11 +++++++ src/App.tsx | 57 ++++++++++++++++++++-------------- src/config/upgrades.ts | 10 ++++++ 5 files changed, 123 insertions(+), 25 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0d3cc27..fbce7e4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "partysocket": "^1.1.4", "react": "^18.3.1", "react-dom": "^18.3.1", + "react-youtube": "^10.1.0", "wouter": "^3.7.1" }, "devDependencies": { @@ -2558,8 +2559,7 @@ "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-glob": { "version": "3.3.2", @@ -3179,6 +3179,11 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, + "node_modules/load-script": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/load-script/-/load-script-1.0.0.tgz", + "integrity": "sha512-kPEjMFtZvwL9TaZo0uZ2ml+Ye9HUMmPwbYRJ324qF9tqMejwykJ5ggTyvzmrbBeapCAbk98BSbTeovHEEP1uCA==" + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -3443,7 +3448,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -3835,6 +3839,16 @@ "integrity": "sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==", "license": "Unlicense" }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -3887,6 +3901,11 @@ "react": "^18.3.1" } }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, "node_modules/react-refresh": { "version": "0.14.2", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", @@ -3896,6 +3915,22 @@ "node": ">=0.10.0" } }, + "node_modules/react-youtube": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/react-youtube/-/react-youtube-10.1.0.tgz", + "integrity": "sha512-ZfGtcVpk0SSZtWCSTYOQKhfx5/1cfyEW1JN/mugGNfAxT3rmVJeMbGpA9+e78yG21ls5nc/5uZJETE3cm3knBg==", + "dependencies": { + "fast-deep-equal": "3.1.3", + "prop-types": "15.8.1", + "youtube-player": "5.5.2" + }, + "engines": { + "node": ">= 14.x" + }, + "peerDependencies": { + "react": ">=0.14.1" + } + }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -4067,6 +4102,11 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/sister": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/sister/-/sister-3.0.2.tgz", + "integrity": "sha512-p19rtTs+NksBRKW9qn0UhZ8/TUI9BPw9lmtHny+Y3TinWlOa9jWh9xB0AtPSdmOy49NJJJSSe0Ey4C7h0TrcYA==" + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -4868,6 +4908,29 @@ "stacktracey": "^2.1.8" } }, + "node_modules/youtube-player": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/youtube-player/-/youtube-player-5.5.2.tgz", + "integrity": "sha512-ZGtsemSpXnDky2AUYWgxjaopgB+shFHgXVpiJFeNB5nWEugpW1KWYDaHKuLqh2b67r24GtP6HoSW5swvf0fFIQ==", + "dependencies": { + "debug": "^2.6.6", + "load-script": "^1.0.0", + "sister": "^3.0.0" + } + }, + "node_modules/youtube-player/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/youtube-player/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, "node_modules/zod": { "version": "3.25.76", "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", diff --git a/package.json b/package.json index ea3923f..cff4bbc 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "partysocket": "^1.1.4", "react": "^18.3.1", "react-dom": "^18.3.1", + "react-youtube": "^10.1.0", "wouter": "^3.7.1" }, "devDependencies": { diff --git a/party/index.ts b/party/index.ts index 9b7e5d5..6c9ab0d 100644 --- a/party/index.ts +++ b/party/index.ts @@ -15,6 +15,7 @@ export interface Upgrade { mascotTiers?: MascotTier[]; oneTime?: boolean; newsTitles?: string[]; + youtubeId?: string; } export interface MascotTier { @@ -191,6 +192,16 @@ const UPGRADES: Upgrade[] = [ `om`, `You are the Glue to my life like how Tokai Teio is glue(stick) to a child's art project`, ] + }, + { + id: 'secretVideo', + name: '🎬 Secret Video', + description: 'Unlock a secret video. Plays automatically!', + baseCost: 1000000, // Very expensive + multiplier: 1, + icon: '🎬', + oneTime: true, + youtubeId: 'ONzntmMFXGE' // The YouTube video ID } ]; diff --git a/src/App.tsx b/src/App.tsx index 57f36cb..5ddaf82 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -15,6 +15,7 @@ import { UPGRADES } from './config/upgrades'; // Import UPGRADES for upgrade con import { useLocation, Link } from 'wouter'; // Import wouter hooks import AdminPage from './components/AdminPage'; // Import AdminPage import { NewsMarquee } from './components/NewsMarquee'; // Import NewsMarquee +import YouTube from 'react-youtube'; // Import YouTube component function App() { const { isSignedIn, isLoaded, userId: clerkUserId } = useAuth(); // Get clerkUserId from useAuth @@ -24,9 +25,10 @@ function App() { const [mascotEntities, setMascotEntities] = useState([]); const timeoutRef = useRef(null); const gameStateRef = useRef(gameState); // Ref to hold the latest gameState - const clickButtonContainerRef = useRef(null); // New ref for the click button container - const [location] = useLocation(); // Get current location from wouter + + const [location, setLocation] = useLocation(); // Get current location from wouter const [adminBroadcastMessage, setAdminBroadcastMessage] = useState(null); // New state for admin messages + const [showSecretVideo, setShowSecretVideo] = useState(false); // New state for secret video // Admin user ID from .env const CLERK_ADMIN_USERID = import.meta.env.VITE_CLERK_ADMIN_USERID; @@ -53,6 +55,13 @@ function App() { } }, [gameState, previousMilestones]); + // Effect for secret video + useEffect(() => { + if (gameState?.upgrades['secretVideo']?.owned > 0) { + setShowSecretVideo(true); + } + }, [gameState?.upgrades['secretVideo']?.owned]); + // Effect for receiving admin broadcast messages useEffect(() => { if (lastMessage) { @@ -86,11 +95,11 @@ function App() { } if (ownedFriendBoost > 0 && friendBoostUpgrade && friendBoostUpgrade.mascotTiers) { - const baseInterval = 12000; // Increased base interval for less frequent spawns + const baseInterval = 18000; // Further increased base interval for less frequent spawns const minInterval = 1000; // Increased min interval const interval = Math.max(minInterval, baseInterval / (1 + ownedFriendBoost * 0.2)); // Adjusted scaling console.log(`Spawning mascots every ${interval} ms for friendBoost level ${ownedFriendBoost}`); - + const currentMascotTiers = friendBoostUpgrade.mascotTiers; // Ensure mascotTiers is not undefined @@ -99,25 +108,13 @@ function App() { const currentGameState = gameStateRef.current; if (!currentGameState) return; // Should not happen if initial check passes - const buttonContainer = clickButtonContainerRef.current; // Use the ref - if (!buttonContainer) { - console.warn('Click button container ref not found!'); - timeoutRef.current = setTimeout(spawnMascot, 1000); // Retry after 1 second - return; - } - - const rect = buttonContainer.getBoundingClientRect(); - const spawnAreaPadding = 150; - const minX = rect.left - spawnAreaPadding; - const maxX = rect.right + spawnAreaPadding; - const minY = rect.top - spawnAreaPadding; - const maxY = rect.bottom + spawnAreaPadding; - const viewportWidth = window.innerWidth; const viewportHeight = window.innerHeight; - const randomX = Math.max(0, Math.min(viewportWidth, minX + Math.random() * (maxX - minX))); - const randomY = Math.max(0, Math.min(viewportHeight, minY + Math.random() * (maxY - minY))); + // Spawn anywhere on the viewport, with a small padding to avoid edges + const padding = 50; + const randomX = Math.random() * (viewportWidth - padding * 2) + padding; + const randomY = Math.random() * (viewportHeight - padding * 2) + padding; // Filter available mascots based on ownedFriendBoost level const availableMascots = currentMascotTiers.filter( @@ -152,7 +149,7 @@ function App() { }; setMascotEntities((prev) => [...prev, newMascot]); - + timeoutRef.current = setTimeout(spawnMascot, interval); }; @@ -248,7 +245,7 @@ function App() { {/* Main Content */}
{/* Left Column - Click Button */} -
{/* Added ref, id and relative positioning */} +
{/* Added ref, id and relative positioning */}
+ {/* Secret Video Player */} + {showSecretVideo && ( +
+ u.id === 'secretVideo')?.youtubeId || ''} + opts={{ + height: '195', + width: '320', + playerVars: { + autoplay: 1, + }, + }} + /> +
+ )} + {/* Sparkle Effects */}
{[...Array(10)].map((_, i) => ( diff --git a/src/config/upgrades.ts b/src/config/upgrades.ts index 6e428c8..1dd5770 100644 --- a/src/config/upgrades.ts +++ b/src/config/upgrades.ts @@ -124,5 +124,15 @@ export const UPGRADES: Upgrade[] = [ `om`, `You are the Glue to my life like how Tokai Teio is glue(stick) to a child's art project`, ] + }, + { + id: 'secretVideo', + name: '🎬 Secret Video', + description: 'Unlock a secret video. Plays automatically!', + baseCost: 1000000, // Very expensive + multiplier: 1, + icon: '🎬', + oneTime: true, + youtubeId: 'ONzntmMFXGE' // The YouTube video ID } ];