mirror of
https://github.com/iDisaster/GTAConnected.git
synced 2026-03-08 09:25:23 +00:00
Enhance Trident UI with advanced visual elements
- Add animated outer glow/shadow effects around menu - Add decorative corner elements with pulsing animations - Enhance header with shimmer effect and gradient backgrounds - Add multi-layer selection highlight with glow effects - Add animated scrollbar with thumb glow - Add enhanced footer with styled navigation hints - Add Player Status panel (health/armor bars, wanted level, vehicle status) - Add real-time clock display with date - Add active toggles indicator (shows when menu closed) - Add bottom screen banner with branding - Add floating particle effects around menu - Add sparkle effects on menu corners - Add Trident Edition badge above menu - Improve info bar with styled border and label box - Add page indicator for scrollable menus
This commit is contained in:
@@ -84,6 +84,19 @@ let Fading_100 = 100; // Fade in effect
|
|||||||
let Fading_150 = 150; // Fade in effect
|
let Fading_150 = 150; // Fade in effect
|
||||||
let dropdown_y = 1.2; // Dropdown animation
|
let dropdown_y = 1.2; // Dropdown animation
|
||||||
|
|
||||||
|
// Enhanced UI Animation State
|
||||||
|
let borderGlow = 0; // Animated border glow (0-1)
|
||||||
|
let borderGlowIncrement = true;
|
||||||
|
let cornerPulse = 0; // Corner decoration pulse
|
||||||
|
let headerWaveOffset = 0; // Header wave animation
|
||||||
|
let scrollbarPulse = 0; // Scrollbar glow pulse
|
||||||
|
let logoRotation = 0; // Logo rotation angle
|
||||||
|
let statsUpdateTime = 0; // Stats panel update timer
|
||||||
|
let particleArray = []; // Particle system
|
||||||
|
let bannerShimmer = 0; // Banner shimmer effect
|
||||||
|
let footerPulse = 0; // Footer pulse animation
|
||||||
|
let itemHoverScale = []; // Per-item hover scale
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// THEME SYSTEM
|
// THEME SYSTEM
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -2454,6 +2467,33 @@ addEventHandler("OnProcess", function(event) {
|
|||||||
if (dropdown_y > 0.96) dropdown_y -= 0.01;
|
if (dropdown_y > 0.96) dropdown_y -= 0.01;
|
||||||
else dropdown_y = 0.95;
|
else dropdown_y = 0.95;
|
||||||
|
|
||||||
|
// ===== Enhanced UI Animations =====
|
||||||
|
// Border glow effect (0-1 smooth pulse)
|
||||||
|
if (borderGlow >= 1) borderGlowIncrement = false;
|
||||||
|
else if (borderGlow <= 0) borderGlowIncrement = true;
|
||||||
|
borderGlow += borderGlowIncrement ? 0.015 : -0.015;
|
||||||
|
|
||||||
|
// Corner pulse effect
|
||||||
|
cornerPulse = (cornerPulse + 0.03) % (Math.PI * 2);
|
||||||
|
|
||||||
|
// Header wave animation
|
||||||
|
headerWaveOffset = (headerWaveOffset + 0.05) % (Math.PI * 2);
|
||||||
|
|
||||||
|
// Scrollbar pulse
|
||||||
|
scrollbarPulse = (scrollbarPulse + 0.08) % (Math.PI * 2);
|
||||||
|
|
||||||
|
// Logo rotation (slow spin)
|
||||||
|
logoRotation = (logoRotation + 0.5) % 360;
|
||||||
|
|
||||||
|
// Banner shimmer effect
|
||||||
|
bannerShimmer = (bannerShimmer + 0.04) % (Math.PI * 2);
|
||||||
|
|
||||||
|
// Footer pulse
|
||||||
|
footerPulse = (footerPulse + 0.05) % (Math.PI * 2);
|
||||||
|
|
||||||
|
// Stats update timer
|
||||||
|
statsUpdateTime += 0.02;
|
||||||
|
|
||||||
// Screen shake decay
|
// Screen shake decay
|
||||||
if (screenShake > 0) {
|
if (screenShake > 0) {
|
||||||
screenShake -= 0.1;
|
screenShake -= 0.1;
|
||||||
@@ -2577,44 +2617,106 @@ addEventHandler("OnDrawnHUD", function(event) {
|
|||||||
let baseX = menu.x + slideOffset;
|
let baseX = menu.x + slideOffset;
|
||||||
let baseY = menu.y;
|
let baseY = menu.y;
|
||||||
|
|
||||||
// ===== MDB WINDOW BACKGROUND - Steelblue (70,130,180) alpha 180 =====
|
// ===== ENHANCED OUTER GLOW/SHADOW =====
|
||||||
// Matches: DRAW_SPRITE(MAP_LOBBY, ..., 70,130,180, 180)
|
let glowIntensity = 0.3 + borderGlow * 0.2;
|
||||||
let windowBgColor = toColour(MDB.Steelblue.r, MDB.Steelblue.g, MDB.Steelblue.b, Math.floor(180 * menuOpenAnim));
|
let outerGlowColor = toColour(MDB.Gold.r, MDB.Gold.g, MDB.Gold.b, Math.floor(40 * glowIntensity * menuOpenAnim));
|
||||||
|
drawRect(baseX - 8, baseY - 8, menu.width + 16, totalHeight + 26, outerGlowColor);
|
||||||
|
let shadowBg = toColour(0, 0, 0, Math.floor(120 * menuOpenAnim));
|
||||||
|
drawRect(baseX - 4, baseY - 4, menu.width + 8, totalHeight + 18, shadowBg);
|
||||||
|
|
||||||
|
// ===== MDB WINDOW BACKGROUND - Enhanced gradient-style =====
|
||||||
|
let windowBgColor = toColour(MDB.Steelblue.r, MDB.Steelblue.g, MDB.Steelblue.b, Math.floor(190 * menuOpenAnim));
|
||||||
drawRect(baseX, baseY, menu.width, totalHeight + 10, windowBgColor);
|
drawRect(baseX, baseY, menu.width, totalHeight + 10, windowBgColor);
|
||||||
|
|
||||||
// ===== MDB HEADER SECTION =====
|
// Inner darker panel for depth
|
||||||
let headerY = baseY + 5;
|
let innerBgColor = toColour(30, 50, 70, Math.floor(100 * menuOpenAnim));
|
||||||
|
drawRect(baseX + 3, baseY + 3, menu.width - 6, totalHeight + 4, innerBgColor);
|
||||||
|
|
||||||
// "MD" Prefix - Steelblue, large text (Version_Txt_Size equivalent)
|
// ===== ANIMATED BORDER =====
|
||||||
// Shadow first
|
let borderAlpha = Math.floor((180 + borderGlow * 75) * menuOpenAnim);
|
||||||
|
let borderColor = toColour(MDB.Gold.r, MDB.Gold.g, MDB.Gold.b, borderAlpha);
|
||||||
|
// Top border
|
||||||
|
drawRect(baseX, baseY, menu.width, 2, borderColor);
|
||||||
|
// Bottom border
|
||||||
|
drawRect(baseX, baseY + totalHeight + 8, menu.width, 2, borderColor);
|
||||||
|
// Left border
|
||||||
|
drawRect(baseX, baseY, 2, totalHeight + 10, borderColor);
|
||||||
|
// Right border
|
||||||
|
drawRect(baseX + menu.width - 2, baseY, 2, totalHeight + 10, borderColor);
|
||||||
|
|
||||||
|
// ===== DECORATIVE CORNER ELEMENTS =====
|
||||||
|
let cornerSize = 12;
|
||||||
|
let cornerAlpha = Math.floor((200 + Math.sin(cornerPulse) * 55) * menuOpenAnim);
|
||||||
|
let cornerColor = toColour(255, 200, 100, cornerAlpha);
|
||||||
|
// Top-left corner
|
||||||
|
drawRect(baseX, baseY, cornerSize, 3, cornerColor);
|
||||||
|
drawRect(baseX, baseY, 3, cornerSize, cornerColor);
|
||||||
|
// Top-right corner
|
||||||
|
drawRect(baseX + menu.width - cornerSize, baseY, cornerSize, 3, cornerColor);
|
||||||
|
drawRect(baseX + menu.width - 3, baseY, 3, cornerSize, cornerColor);
|
||||||
|
// Bottom-left corner
|
||||||
|
drawRect(baseX, baseY + totalHeight + 7, cornerSize, 3, cornerColor);
|
||||||
|
drawRect(baseX, baseY + totalHeight + 10 - cornerSize, 3, cornerSize, cornerColor);
|
||||||
|
// Bottom-right corner
|
||||||
|
drawRect(baseX + menu.width - cornerSize, baseY + totalHeight + 7, cornerSize, 3, cornerColor);
|
||||||
|
drawRect(baseX + menu.width - 3, baseY + totalHeight + 10 - cornerSize, 3, cornerSize, cornerColor);
|
||||||
|
|
||||||
|
// ===== ENHANCED HEADER BANNER =====
|
||||||
|
let headerY = baseY + 5;
|
||||||
|
// Header background gradient
|
||||||
|
let headerBg1 = toColour(40, 60, 90, Math.floor(220 * menuOpenAnim));
|
||||||
|
let headerBg2 = toColour(60, 90, 130, Math.floor(220 * menuOpenAnim));
|
||||||
|
drawRect(baseX + 4, headerY - 2, menu.width - 8, 55, headerBg1);
|
||||||
|
// Header shimmer effect
|
||||||
|
let shimmerX = baseX + 4 + ((Math.sin(bannerShimmer) + 1) * 0.5) * (menu.width - 80);
|
||||||
|
let shimmerColor = toColour(255, 255, 255, Math.floor(30 * menuOpenAnim));
|
||||||
|
drawRect(shimmerX, headerY - 2, 60, 55, shimmerColor);
|
||||||
|
|
||||||
|
// "MD" Prefix - Enhanced with glow
|
||||||
let shadowColor = toColour(0, 0, 0, Math.floor(255 * menuOpenAnim));
|
let shadowColor = toColour(0, 0, 0, Math.floor(255 * menuOpenAnim));
|
||||||
|
drawText("MD", baseX + 13, headerY + 3, shadowColor, 28);
|
||||||
drawText("MD", baseX + 11, headerY + 1, shadowColor, 28);
|
drawText("MD", baseX + 11, headerY + 1, shadowColor, 28);
|
||||||
// Main "MD" in Steelblue
|
// Main "MD" in bright Steelblue
|
||||||
let mdColor = toColour(MDB.Steelblue.r, MDB.Steelblue.g, MDB.Steelblue.b, animAlpha);
|
let mdGlowColor = toColour(100, 160, 220, Math.floor(FlashingGhost * menuOpenAnim));
|
||||||
|
let mdColor = toColour(MDB.Steelblue.r + 30, MDB.Steelblue.g + 30, MDB.Steelblue.b + 30, animAlpha);
|
||||||
|
drawText("MD", baseX + 10, headerY, mdGlowColor, 28);
|
||||||
drawText("MD", baseX + 10, headerY, mdColor, 28);
|
drawText("MD", baseX + 10, headerY, mdColor, 28);
|
||||||
|
|
||||||
// Menu Header Text - Gold with FlashingGhost alpha (Extend_Txt_Size equivalent)
|
// "REVOLUTION" - Enhanced with glow effect
|
||||||
// Shadow
|
drawText("REVOLUTION", baseX + 58, headerY + 8, shadowColor, 20);
|
||||||
drawText("REVOLUTION", baseX + 56, headerY + 6, shadowColor, 20);
|
drawText("REVOLUTION", baseX + 56, headerY + 6, shadowColor, 20);
|
||||||
// Main header in Gold with FlashingGhost effect
|
// Main header in Gold with enhanced FlashingGhost effect
|
||||||
let headerGoldColor = toColour(MDB.Gold.r, MDB.Gold.g, MDB.Gold.b, Math.floor(FlashingGhost * menuOpenAnim));
|
let headerGlowColor = toColour(255, 200, 100, Math.floor(FlashingGhost * 0.7 * menuOpenAnim));
|
||||||
|
let headerGoldColor = toColour(MDB.Gold.r + 40, MDB.Gold.g + 40, MDB.Gold.b, Math.floor(FlashingGhost * menuOpenAnim));
|
||||||
|
drawText("REVOLUTION", baseX + 55, headerY + 5, headerGlowColor, 20);
|
||||||
drawText("REVOLUTION", baseX + 55, headerY + 5, headerGoldColor, 20);
|
drawText("REVOLUTION", baseX + 55, headerY + 5, headerGoldColor, 20);
|
||||||
|
|
||||||
// Version text - Steelblue (right side)
|
// Version badge - Enhanced with box
|
||||||
let versionColor = toColour(MDB.Steelblue.r, MDB.Steelblue.g, MDB.Steelblue.b, animAlpha);
|
let badgeX = baseX + menu.width - 78;
|
||||||
drawText("TRIDENT", baseX + menu.width - 70, headerY + 22, versionColor, 12);
|
let badgeY = headerY + 18;
|
||||||
|
let badgeBg = toColour(MDB.Steelblue.r, MDB.Steelblue.g, MDB.Steelblue.b, Math.floor(200 * menuOpenAnim));
|
||||||
|
drawRect(badgeX - 4, badgeY - 2, 70, 18, badgeBg);
|
||||||
|
let versionColor = toColour(255, 255, 255, animAlpha);
|
||||||
|
drawText("TRIDENT", badgeX, badgeY + 2, versionColor, 11);
|
||||||
|
|
||||||
// Sub Header - centered, SubHeader color (58,95,205)
|
// Sub Header - Enhanced with underline effect
|
||||||
let subHeaderColor = toColour(MDB.SubHeader.r, MDB.SubHeader.g, MDB.SubHeader.b, animAlpha);
|
let subHeaderColor = toColour(MDB.SubHeader.r + 40, MDB.SubHeader.g + 40, MDB.SubHeader.b + 40, animAlpha);
|
||||||
let subHeaderText = currentMenu === "main" ? "MAJOR DISTRIBUTION" : title;
|
let subHeaderText = currentMenu === "main" ? "MAJOR DISTRIBUTION" : title;
|
||||||
// Calculate center position
|
let subHeaderX = baseX + (menu.width / 2) - (subHeaderText.length * 3.5);
|
||||||
let subHeaderX = baseX + (menu.width / 2) - (subHeaderText.length * 3);
|
drawText(subHeaderText, subHeaderX + 1, headerY + 40, shadowColor, 12);
|
||||||
drawText(subHeaderText, subHeaderX, headerY + 38, subHeaderColor, 12);
|
drawText(subHeaderText, subHeaderX, headerY + 39, subHeaderColor, 12);
|
||||||
|
|
||||||
// ===== MDB WHITE LINE SEPARATOR =====
|
// ===== ENHANCED WHITE LINE SEPARATOR =====
|
||||||
// DRAW_RECT(..., Line_r=255, Line_g=255, Line_b=255, 255)
|
// Gradient-style separator
|
||||||
let lineColor = toColour(MDB.Line.r, MDB.Line.g, MDB.Line.b, animAlpha);
|
let lineColorL = toColour(MDB.Gold.r, MDB.Gold.g, MDB.Gold.b, Math.floor(200 * menuOpenAnim));
|
||||||
drawRect(baseX + 10, baseY + menu.headerHeight - 5, menu.width - 20, 2, lineColor);
|
let lineColorC = toColour(MDB.Line.r, MDB.Line.g, MDB.Line.b, animAlpha);
|
||||||
|
let lineColorR = toColour(MDB.Gold.r, MDB.Gold.g, MDB.Gold.b, Math.floor(200 * menuOpenAnim));
|
||||||
|
drawRect(baseX + 10, baseY + menu.headerHeight - 5, 30, 2, lineColorL);
|
||||||
|
drawRect(baseX + 40, baseY + menu.headerHeight - 5, menu.width - 80, 2, lineColorC);
|
||||||
|
drawRect(baseX + menu.width - 40, baseY + menu.headerHeight - 5, 30, 2, lineColorR);
|
||||||
|
// Add glow line under
|
||||||
|
let glowLineColor = toColour(MDB.Gold.r, MDB.Gold.g, MDB.Gold.b, Math.floor(60 * borderGlow * menuOpenAnim));
|
||||||
|
drawRect(baseX + 10, baseY + menu.headerHeight - 3, menu.width - 20, 3, glowLineColor);
|
||||||
|
|
||||||
// ===== MDB MENU ITEMS =====
|
// ===== MDB MENU ITEMS =====
|
||||||
let yPos = baseY + menu.headerHeight;
|
let yPos = baseY + menu.headerHeight;
|
||||||
@@ -2626,14 +2728,29 @@ addEventHandler("OnDrawnHUD", function(event) {
|
|||||||
let itemY = yPos + (i - scrollOffset) * menu.itemHeight;
|
let itemY = yPos + (i - scrollOffset) * menu.itemHeight;
|
||||||
|
|
||||||
if (isSelected) {
|
if (isSelected) {
|
||||||
// ===== MDB SELECTED ITEM - Scrollbar with Glowing effect =====
|
// ===== ENHANCED SELECTED ITEM - Multi-layer glow effect =====
|
||||||
// DRAW_RECT(..., Glowing, Glowing, 200, 150)
|
// Outer glow
|
||||||
let scrollbarColor = toColour(Glowing, Glowing, 200, Math.floor(150 * menuOpenAnim));
|
let outerGlowAlpha = Math.floor((80 + Math.sin(scrollbarPulse) * 40) * menuOpenAnim);
|
||||||
|
let outerGlowCol = toColour(MDB.Gold.r, MDB.Gold.g, MDB.Gold.b, outerGlowAlpha);
|
||||||
|
drawRect(baseX + 4, itemY - 2, menu.width - 8, menu.itemHeight + 2, outerGlowCol);
|
||||||
|
|
||||||
|
// Main selection background with enhanced Glowing effect
|
||||||
|
let scrollbarAlpha = Math.floor((160 + Math.sin(scrollbarPulse) * 30) * menuOpenAnim);
|
||||||
|
let scrollbarColor = toColour(Glowing, Glowing + 30, 220, scrollbarAlpha);
|
||||||
drawRect(baseX + 6, itemY, menu.width - 12, menu.itemHeight - 2, scrollbarColor);
|
drawRect(baseX + 6, itemY, menu.width - 12, menu.itemHeight - 2, scrollbarColor);
|
||||||
|
|
||||||
|
// Inner highlight line (top)
|
||||||
|
let highlightLineColor = toColour(255, 255, 255, Math.floor(100 * menuOpenAnim));
|
||||||
|
drawRect(baseX + 8, itemY + 1, menu.width - 16, 1, highlightLineColor);
|
||||||
|
|
||||||
|
// Left accent bar
|
||||||
|
let accentColor = toColour(MDB.Gold.r, MDB.Gold.g, MDB.Gold.b, animAlpha);
|
||||||
|
drawRect(baseX + 6, itemY + 2, 3, menu.itemHeight - 6, accentColor);
|
||||||
|
|
||||||
} else if (item.action === "none") {
|
} else if (item.action === "none") {
|
||||||
// ===== MDB Separator/JumpOver =====
|
// ===== MDB Separator/JumpOver - Enhanced with subtle line =====
|
||||||
// No background, just different text color
|
let sepLineColor = toColour(MDB.JumpOver.r, MDB.JumpOver.g, MDB.JumpOver.b, Math.floor(80 * menuOpenAnim));
|
||||||
|
drawRect(baseX + 20, itemY + menu.itemHeight - 4, menu.width - 40, 1, sepLineColor);
|
||||||
}
|
}
|
||||||
// Normal items have no background in MDB style (transparent over Steelblue window)
|
// Normal items have no background in MDB style (transparent over Steelblue window)
|
||||||
|
|
||||||
@@ -2687,18 +2804,59 @@ addEventHandler("OnDrawnHUD", function(event) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===== MDB HELPER TEXT (Bottom of screen style) =====
|
// ===== ENHANCED FOOTER =====
|
||||||
// In MDB this appears at bottom of screen, we'll put in footer area
|
|
||||||
let footerY = yPos + visibleCount * menu.itemHeight;
|
let footerY = yPos + visibleCount * menu.itemHeight;
|
||||||
|
|
||||||
// Simple footer with MDB style helper text
|
// Footer background with gradient effect
|
||||||
let helperColor = toColour(MDB.Orange.r, MDB.Orange.g, MDB.Orange.b, animAlpha);
|
let footerBgColor = toColour(30, 50, 70, Math.floor(180 * menuOpenAnim));
|
||||||
let helperTextColor = toColour(MDB.StatsItem.r, MDB.StatsItem.g, MDB.StatsItem.b, Math.floor(200 * menuOpenAnim));
|
drawRect(baseX + 4, footerY + 2, menu.width - 8, menu.footerHeight - 4, footerBgColor);
|
||||||
|
|
||||||
drawText("[UP/DOWN] Navigate [ENTER] Select [BACKSPACE] Back", baseX + 15, footerY + 10, helperTextColor, 10);
|
// Footer top line
|
||||||
|
let footerLineColor = toColour(MDB.Gold.r, MDB.Gold.g, MDB.Gold.b, Math.floor((150 + Math.sin(footerPulse) * 50) * menuOpenAnim));
|
||||||
|
drawRect(baseX + 10, footerY + 2, menu.width - 20, 1, footerLineColor);
|
||||||
|
|
||||||
// ===== MDB SCROLL INDICATORS =====
|
// Navigation hints with icons
|
||||||
|
let helperTextColor = toColour(MDB.StatsItem.r, MDB.StatsItem.g, MDB.StatsItem.b, Math.floor(220 * menuOpenAnim));
|
||||||
|
let helperAccentColor = toColour(MDB.Gold.r, MDB.Gold.g, MDB.Gold.b, Math.floor(220 * menuOpenAnim));
|
||||||
|
|
||||||
|
// Draw key hints
|
||||||
|
drawText("[", baseX + 12, footerY + 12, helperAccentColor, 10);
|
||||||
|
drawText("UP/DOWN", baseX + 18, footerY + 12, helperTextColor, 10);
|
||||||
|
drawText("]", baseX + 68, footerY + 12, helperAccentColor, 10);
|
||||||
|
drawText("Navigate", baseX + 76, footerY + 12, helperTextColor, 9);
|
||||||
|
|
||||||
|
drawText("[", baseX + 130, footerY + 12, helperAccentColor, 10);
|
||||||
|
drawText("ENTER", baseX + 136, footerY + 12, helperTextColor, 10);
|
||||||
|
drawText("]", baseX + 172, footerY + 12, helperAccentColor, 10);
|
||||||
|
drawText("Select", baseX + 180, footerY + 12, helperTextColor, 9);
|
||||||
|
|
||||||
|
drawText("[", baseX + 225, footerY + 12, helperAccentColor, 10);
|
||||||
|
drawText("BACK", baseX + 231, footerY + 12, helperTextColor, 10);
|
||||||
|
drawText("]", baseX + 260, footerY + 12, helperAccentColor, 10);
|
||||||
|
drawText("Return", baseX + 268, footerY + 12, helperTextColor, 9);
|
||||||
|
|
||||||
|
// ===== ENHANCED SCROLLBAR (RIGHT SIDE) =====
|
||||||
if (items.length > menu.maxVisibleItems) {
|
if (items.length > menu.maxVisibleItems) {
|
||||||
|
let scrollbarX = baseX + menu.width - 10;
|
||||||
|
let scrollbarY = baseY + menu.headerHeight + 5;
|
||||||
|
let scrollbarH = visibleCount * menu.itemHeight - 10;
|
||||||
|
let maxScroll = items.length - visibleCount;
|
||||||
|
let scrollProgress = scrollOffset / maxScroll;
|
||||||
|
let thumbH = Math.max(30, scrollbarH * (visibleCount / items.length));
|
||||||
|
let thumbY = scrollbarY + scrollProgress * (scrollbarH - thumbH);
|
||||||
|
|
||||||
|
// Scrollbar track
|
||||||
|
let trackColor = toColour(40, 40, 50, Math.floor(150 * menuOpenAnim));
|
||||||
|
drawRect(scrollbarX, scrollbarY, 5, scrollbarH, trackColor);
|
||||||
|
|
||||||
|
// Scrollbar thumb with glow
|
||||||
|
let thumbGlowAlpha = Math.floor((60 + Math.sin(scrollbarPulse) * 30) * menuOpenAnim);
|
||||||
|
let thumbGlowColor = toColour(MDB.Gold.r, MDB.Gold.g, MDB.Gold.b, thumbGlowAlpha);
|
||||||
|
drawRect(scrollbarX - 1, thumbY - 1, 7, thumbH + 2, thumbGlowColor);
|
||||||
|
|
||||||
|
let thumbColor = toColour(MDB.Gold.r, MDB.Gold.g, MDB.Gold.b, Math.floor(220 * menuOpenAnim));
|
||||||
|
drawRect(scrollbarX, thumbY, 5, thumbH, thumbColor);
|
||||||
|
|
||||||
// Up arrow - Gold color, show when not at top
|
// Up arrow - Gold color, show when not at top
|
||||||
if (scrollOffset > 0) {
|
if (scrollOffset > 0) {
|
||||||
let upArrowY = baseY + menu.headerHeight + 2;
|
let upArrowY = baseY + menu.headerHeight + 2;
|
||||||
@@ -2707,34 +2865,49 @@ addEventHandler("OnDrawnHUD", function(event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Down arrow - Gold color, show when not at bottom
|
// Down arrow - Gold color, show when not at bottom
|
||||||
let maxScroll = items.length - visibleCount;
|
|
||||||
if (scrollOffset < maxScroll) {
|
if (scrollOffset < maxScroll) {
|
||||||
let downArrowY = footerY - 16;
|
let downArrowY = footerY - 16;
|
||||||
let downArrowColor = toColour(MDB.Gold.r, MDB.Gold.g, MDB.Gold.b, Math.floor(FlashingGhost * menuOpenAnim));
|
let downArrowColor = toColour(MDB.Gold.r, MDB.Gold.g, MDB.Gold.b, Math.floor(FlashingGhost * menuOpenAnim));
|
||||||
drawText("v", baseX + menu.width / 2 - 5, downArrowY, downArrowColor, 14);
|
drawText("v", baseX + menu.width / 2 - 5, downArrowY, downArrowColor, 14);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Page indicator
|
||||||
|
let pageText = (scrollOffset + 1) + "/" + (maxScroll + 1);
|
||||||
|
let pageColor = toColour(150, 150, 160, Math.floor(180 * menuOpenAnim));
|
||||||
|
drawText(pageText, baseX + menu.width - 45, footerY + 12, pageColor, 9);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===== MDB INFO BAR =====
|
// ===== ENHANCED INFO BAR =====
|
||||||
if (currentDescription && currentDescription.length > 0) {
|
if (currentDescription && currentDescription.length > 0) {
|
||||||
let infoY = baseY + totalHeight + 15;
|
let infoY = baseY + totalHeight + 15;
|
||||||
let infoBarHeight = infoBar.height;
|
let infoBarHeight = infoBar.height + 5;
|
||||||
|
|
||||||
// Background - Steelblue like window
|
// Shadow
|
||||||
let infoBgColor = toColour(MDB.Steelblue.r, MDB.Steelblue.g, MDB.Steelblue.b, Math.floor(160 * menuOpenAnim));
|
let infoShadow = toColour(0, 0, 0, Math.floor(100 * menuOpenAnim));
|
||||||
|
drawRect(baseX - 2, infoY - 2, menu.width + 4, infoBarHeight + 4, infoShadow);
|
||||||
|
|
||||||
|
// Background - Enhanced with gradient look
|
||||||
|
let infoBgColor = toColour(MDB.Steelblue.r - 20, MDB.Steelblue.g - 20, MDB.Steelblue.b - 20, Math.floor(200 * menuOpenAnim));
|
||||||
drawRect(baseX, infoY, menu.width, infoBarHeight, infoBgColor);
|
drawRect(baseX, infoY, menu.width, infoBarHeight, infoBgColor);
|
||||||
|
|
||||||
// White line at top
|
// Border
|
||||||
let infoLineColor = toColour(MDB.Line.r, MDB.Line.g, MDB.Line.b, animAlpha);
|
let infoBorderColor = toColour(MDB.Gold.r, MDB.Gold.g, MDB.Gold.b, Math.floor(180 * menuOpenAnim));
|
||||||
drawRect(baseX + 10, infoY + 2, menu.width - 20, 2, infoLineColor);
|
drawRect(baseX, infoY, menu.width, 2, infoBorderColor);
|
||||||
|
drawRect(baseX, infoY + infoBarHeight - 2, menu.width, 2, infoBorderColor);
|
||||||
|
drawRect(baseX, infoY, 2, infoBarHeight, infoBorderColor);
|
||||||
|
drawRect(baseX + menu.width - 2, infoY, 2, infoBarHeight, infoBorderColor);
|
||||||
|
|
||||||
// "INFO" label in Gold
|
// "INFO" label box
|
||||||
let infoLabelColor = toColour(MDB.Gold.r, MDB.Gold.g, MDB.Gold.b, animAlpha);
|
let infoLabelBg = toColour(MDB.Gold.r, MDB.Gold.g, MDB.Gold.b, Math.floor(200 * menuOpenAnim));
|
||||||
drawText("INFO", baseX + 12, infoY + 6, infoLabelColor, 10);
|
drawRect(baseX + 8, infoY + 6, 40, 16, infoLabelBg);
|
||||||
|
let infoLabelColor = toColour(0, 0, 0, animAlpha);
|
||||||
|
drawText("INFO", baseX + 12, infoY + 8, infoLabelColor, 10);
|
||||||
|
|
||||||
// Description text - white
|
// Description text - white with shadow
|
||||||
|
let descShadow = toColour(0, 0, 0, Math.floor(200 * menuOpenAnim));
|
||||||
let descColor = toColour(MDB.StatsItem.r, MDB.StatsItem.g, MDB.StatsItem.b, animAlpha);
|
let descColor = toColour(MDB.StatsItem.r, MDB.StatsItem.g, MDB.StatsItem.b, animAlpha);
|
||||||
drawText(currentDescription, baseX + 12, infoY + 20, descColor, 11);
|
drawText(currentDescription, baseX + 13, infoY + 28, descShadow, 11);
|
||||||
|
drawText(currentDescription, baseX + 12, infoY + 27, descColor, 11);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -2829,6 +3002,346 @@ addEventHandler("OnDrawnHUD", function(event) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// PLAYER STATS PANEL - Shows player info when menu is open
|
||||||
|
// ============================================================================
|
||||||
|
addEventHandler("OnDrawnHUD", function(event) {
|
||||||
|
if (menuOpenAnim <= 0) return;
|
||||||
|
if (!localPlayer) return;
|
||||||
|
|
||||||
|
let alpha = Math.floor(255 * menuOpenAnim);
|
||||||
|
let theme = getTheme();
|
||||||
|
|
||||||
|
// Panel position (top-left of screen)
|
||||||
|
let panelX = 30;
|
||||||
|
let panelY = 100;
|
||||||
|
let panelW = 220;
|
||||||
|
let panelH = 240;
|
||||||
|
|
||||||
|
// Slide in animation from left
|
||||||
|
let slideOffset = (1 - menuOpenAnim) * -100;
|
||||||
|
panelX += slideOffset;
|
||||||
|
|
||||||
|
// ===== PANEL SHADOW =====
|
||||||
|
let shadowColor = toColour(0, 0, 0, Math.floor(100 * menuOpenAnim));
|
||||||
|
drawRect(panelX - 3, panelY - 3, panelW + 6, panelH + 6, shadowColor);
|
||||||
|
|
||||||
|
// ===== PANEL BACKGROUND =====
|
||||||
|
let bgColor = toColour(MDB.Steelblue.r - 30, MDB.Steelblue.g - 30, MDB.Steelblue.b - 30, Math.floor(200 * menuOpenAnim));
|
||||||
|
drawRect(panelX, panelY, panelW, panelH, bgColor);
|
||||||
|
|
||||||
|
// Inner panel
|
||||||
|
let innerBg = toColour(20, 35, 55, Math.floor(150 * menuOpenAnim));
|
||||||
|
drawRect(panelX + 3, panelY + 3, panelW - 6, panelH - 6, innerBg);
|
||||||
|
|
||||||
|
// ===== PANEL BORDER =====
|
||||||
|
let borderCol = toColour(MDB.Gold.r, MDB.Gold.g, MDB.Gold.b, Math.floor((180 + borderGlow * 50) * menuOpenAnim));
|
||||||
|
drawRect(panelX, panelY, panelW, 2, borderCol);
|
||||||
|
drawRect(panelX, panelY + panelH - 2, panelW, 2, borderCol);
|
||||||
|
drawRect(panelX, panelY, 2, panelH, borderCol);
|
||||||
|
drawRect(panelX + panelW - 2, panelY, 2, panelH, borderCol);
|
||||||
|
|
||||||
|
// Corner accents
|
||||||
|
let cornerCol = toColour(255, 200, 100, Math.floor((200 + Math.sin(cornerPulse) * 55) * menuOpenAnim));
|
||||||
|
drawRect(panelX, panelY, 10, 2, cornerCol);
|
||||||
|
drawRect(panelX, panelY, 2, 10, cornerCol);
|
||||||
|
drawRect(panelX + panelW - 10, panelY, 10, 2, cornerCol);
|
||||||
|
drawRect(panelX + panelW - 2, panelY, 2, 10, cornerCol);
|
||||||
|
|
||||||
|
// ===== HEADER =====
|
||||||
|
let headerBg = toColour(MDB.Steelblue.r, MDB.Steelblue.g, MDB.Steelblue.b, Math.floor(220 * menuOpenAnim));
|
||||||
|
drawRect(panelX + 4, panelY + 4, panelW - 8, 28, headerBg);
|
||||||
|
|
||||||
|
let titleCol = toColour(255, 255, 255, alpha);
|
||||||
|
let titleShadow = toColour(0, 0, 0, alpha);
|
||||||
|
drawText("PLAYER STATUS", panelX + 11, panelY + 10, titleShadow, 13);
|
||||||
|
drawText("PLAYER STATUS", panelX + 10, panelY + 9, titleCol, 13);
|
||||||
|
|
||||||
|
// ===== STATS CONTENT =====
|
||||||
|
let contentY = panelY + 40;
|
||||||
|
let labelCol = toColour(MDB.Item.r, MDB.Item.g, MDB.Item.b, alpha);
|
||||||
|
let valueCol = toColour(255, 255, 255, alpha);
|
||||||
|
let rowH = 24;
|
||||||
|
|
||||||
|
// Health bar
|
||||||
|
drawText("Health", panelX + 12, contentY, labelCol, 10);
|
||||||
|
let health = localPlayer.health || 0;
|
||||||
|
let maxHealth = 200;
|
||||||
|
let healthPct = Math.min(1, health / maxHealth);
|
||||||
|
let healthBarBg = toColour(40, 40, 50, alpha);
|
||||||
|
drawRect(panelX + 12, contentY + 14, panelW - 24, 8, healthBarBg);
|
||||||
|
let healthCol = healthPct > 0.5 ? toColour(50, 200, 50, alpha) : healthPct > 0.25 ? toColour(255, 200, 0, alpha) : toColour(255, 50, 50, alpha);
|
||||||
|
drawRect(panelX + 12, contentY + 14, (panelW - 24) * healthPct, 8, healthCol);
|
||||||
|
drawText(Math.floor(health), panelX + panelW - 40, contentY, valueCol, 10);
|
||||||
|
contentY += rowH + 4;
|
||||||
|
|
||||||
|
// Armor bar
|
||||||
|
drawText("Armor", panelX + 12, contentY, labelCol, 10);
|
||||||
|
let armor = localPlayer.armour || 0;
|
||||||
|
let armorPct = Math.min(1, armor / 100);
|
||||||
|
drawRect(panelX + 12, contentY + 14, panelW - 24, 8, healthBarBg);
|
||||||
|
let armorCol = toColour(100, 150, 255, alpha);
|
||||||
|
drawRect(panelX + 12, contentY + 14, (panelW - 24) * armorPct, 8, armorCol);
|
||||||
|
drawText(Math.floor(armor), panelX + panelW - 40, contentY, valueCol, 10);
|
||||||
|
contentY += rowH + 8;
|
||||||
|
|
||||||
|
// Separator line
|
||||||
|
let sepCol = toColour(MDB.Gold.r, MDB.Gold.g, MDB.Gold.b, Math.floor(100 * menuOpenAnim));
|
||||||
|
drawRect(panelX + 10, contentY, panelW - 20, 1, sepCol);
|
||||||
|
contentY += 8;
|
||||||
|
|
||||||
|
// Wanted Level
|
||||||
|
drawText("Wanted Level", panelX + 12, contentY, labelCol, 10);
|
||||||
|
let wanted = 0;
|
||||||
|
try { wanted = localPlayer.wantedLevel || 0; } catch(e) {}
|
||||||
|
// Draw stars
|
||||||
|
for (let i = 0; i < 6; i++) {
|
||||||
|
let starCol = i < wanted ? toColour(255, 200, 0, alpha) : toColour(60, 60, 70, alpha);
|
||||||
|
drawRect(panelX + 100 + i * 18, contentY + 2, 12, 12, starCol);
|
||||||
|
}
|
||||||
|
contentY += rowH;
|
||||||
|
|
||||||
|
// Vehicle Status
|
||||||
|
drawText("Vehicle", panelX + 12, contentY, labelCol, 10);
|
||||||
|
let vehStatus = "On Foot";
|
||||||
|
let vehStatusCol = toColour(150, 150, 150, alpha);
|
||||||
|
if (localPlayer.vehicle) {
|
||||||
|
vehStatus = "In Vehicle";
|
||||||
|
vehStatusCol = toColour(100, 255, 100, alpha);
|
||||||
|
}
|
||||||
|
drawText(vehStatus, panelX + 100, contentY, vehStatusCol, 10);
|
||||||
|
contentY += rowH;
|
||||||
|
|
||||||
|
// Active Toggles Counter
|
||||||
|
drawText("Active Mods", panelX + 12, contentY, labelCol, 10);
|
||||||
|
let activeCount = 0;
|
||||||
|
for (let key in toggleStates) {
|
||||||
|
if (toggleStates[key]) activeCount++;
|
||||||
|
}
|
||||||
|
let modCountCol = activeCount > 0 ? toColour(MDB.ItemHighlight.r, MDB.ItemHighlight.g, MDB.ItemHighlight.b, alpha) : valueCol;
|
||||||
|
drawText(activeCount.toString(), panelX + 100, contentY, modCountCol, 10);
|
||||||
|
contentY += rowH + 8;
|
||||||
|
|
||||||
|
// ===== CLOCK / TIME DISPLAY =====
|
||||||
|
let clockY = panelY + panelH - 35;
|
||||||
|
drawRect(panelX + 10, clockY - 5, panelW - 20, 1, sepCol);
|
||||||
|
|
||||||
|
// Get current time
|
||||||
|
let now = new Date();
|
||||||
|
let hours = now.getHours().toString().padStart(2, '0');
|
||||||
|
let mins = now.getMinutes().toString().padStart(2, '0');
|
||||||
|
let secs = now.getSeconds().toString().padStart(2, '0');
|
||||||
|
let timeStr = hours + ":" + mins + ":" + secs;
|
||||||
|
|
||||||
|
// Time display with pulsing colon effect
|
||||||
|
let clockBg = toColour(MDB.Steelblue.r, MDB.Steelblue.g, MDB.Steelblue.b, Math.floor(180 * menuOpenAnim));
|
||||||
|
drawRect(panelX + panelW / 2 - 45, clockY, 90, 22, clockBg);
|
||||||
|
|
||||||
|
let clockCol = toColour(MDB.Gold.r, MDB.Gold.g, MDB.Gold.b, alpha);
|
||||||
|
let clockShadow = toColour(0, 0, 0, alpha);
|
||||||
|
drawText(timeStr, panelX + panelW / 2 - 35, clockY + 5, clockShadow, 14);
|
||||||
|
drawText(timeStr, panelX + panelW / 2 - 36, clockY + 4, clockCol, 14);
|
||||||
|
|
||||||
|
// Date
|
||||||
|
let dateCol = toColour(150, 150, 160, Math.floor(180 * menuOpenAnim));
|
||||||
|
let dateStr = (now.getMonth() + 1) + "/" + now.getDate() + "/" + now.getFullYear();
|
||||||
|
drawText(dateStr, panelX + 12, clockY + 6, dateCol, 9);
|
||||||
|
});
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// ACTIVE TOGGLES INDICATOR - Shows active mods in corner
|
||||||
|
// ============================================================================
|
||||||
|
addEventHandler("OnDrawnHUD", function(event) {
|
||||||
|
if (menuOpen) return; // Don't show when menu is open
|
||||||
|
if (!localPlayer) return;
|
||||||
|
|
||||||
|
// Count active toggles
|
||||||
|
let activeToggles = [];
|
||||||
|
if (toggleStates.godMode) activeToggles.push("GOD");
|
||||||
|
if (toggleStates.invincible) activeToggles.push("INV");
|
||||||
|
if (toggleStates.superRun) activeToggles.push("SPD");
|
||||||
|
if (toggleStates.neverWanted) activeToggles.push("NW");
|
||||||
|
if (toggleStates.invisible) activeToggles.push("INV");
|
||||||
|
if (toggleStates.vehGodMode) activeToggles.push("VGOD");
|
||||||
|
if (toggleStates.driftMode) activeToggles.push("DRFT");
|
||||||
|
if (toggleStates.rainbowCar) activeToggles.push("RGB");
|
||||||
|
if (toggleStates.flyMode) activeToggles.push("FLY");
|
||||||
|
|
||||||
|
if (activeToggles.length === 0) return;
|
||||||
|
|
||||||
|
// Position in top-right corner
|
||||||
|
let indicatorX = 1680;
|
||||||
|
let indicatorY = 20;
|
||||||
|
|
||||||
|
// Background
|
||||||
|
let bgColor = toColour(0, 0, 0, 150);
|
||||||
|
let bgWidth = 80;
|
||||||
|
let bgHeight = 20 + activeToggles.length * 16;
|
||||||
|
drawRect(indicatorX, indicatorY, bgWidth, bgHeight, bgColor);
|
||||||
|
|
||||||
|
// Border
|
||||||
|
let borderColor = toColour(MDB.Gold.r, MDB.Gold.g, MDB.Gold.b, 180);
|
||||||
|
drawRect(indicatorX, indicatorY, bgWidth, 2, borderColor);
|
||||||
|
drawRect(indicatorX, indicatorY + bgHeight - 2, bgWidth, 2, borderColor);
|
||||||
|
drawRect(indicatorX, indicatorY, 2, bgHeight, borderColor);
|
||||||
|
drawRect(indicatorX + bgWidth - 2, indicatorY, 2, bgHeight, borderColor);
|
||||||
|
|
||||||
|
// Title
|
||||||
|
let titleColor = toColour(MDB.Gold.r, MDB.Gold.g, MDB.Gold.b, 255);
|
||||||
|
drawText("ACTIVE", indicatorX + 18, indicatorY + 4, titleColor, 9);
|
||||||
|
|
||||||
|
// List active toggles
|
||||||
|
let listY = indicatorY + 20;
|
||||||
|
for (let i = 0; i < activeToggles.length; i++) {
|
||||||
|
let toggleColor = toColour(MDB.ItemHighlight.r, MDB.ItemHighlight.g, MDB.ItemHighlight.b, Math.floor(200 + Math.sin(animTime * 3 + i) * 55));
|
||||||
|
drawText(activeToggles[i], indicatorX + 8, listY + i * 16, toggleColor, 10);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// BOTTOM SCREEN BANNER - Shows when menu is open
|
||||||
|
// ============================================================================
|
||||||
|
addEventHandler("OnDrawnHUD", function(event) {
|
||||||
|
if (menuOpenAnim <= 0) return;
|
||||||
|
|
||||||
|
let screenWidth = 1920;
|
||||||
|
let screenHeight = 1080;
|
||||||
|
try {
|
||||||
|
screenWidth = game.width || 1920;
|
||||||
|
screenHeight = game.height || 1080;
|
||||||
|
} catch(e) {}
|
||||||
|
|
||||||
|
let alpha = Math.floor(255 * menuOpenAnim);
|
||||||
|
let bannerH = 45;
|
||||||
|
let bannerY = screenHeight - bannerH - 10;
|
||||||
|
|
||||||
|
// Slide up animation
|
||||||
|
let slideOffset = (1 - menuOpenAnim) * 60;
|
||||||
|
bannerY += slideOffset;
|
||||||
|
|
||||||
|
// Banner background
|
||||||
|
let bannerBg = toColour(0, 0, 0, Math.floor(180 * menuOpenAnim));
|
||||||
|
drawRect(0, bannerY, screenWidth, bannerH, bannerBg);
|
||||||
|
|
||||||
|
// Top border with gradient
|
||||||
|
let borderL = toColour(MDB.Gold.r, MDB.Gold.g, MDB.Gold.b, Math.floor((180 + borderGlow * 50) * menuOpenAnim));
|
||||||
|
let borderC = toColour(MDB.Steelblue.r, MDB.Steelblue.g, MDB.Steelblue.b, alpha);
|
||||||
|
drawRect(0, bannerY, screenWidth * 0.3, 2, borderL);
|
||||||
|
drawRect(screenWidth * 0.3, bannerY, screenWidth * 0.4, 2, borderC);
|
||||||
|
drawRect(screenWidth * 0.7, bannerY, screenWidth * 0.3, 2, borderL);
|
||||||
|
|
||||||
|
// Left logo
|
||||||
|
let logoShadow = toColour(0, 0, 0, alpha);
|
||||||
|
let logoGold = toColour(MDB.Gold.r, MDB.Gold.g, MDB.Gold.b, alpha);
|
||||||
|
let logoBlue = toColour(MDB.Steelblue.r + 40, MDB.Steelblue.g + 40, MDB.Steelblue.b + 40, alpha);
|
||||||
|
drawText("MD", 21, bannerY + 12, logoShadow, 18);
|
||||||
|
drawText("MD", 20, bannerY + 11, logoBlue, 18);
|
||||||
|
drawText("REVOLUTION", 58, bannerY + 15, logoShadow, 14);
|
||||||
|
drawText("REVOLUTION", 57, bannerY + 14, logoGold, 14);
|
||||||
|
|
||||||
|
// Center text - server info
|
||||||
|
let centerText = "GTA CONNECTED";
|
||||||
|
let centerX = screenWidth / 2 - centerText.length * 4;
|
||||||
|
let centerCol = toColour(MDB.SubHeader.r, MDB.SubHeader.g, MDB.SubHeader.b, alpha);
|
||||||
|
drawText(centerText, centerX + 1, bannerY + 16, logoShadow, 12);
|
||||||
|
drawText(centerText, centerX, bannerY + 15, centerCol, 12);
|
||||||
|
|
||||||
|
// Right side - F5 hint
|
||||||
|
let hintCol = toColour(150, 150, 160, alpha);
|
||||||
|
let keyCol = toColour(MDB.Gold.r, MDB.Gold.g, MDB.Gold.b, alpha);
|
||||||
|
drawText("Press", screenWidth - 150, bannerY + 15, hintCol, 10);
|
||||||
|
drawText("[F5]", screenWidth - 115, bannerY + 15, keyCol, 10);
|
||||||
|
drawText("to close", screenWidth - 80, bannerY + 15, hintCol, 10);
|
||||||
|
|
||||||
|
// Animated bottom line
|
||||||
|
let lineAlpha = Math.floor((150 + Math.sin(footerPulse) * 60) * menuOpenAnim);
|
||||||
|
let lineCol = toColour(MDB.Gold.r, MDB.Gold.g, MDB.Gold.b, lineAlpha);
|
||||||
|
drawRect(0, bannerY + bannerH - 2, screenWidth, 2, lineCol);
|
||||||
|
});
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// MENU PARTICLE EFFECTS - Subtle floating particles
|
||||||
|
// ============================================================================
|
||||||
|
addEventHandler("OnDrawnHUD", function(event) {
|
||||||
|
if (menuOpenAnim <= 0.1) return;
|
||||||
|
|
||||||
|
let baseX = menu.x;
|
||||||
|
let baseY = menu.y;
|
||||||
|
let alpha = Math.floor(255 * menuOpenAnim);
|
||||||
|
|
||||||
|
// Generate particles around the menu
|
||||||
|
for (let i = 0; i < 8; i++) {
|
||||||
|
let angle = (animTime * 0.5 + i * 0.785) % (Math.PI * 2);
|
||||||
|
let radius = 180 + Math.sin(animTime + i) * 30;
|
||||||
|
let px = baseX + menu.width / 2 + Math.cos(angle) * radius;
|
||||||
|
let py = baseY + 250 + Math.sin(angle) * 100;
|
||||||
|
|
||||||
|
// Floating particle
|
||||||
|
let particleAlpha = Math.floor((40 + Math.sin(animTime * 2 + i) * 25) * menuOpenAnim);
|
||||||
|
let particleSize = 3 + Math.sin(animTime + i * 0.5) * 2;
|
||||||
|
|
||||||
|
// Gold particles
|
||||||
|
let pColor = toColour(MDB.Gold.r, MDB.Gold.g, MDB.Gold.b, particleAlpha);
|
||||||
|
drawRect(px, py, particleSize, particleSize, pColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Subtle sparkle effects on corners
|
||||||
|
let sparkleTime = animTime * 3;
|
||||||
|
for (let i = 0; i < 4; i++) {
|
||||||
|
let sparkleAlpha = Math.floor(Math.max(0, Math.sin(sparkleTime + i * 1.57) * 80) * menuOpenAnim);
|
||||||
|
if (sparkleAlpha > 10) {
|
||||||
|
let sx, sy;
|
||||||
|
switch(i) {
|
||||||
|
case 0: sx = baseX - 5; sy = baseY - 5; break;
|
||||||
|
case 1: sx = baseX + menu.width + 2; sy = baseY - 5; break;
|
||||||
|
case 2: sx = baseX - 5; sy = baseY + 450; break;
|
||||||
|
case 3: sx = baseX + menu.width + 2; sy = baseY + 450; break;
|
||||||
|
}
|
||||||
|
let sparkleCol = toColour(255, 255, 200, sparkleAlpha);
|
||||||
|
drawRect(sx, sy, 4, 4, sparkleCol);
|
||||||
|
drawRect(sx - 1, sy + 1, 6, 2, sparkleCol);
|
||||||
|
drawRect(sx + 1, sy - 1, 2, 6, sparkleCol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// MENU TITLE BADGE (Above main menu)
|
||||||
|
// ============================================================================
|
||||||
|
addEventHandler("OnDrawnHUD", function(event) {
|
||||||
|
if (menuOpenAnim <= 0) return;
|
||||||
|
|
||||||
|
let alpha = Math.floor(255 * menuOpenAnim);
|
||||||
|
let slideOffset = (1 - menuOpenAnim) * 120;
|
||||||
|
let baseX = menu.x + slideOffset;
|
||||||
|
let baseY = menu.y - 50;
|
||||||
|
|
||||||
|
// Slide down animation
|
||||||
|
let slideDown = (1 - menuOpenAnim) * -30;
|
||||||
|
baseY += slideDown;
|
||||||
|
|
||||||
|
// Badge background
|
||||||
|
let badgeBg = toColour(MDB.DevilsRed.r, MDB.DevilsRed.g, MDB.DevilsRed.b, Math.floor(220 * menuOpenAnim));
|
||||||
|
drawRect(baseX + menu.width / 2 - 80, baseY, 160, 35, badgeBg);
|
||||||
|
|
||||||
|
// Border glow
|
||||||
|
let borderGlowCol = toColour(MDB.Gold.r, MDB.Gold.g, MDB.Gold.b, Math.floor((100 + borderGlow * 80) * menuOpenAnim));
|
||||||
|
drawRect(baseX + menu.width / 2 - 82, baseY - 2, 164, 2, borderGlowCol);
|
||||||
|
drawRect(baseX + menu.width / 2 - 82, baseY + 35, 164, 2, borderGlowCol);
|
||||||
|
drawRect(baseX + menu.width / 2 - 82, baseY - 2, 2, 39, borderGlowCol);
|
||||||
|
drawRect(baseX + menu.width / 2 + 80, baseY - 2, 2, 39, borderGlowCol);
|
||||||
|
|
||||||
|
// Badge text
|
||||||
|
let badgeShadow = toColour(0, 0, 0, alpha);
|
||||||
|
let badgeText = toColour(255, 255, 255, alpha);
|
||||||
|
drawText("TRIDENT EDITION", baseX + menu.width / 2 - 60, baseY + 11, badgeShadow, 13);
|
||||||
|
drawText("TRIDENT EDITION", baseX + menu.width / 2 - 61, baseY + 10, badgeText, 13);
|
||||||
|
|
||||||
|
// Version number
|
||||||
|
let versionCol = toColour(MDB.Gold.r, MDB.Gold.g, MDB.Gold.b, Math.floor(FlashingGhost * menuOpenAnim));
|
||||||
|
drawText("v2.0", baseX + menu.width / 2 + 48, baseY + 12, versionCol, 10);
|
||||||
|
});
|
||||||
|
|
||||||
// Draw rectangle using graphics API
|
// Draw rectangle using graphics API
|
||||||
function drawRect(x, y, w, h, colour) {
|
function drawRect(x, y, w, h, colour) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user