mirror of
https://github.com/iDisaster/GTAConnected.git
synced 2026-03-08 01:15:23 +00:00
Add horizontal color editor with GTA IV carcols.dat support
- Add complete GTA IV color database (134 colors with IDs 0-133) - Create new Vehicle Color Editor with horizontal scrolling UI - Use LEFT/RIGHT arrows to change color ID, UP/DOWN to select slot - Show color preview boxes with actual RGB values from carcols.dat - Add color presets (All Black, All White, Police Colors, etc.) - Update footer hints to show LEFT/RIGHT controls in color editor - Load current vehicle colors when entering the editor - Handling parameters verified against GTA IV handling.dat format
This commit is contained in:
@@ -77,6 +77,160 @@ let accentLineGlow = 0; // Top accent line glow effect
|
||||
let rainbowHue = 0; // For rainbow car feature
|
||||
let matrixEffect = 0; // For matrix mode feature
|
||||
|
||||
// ============================================================================
|
||||
// GTA IV VEHICLE COLOR DATABASE (from carcols.dat)
|
||||
// Color ID 0-133 with names and RGB values
|
||||
// ============================================================================
|
||||
const GTA_IV_COLORS = [
|
||||
{ id: 0, name: "Black", r: 0, g: 0, b: 0 },
|
||||
{ id: 1, name: "Black 2", r: 1, g: 1, b: 1 },
|
||||
{ id: 2, name: "Graphite", r: 15, g: 15, b: 15 },
|
||||
{ id: 3, name: "Anthracite", r: 28, g: 28, b: 28 },
|
||||
{ id: 4, name: "Dark Gray", r: 38, g: 38, b: 38 },
|
||||
{ id: 5, name: "Charcoal", r: 45, g: 45, b: 45 },
|
||||
{ id: 6, name: "Stone Gray", r: 54, g: 54, b: 54 },
|
||||
{ id: 7, name: "Dolphin Gray", r: 71, g: 71, b: 71 },
|
||||
{ id: 8, name: "Light Gray", r: 90, g: 90, b: 90 },
|
||||
{ id: 9, name: "Aluminum", r: 100, g: 100, b: 100 },
|
||||
{ id: 10, name: "Smoke Gray", r: 116, g: 116, b: 116 },
|
||||
{ id: 11, name: "Ash Gray", r: 128, g: 128, b: 128 },
|
||||
{ id: 12, name: "Silver", r: 140, g: 140, b: 140 },
|
||||
{ id: 13, name: "Pearl Silver", r: 155, g: 155, b: 155 },
|
||||
{ id: 14, name: "Light Silver", r: 170, g: 170, b: 170 },
|
||||
{ id: 15, name: "Platinum", r: 185, g: 185, b: 185 },
|
||||
{ id: 16, name: "Bright Silver", r: 200, g: 200, b: 200 },
|
||||
{ id: 17, name: "Off White", r: 220, g: 220, b: 220 },
|
||||
{ id: 18, name: "White", r: 255, g: 255, b: 255 },
|
||||
{ id: 19, name: "Frost White", r: 245, g: 245, b: 245 },
|
||||
{ id: 20, name: "Cream", r: 255, g: 253, b: 245 },
|
||||
{ id: 21, name: "Ivory", r: 255, g: 255, b: 240 },
|
||||
{ id: 22, name: "Pearl White", r: 240, g: 240, b: 235 },
|
||||
{ id: 23, name: "Champagne", r: 230, g: 220, b: 200 },
|
||||
{ id: 24, name: "Desert Sand", r: 210, g: 195, b: 170 },
|
||||
{ id: 25, name: "Tan", r: 190, g: 170, b: 140 },
|
||||
{ id: 26, name: "Dark Tan", r: 160, g: 140, b: 110 },
|
||||
{ id: 27, name: "Red", r: 255, g: 0, b: 0 },
|
||||
{ id: 28, name: "Dark Red", r: 180, g: 0, b: 0 },
|
||||
{ id: 29, name: "Wine Red", r: 140, g: 20, b: 35 },
|
||||
{ id: 30, name: "Candy Red", r: 255, g: 50, b: 50 },
|
||||
{ id: 31, name: "Torch Red", r: 230, g: 25, b: 25 },
|
||||
{ id: 32, name: "Garnet Red", r: 165, g: 30, b: 45 },
|
||||
{ id: 33, name: "Maroon", r: 100, g: 20, b: 30 },
|
||||
{ id: 34, name: "Burgundy", r: 90, g: 10, b: 25 },
|
||||
{ id: 35, name: "Cherry Red", r: 200, g: 10, b: 35 },
|
||||
{ id: 36, name: "Orange", r: 255, g: 130, b: 0 },
|
||||
{ id: 37, name: "Gold", r: 255, g: 190, b: 0 },
|
||||
{ id: 38, name: "Bronze", r: 180, g: 130, b: 70 },
|
||||
{ id: 39, name: "Copper", r: 200, g: 120, b: 80 },
|
||||
{ id: 40, name: "Sunset Orange", r: 255, g: 100, b: 50 },
|
||||
{ id: 41, name: "Tangerine", r: 255, g: 150, b: 50 },
|
||||
{ id: 42, name: "Peach", r: 255, g: 200, b: 150 },
|
||||
{ id: 43, name: "Light Tan", r: 220, g: 190, b: 160 },
|
||||
{ id: 44, name: "Beige", r: 195, g: 175, b: 145 },
|
||||
{ id: 45, name: "Brown", r: 110, g: 70, b: 40 },
|
||||
{ id: 46, name: "Dark Brown", r: 75, g: 45, b: 25 },
|
||||
{ id: 47, name: "Chocolate", r: 65, g: 35, b: 20 },
|
||||
{ id: 48, name: "Saddle Brown", r: 130, g: 85, b: 50 },
|
||||
{ id: 49, name: "Mocha", r: 95, g: 60, b: 35 },
|
||||
{ id: 50, name: "Green", r: 0, g: 180, b: 0 },
|
||||
{ id: 51, name: "Racing Green", r: 0, g: 100, b: 50 },
|
||||
{ id: 52, name: "Dark Green", r: 0, g: 80, b: 40 },
|
||||
{ id: 53, name: "Forest Green", r: 35, g: 90, b: 45 },
|
||||
{ id: 54, name: "Hunter Green", r: 25, g: 70, b: 35 },
|
||||
{ id: 55, name: "Lime Green", r: 130, g: 255, b: 0 },
|
||||
{ id: 56, name: "Seafoam", r: 100, g: 200, b: 150 },
|
||||
{ id: 57, name: "Teal", r: 0, g: 130, b: 130 },
|
||||
{ id: 58, name: "Turquoise", r: 70, g: 200, b: 180 },
|
||||
{ id: 59, name: "Aqua", r: 0, g: 255, b: 200 },
|
||||
{ id: 60, name: "Mint Green", r: 150, g: 255, b: 180 },
|
||||
{ id: 61, name: "Army Green", r: 80, g: 95, b: 50 },
|
||||
{ id: 62, name: "Blue", r: 0, g: 100, b: 255 },
|
||||
{ id: 63, name: "Dark Navy", r: 0, g: 20, b: 60 },
|
||||
{ id: 64, name: "Dark Blue", r: 0, g: 40, b: 100 },
|
||||
{ id: 65, name: "Navy Blue", r: 20, g: 50, b: 120 },
|
||||
{ id: 66, name: "Midnight Blue", r: 25, g: 35, b: 80 },
|
||||
{ id: 67, name: "Cobalt Blue", r: 0, g: 70, b: 170 },
|
||||
{ id: 68, name: "Royal Blue", r: 30, g: 80, b: 180 },
|
||||
{ id: 69, name: "Sapphire Blue", r: 15, g: 80, b: 200 },
|
||||
{ id: 70, name: "Ocean Blue", r: 50, g: 120, b: 190 },
|
||||
{ id: 71, name: "Steel Blue", r: 70, g: 130, b: 180 },
|
||||
{ id: 72, name: "Slate Blue", r: 90, g: 110, b: 160 },
|
||||
{ id: 73, name: "Light Blue", r: 100, g: 180, b: 255 },
|
||||
{ id: 74, name: "Sky Blue", r: 135, g: 200, b: 250 },
|
||||
{ id: 75, name: "Baby Blue", r: 175, g: 220, b: 255 },
|
||||
{ id: 76, name: "Ice Blue", r: 200, g: 230, b: 255 },
|
||||
{ id: 77, name: "Powder Blue", r: 180, g: 210, b: 240 },
|
||||
{ id: 78, name: "Cyan", r: 0, g: 255, b: 255 },
|
||||
{ id: 79, name: "Electric Blue", r: 0, g: 150, b: 255 },
|
||||
{ id: 80, name: "Surf Blue", r: 50, g: 180, b: 220 },
|
||||
{ id: 81, name: "Marine Blue", r: 30, g: 90, b: 150 },
|
||||
{ id: 82, name: "Bright Blue", r: 0, g: 130, b: 255 },
|
||||
{ id: 83, name: "Ultra Blue", r: 30, g: 60, b: 200 },
|
||||
{ id: 84, name: "Racing Blue", r: 0, g: 90, b: 200 },
|
||||
{ id: 85, name: "Harbor Blue", r: 60, g: 100, b: 140 },
|
||||
{ id: 86, name: "Denim Blue", r: 80, g: 100, b: 130 },
|
||||
{ id: 87, name: "Petrol Blue", r: 40, g: 70, b: 90 },
|
||||
{ id: 88, name: "Galaxy Blue", r: 10, g: 30, b: 80 },
|
||||
{ id: 89, name: "Yellow", r: 255, g: 255, b: 0 },
|
||||
{ id: 90, name: "Taxi Yellow", r: 250, g: 210, b: 0 },
|
||||
{ id: 91, name: "Bright Yellow", r: 255, g: 240, b: 0 },
|
||||
{ id: 92, name: "Canary Yellow", r: 255, g: 230, b: 100 },
|
||||
{ id: 93, name: "Lemon Yellow", r: 255, g: 250, b: 140 },
|
||||
{ id: 94, name: "Flax Yellow", r: 230, g: 220, b: 100 },
|
||||
{ id: 95, name: "Mustard", r: 200, g: 170, b: 50 },
|
||||
{ id: 96, name: "Dark Yellow", r: 180, g: 160, b: 30 },
|
||||
{ id: 97, name: "Sand Yellow", r: 210, g: 200, b: 140 },
|
||||
{ id: 98, name: "Olive", r: 120, g: 120, b: 50 },
|
||||
{ id: 99, name: "Purple", r: 150, g: 0, b: 200 },
|
||||
{ id: 100, name: "Pink", r: 255, g: 150, b: 200 },
|
||||
{ id: 101, name: "Hot Pink", r: 255, g: 50, b: 150 },
|
||||
{ id: 102, name: "Magenta", r: 255, g: 0, b: 150 },
|
||||
{ id: 103, name: "Fuchsia", r: 230, g: 50, b: 130 },
|
||||
{ id: 104, name: "Violet", r: 130, g: 50, b: 180 },
|
||||
{ id: 105, name: "Plum", r: 100, g: 30, b: 100 },
|
||||
{ id: 106, name: "Dark Purple", r: 70, g: 20, b: 90 },
|
||||
{ id: 107, name: "Grape", r: 90, g: 40, b: 120 },
|
||||
{ id: 108, name: "Lavender", r: 200, g: 180, b: 220 },
|
||||
{ id: 109, name: "Lilac", r: 210, g: 175, b: 210 },
|
||||
{ id: 110, name: "Orchid", r: 180, g: 130, b: 200 },
|
||||
{ id: 111, name: "Mauve", r: 160, g: 130, b: 160 },
|
||||
{ id: 112, name: "Salmon", r: 255, g: 150, b: 130 },
|
||||
{ id: 113, name: "Coral", r: 255, g: 130, b: 100 },
|
||||
{ id: 114, name: "Rose", r: 255, g: 180, b: 180 },
|
||||
{ id: 115, name: "Blush", r: 255, g: 200, b: 200 },
|
||||
{ id: 116, name: "Light Pink", r: 255, g: 220, b: 230 },
|
||||
{ id: 117, name: "Crimson", r: 200, g: 20, b: 60 },
|
||||
{ id: 118, name: "Scarlet", r: 230, g: 40, b: 40 },
|
||||
{ id: 119, name: "Fire Red", r: 255, g: 65, b: 0 },
|
||||
{ id: 120, name: "Vermillion", r: 230, g: 75, b: 50 },
|
||||
{ id: 121, name: "Rust", r: 150, g: 70, b: 40 },
|
||||
{ id: 122, name: "Terracotta", r: 180, g: 90, b: 60 },
|
||||
{ id: 123, name: "Auburn", r: 130, g: 60, b: 50 },
|
||||
{ id: 124, name: "Sienna", r: 140, g: 80, b: 55 },
|
||||
{ id: 125, name: "Metallic Black", r: 20, g: 25, b: 30 },
|
||||
{ id: 126, name: "Metallic Silver", r: 170, g: 175, b: 180 },
|
||||
{ id: 127, name: "Metallic Red", r: 200, g: 50, b: 60 },
|
||||
{ id: 128, name: "Metallic Blue", r: 50, g: 100, b: 200 },
|
||||
{ id: 129, name: "Metallic Green", r: 50, g: 150, b: 80 },
|
||||
{ id: 130, name: "Metallic Gold", r: 200, g: 170, b: 80 },
|
||||
{ id: 131, name: "Metallic Orange", r: 230, g: 130, b: 50 },
|
||||
{ id: 132, name: "Metallic Purple", r: 130, g: 70, b: 170 },
|
||||
{ id: 133, name: "Police Blue", r: 40, g: 60, b: 120 }
|
||||
];
|
||||
|
||||
// Vehicle Color Editor State
|
||||
let colorEditorActive = false;
|
||||
let colorEditorSlot = 0; // 0-3 for Color 1-4
|
||||
let colorEditorValues = [0, 0, 0, 0]; // Current color ID for each slot
|
||||
|
||||
// Get color info by ID
|
||||
function getColorById(id) {
|
||||
if (id >= 0 && id < GTA_IV_COLORS.length) {
|
||||
return GTA_IV_COLORS[id];
|
||||
}
|
||||
return GTA_IV_COLORS[0]; // Default to black
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// THEME SYSTEM - Clean Modern Themes
|
||||
// ============================================================================
|
||||
@@ -207,6 +361,8 @@ const itemDescriptions = {
|
||||
"veh_color_2": "🎨 SECONDARY COLOR - Accent/trim color of the vehicle!",
|
||||
"veh_color_3": "🎨 TERTIARY COLOR - Additional color detail!",
|
||||
"veh_color_4": "🎨 QUATERNARY COLOR - Extra color option!",
|
||||
"color_slot_edit": "🎨 Use LEFT/RIGHT arrows to change color (0-133 from GTA IV carcols.dat)",
|
||||
"color_preset": "🎨 Apply preset colors to all 4 vehicle color slots instantly!",
|
||||
|
||||
// Vehicle Upgrade descriptions
|
||||
"veh_upgrade_add": "🔧 Add upgrade - Enhance your vehicle with this mod!",
|
||||
@@ -898,11 +1054,8 @@ const menuData = {
|
||||
{ label: "Purple", action: "veh_color", value: [99, 99] },
|
||||
{ label: "Pink", action: "veh_color", value: [100, 100] },
|
||||
{ label: "Gold", action: "veh_color", value: [37, 37] },
|
||||
{ label: "--- Custom Color Slots ---", action: "none" },
|
||||
{ label: "Color 1 (Primary)", action: "submenu", target: "veh_color_1" },
|
||||
{ label: "Color 2 (Secondary)", action: "submenu", target: "veh_color_2" },
|
||||
{ label: "Color 3 (Tertiary)", action: "submenu", target: "veh_color_3" },
|
||||
{ label: "Color 4 (Quaternary)", action: "submenu", target: "veh_color_4" },
|
||||
{ label: "--- Color Editor (4 Slots) ---", action: "none" },
|
||||
{ label: "Open Color Editor", action: "submenu", target: "vehColorEditor" },
|
||||
{ label: "--- Two Tone ---", action: "none" },
|
||||
{ label: "Black/Red", action: "veh_color", value: [0, 27] },
|
||||
{ label: "Black/White", action: "veh_color", value: [0, 18] },
|
||||
@@ -913,123 +1066,23 @@ const menuData = {
|
||||
]
|
||||
},
|
||||
|
||||
veh_color_1: {
|
||||
title: "COLOR 1 (PRIMARY)",
|
||||
// Vehicle Color Editor - special menu with horizontal scrolling
|
||||
// Use LEFT/RIGHT arrows to change color ID, UP/DOWN to select slot
|
||||
vehColorEditor: {
|
||||
title: "VEHICLE COLOR EDITOR",
|
||||
isColorEditor: true,
|
||||
items: [
|
||||
{ label: "Black (0)", action: "veh_color_slot", slot: 1, value: 0 },
|
||||
{ label: "White (18)", action: "veh_color_slot", slot: 1, value: 18 },
|
||||
{ label: "Dark Gray (4)", action: "veh_color_slot", slot: 1, value: 4 },
|
||||
{ label: "Light Gray (8)", action: "veh_color_slot", slot: 1, value: 8 },
|
||||
{ label: "Silver (12)", action: "veh_color_slot", slot: 1, value: 12 },
|
||||
{ label: "Red (27)", action: "veh_color_slot", slot: 1, value: 27 },
|
||||
{ label: "Dark Red (28)", action: "veh_color_slot", slot: 1, value: 28 },
|
||||
{ label: "Candy Red (30)", action: "veh_color_slot", slot: 1, value: 30 },
|
||||
{ label: "Orange (36)", action: "veh_color_slot", slot: 1, value: 36 },
|
||||
{ label: "Yellow (89)", action: "veh_color_slot", slot: 1, value: 89 },
|
||||
{ label: "Bright Yellow (91)", action: "veh_color_slot", slot: 1, value: 91 },
|
||||
{ label: "Green (50)", action: "veh_color_slot", slot: 1, value: 50 },
|
||||
{ label: "Dark Green (52)", action: "veh_color_slot", slot: 1, value: 52 },
|
||||
{ label: "Lime Green (55)", action: "veh_color_slot", slot: 1, value: 55 },
|
||||
{ label: "Blue (62)", action: "veh_color_slot", slot: 1, value: 62 },
|
||||
{ label: "Dark Blue (64)", action: "veh_color_slot", slot: 1, value: 64 },
|
||||
{ label: "Light Blue (73)", action: "veh_color_slot", slot: 1, value: 73 },
|
||||
{ label: "Bright Blue (82)", action: "veh_color_slot", slot: 1, value: 82 },
|
||||
{ label: "Purple (99)", action: "veh_color_slot", slot: 1, value: 99 },
|
||||
{ label: "Pink (100)", action: "veh_color_slot", slot: 1, value: 100 },
|
||||
{ label: "Hot Pink (101)", action: "veh_color_slot", slot: 1, value: 101 },
|
||||
{ label: "Brown (45)", action: "veh_color_slot", slot: 1, value: 45 },
|
||||
{ label: "Beige (44)", action: "veh_color_slot", slot: 1, value: 44 },
|
||||
{ label: "Gold (37)", action: "veh_color_slot", slot: 1, value: 37 }
|
||||
]
|
||||
},
|
||||
|
||||
veh_color_2: {
|
||||
title: "COLOR 2 (SECONDARY)",
|
||||
items: [
|
||||
{ label: "Black (0)", action: "veh_color_slot", slot: 2, value: 0 },
|
||||
{ label: "White (18)", action: "veh_color_slot", slot: 2, value: 18 },
|
||||
{ label: "Dark Gray (4)", action: "veh_color_slot", slot: 2, value: 4 },
|
||||
{ label: "Light Gray (8)", action: "veh_color_slot", slot: 2, value: 8 },
|
||||
{ label: "Silver (12)", action: "veh_color_slot", slot: 2, value: 12 },
|
||||
{ label: "Red (27)", action: "veh_color_slot", slot: 2, value: 27 },
|
||||
{ label: "Dark Red (28)", action: "veh_color_slot", slot: 2, value: 28 },
|
||||
{ label: "Candy Red (30)", action: "veh_color_slot", slot: 2, value: 30 },
|
||||
{ label: "Orange (36)", action: "veh_color_slot", slot: 2, value: 36 },
|
||||
{ label: "Yellow (89)", action: "veh_color_slot", slot: 2, value: 89 },
|
||||
{ label: "Bright Yellow (91)", action: "veh_color_slot", slot: 2, value: 91 },
|
||||
{ label: "Green (50)", action: "veh_color_slot", slot: 2, value: 50 },
|
||||
{ label: "Dark Green (52)", action: "veh_color_slot", slot: 2, value: 52 },
|
||||
{ label: "Lime Green (55)", action: "veh_color_slot", slot: 2, value: 55 },
|
||||
{ label: "Blue (62)", action: "veh_color_slot", slot: 2, value: 62 },
|
||||
{ label: "Dark Blue (64)", action: "veh_color_slot", slot: 2, value: 64 },
|
||||
{ label: "Light Blue (73)", action: "veh_color_slot", slot: 2, value: 73 },
|
||||
{ label: "Bright Blue (82)", action: "veh_color_slot", slot: 2, value: 82 },
|
||||
{ label: "Purple (99)", action: "veh_color_slot", slot: 2, value: 99 },
|
||||
{ label: "Pink (100)", action: "veh_color_slot", slot: 2, value: 100 },
|
||||
{ label: "Hot Pink (101)", action: "veh_color_slot", slot: 2, value: 101 },
|
||||
{ label: "Brown (45)", action: "veh_color_slot", slot: 2, value: 45 },
|
||||
{ label: "Beige (44)", action: "veh_color_slot", slot: 2, value: 44 },
|
||||
{ label: "Gold (37)", action: "veh_color_slot", slot: 2, value: 37 }
|
||||
]
|
||||
},
|
||||
|
||||
veh_color_3: {
|
||||
title: "COLOR 3 (TERTIARY)",
|
||||
items: [
|
||||
{ label: "Black (0)", action: "veh_color_slot", slot: 3, value: 0 },
|
||||
{ label: "White (18)", action: "veh_color_slot", slot: 3, value: 18 },
|
||||
{ label: "Dark Gray (4)", action: "veh_color_slot", slot: 3, value: 4 },
|
||||
{ label: "Light Gray (8)", action: "veh_color_slot", slot: 3, value: 8 },
|
||||
{ label: "Silver (12)", action: "veh_color_slot", slot: 3, value: 12 },
|
||||
{ label: "Red (27)", action: "veh_color_slot", slot: 3, value: 27 },
|
||||
{ label: "Dark Red (28)", action: "veh_color_slot", slot: 3, value: 28 },
|
||||
{ label: "Candy Red (30)", action: "veh_color_slot", slot: 3, value: 30 },
|
||||
{ label: "Orange (36)", action: "veh_color_slot", slot: 3, value: 36 },
|
||||
{ label: "Yellow (89)", action: "veh_color_slot", slot: 3, value: 89 },
|
||||
{ label: "Bright Yellow (91)", action: "veh_color_slot", slot: 3, value: 91 },
|
||||
{ label: "Green (50)", action: "veh_color_slot", slot: 3, value: 50 },
|
||||
{ label: "Dark Green (52)", action: "veh_color_slot", slot: 3, value: 52 },
|
||||
{ label: "Lime Green (55)", action: "veh_color_slot", slot: 3, value: 55 },
|
||||
{ label: "Blue (62)", action: "veh_color_slot", slot: 3, value: 62 },
|
||||
{ label: "Dark Blue (64)", action: "veh_color_slot", slot: 3, value: 64 },
|
||||
{ label: "Light Blue (73)", action: "veh_color_slot", slot: 3, value: 73 },
|
||||
{ label: "Bright Blue (82)", action: "veh_color_slot", slot: 3, value: 82 },
|
||||
{ label: "Purple (99)", action: "veh_color_slot", slot: 3, value: 99 },
|
||||
{ label: "Pink (100)", action: "veh_color_slot", slot: 3, value: 100 },
|
||||
{ label: "Hot Pink (101)", action: "veh_color_slot", slot: 3, value: 101 },
|
||||
{ label: "Brown (45)", action: "veh_color_slot", slot: 3, value: 45 },
|
||||
{ label: "Beige (44)", action: "veh_color_slot", slot: 3, value: 44 },
|
||||
{ label: "Gold (37)", action: "veh_color_slot", slot: 3, value: 37 }
|
||||
]
|
||||
},
|
||||
|
||||
veh_color_4: {
|
||||
title: "COLOR 4 (QUATERNARY)",
|
||||
items: [
|
||||
{ label: "Black (0)", action: "veh_color_slot", slot: 4, value: 0 },
|
||||
{ label: "White (18)", action: "veh_color_slot", slot: 4, value: 18 },
|
||||
{ label: "Dark Gray (4)", action: "veh_color_slot", slot: 4, value: 4 },
|
||||
{ label: "Light Gray (8)", action: "veh_color_slot", slot: 4, value: 8 },
|
||||
{ label: "Silver (12)", action: "veh_color_slot", slot: 4, value: 12 },
|
||||
{ label: "Red (27)", action: "veh_color_slot", slot: 4, value: 27 },
|
||||
{ label: "Dark Red (28)", action: "veh_color_slot", slot: 4, value: 28 },
|
||||
{ label: "Candy Red (30)", action: "veh_color_slot", slot: 4, value: 30 },
|
||||
{ label: "Orange (36)", action: "veh_color_slot", slot: 4, value: 36 },
|
||||
{ label: "Yellow (89)", action: "veh_color_slot", slot: 4, value: 89 },
|
||||
{ label: "Bright Yellow (91)", action: "veh_color_slot", slot: 4, value: 91 },
|
||||
{ label: "Green (50)", action: "veh_color_slot", slot: 4, value: 50 },
|
||||
{ label: "Dark Green (52)", action: "veh_color_slot", slot: 4, value: 52 },
|
||||
{ label: "Lime Green (55)", action: "veh_color_slot", slot: 4, value: 55 },
|
||||
{ label: "Blue (62)", action: "veh_color_slot", slot: 4, value: 62 },
|
||||
{ label: "Dark Blue (64)", action: "veh_color_slot", slot: 4, value: 64 },
|
||||
{ label: "Light Blue (73)", action: "veh_color_slot", slot: 4, value: 73 },
|
||||
{ label: "Bright Blue (82)", action: "veh_color_slot", slot: 4, value: 82 },
|
||||
{ label: "Purple (99)", action: "veh_color_slot", slot: 4, value: 99 },
|
||||
{ label: "Pink (100)", action: "veh_color_slot", slot: 4, value: 100 },
|
||||
{ label: "Hot Pink (101)", action: "veh_color_slot", slot: 4, value: 101 },
|
||||
{ label: "Brown (45)", action: "veh_color_slot", slot: 4, value: 45 },
|
||||
{ label: "Beige (44)", action: "veh_color_slot", slot: 4, value: 44 },
|
||||
{ label: "Gold (37)", action: "veh_color_slot", slot: 4, value: 37 }
|
||||
{ label: "Color 1 (Primary)", action: "color_slot_edit", slot: 0 },
|
||||
{ label: "Color 2 (Secondary)", action: "color_slot_edit", slot: 1 },
|
||||
{ label: "Color 3 (Tertiary)", action: "color_slot_edit", slot: 2 },
|
||||
{ label: "Color 4 (Quaternary)", action: "color_slot_edit", slot: 3 },
|
||||
{ label: "--- Quick Presets ---", action: "none" },
|
||||
{ label: "All Black", action: "color_preset", values: [0, 0, 0, 0] },
|
||||
{ label: "All White", action: "color_preset", values: [18, 18, 18, 18] },
|
||||
{ label: "All Red", action: "color_preset", values: [27, 27, 27, 27] },
|
||||
{ label: "All Blue", action: "color_preset", values: [62, 62, 62, 62] },
|
||||
{ label: "Police Colors", action: "color_preset", values: [133, 18, 133, 18] },
|
||||
{ label: "Taxi Yellow", action: "color_preset", values: [90, 90, 0, 0] }
|
||||
]
|
||||
},
|
||||
|
||||
@@ -1310,6 +1363,12 @@ addEventHandler("OnKeyUp", function(event, key, scanCode, mods) {
|
||||
navigateUp();
|
||||
} else if (key === SDLK_DOWN) {
|
||||
navigateDown();
|
||||
} else if (key === SDLK_LEFT) {
|
||||
// Left arrow - decrease color value in color editor
|
||||
handleColorEditorLeft();
|
||||
} else if (key === SDLK_RIGHT) {
|
||||
// Right arrow - increase color value in color editor
|
||||
handleColorEditorRight();
|
||||
} else if (key === SDLK_RETURN || key === SDLK_KP_ENTER) {
|
||||
selectItem();
|
||||
} else if (key === SDLK_BACKSPACE || key === SDLK_ESCAPE) {
|
||||
@@ -1317,6 +1376,97 @@ addEventHandler("OnKeyUp", function(event, key, scanCode, mods) {
|
||||
}
|
||||
});
|
||||
|
||||
// Handle left arrow in color editor
|
||||
function handleColorEditorLeft() {
|
||||
if (currentMenu !== "vehColorEditor") return;
|
||||
|
||||
let items = getCurrentMenuItems();
|
||||
let item = items[selectedIndex];
|
||||
|
||||
if (item && item.action === "color_slot_edit") {
|
||||
let slot = item.slot;
|
||||
colorEditorValues[slot]--;
|
||||
if (colorEditorValues[slot] < 0) {
|
||||
colorEditorValues[slot] = GTA_IV_COLORS.length - 1;
|
||||
}
|
||||
applyColorToVehicle(slot, colorEditorValues[slot]);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle right arrow in color editor
|
||||
function handleColorEditorRight() {
|
||||
if (currentMenu !== "vehColorEditor") return;
|
||||
|
||||
let items = getCurrentMenuItems();
|
||||
let item = items[selectedIndex];
|
||||
|
||||
if (item && item.action === "color_slot_edit") {
|
||||
let slot = item.slot;
|
||||
colorEditorValues[slot]++;
|
||||
if (colorEditorValues[slot] >= GTA_IV_COLORS.length) {
|
||||
colorEditorValues[slot] = 0;
|
||||
}
|
||||
applyColorToVehicle(slot, colorEditorValues[slot]);
|
||||
}
|
||||
}
|
||||
|
||||
// Apply color to vehicle slot
|
||||
function applyColorToVehicle(slot, colorId) {
|
||||
if (!localPlayer || !localPlayer.vehicle) {
|
||||
showNotification("Not in vehicle!");
|
||||
return;
|
||||
}
|
||||
|
||||
let veh = localPlayer.vehicle;
|
||||
let colorInfo = getColorById(colorId);
|
||||
|
||||
try {
|
||||
switch(slot) {
|
||||
case 0:
|
||||
veh.colour1 = colorId;
|
||||
break;
|
||||
case 1:
|
||||
veh.colour2 = colorId;
|
||||
break;
|
||||
case 2:
|
||||
veh.colour3 = colorId;
|
||||
break;
|
||||
case 3:
|
||||
veh.colour4 = colorId;
|
||||
break;
|
||||
}
|
||||
showNotification("Color " + (slot + 1) + ": " + colorInfo.name + " (" + colorId + ")");
|
||||
} catch(e) {
|
||||
// Fallback for older API
|
||||
try {
|
||||
if (slot === 0 || slot === 1) {
|
||||
let col1 = slot === 0 ? colorId : colorEditorValues[0];
|
||||
let col2 = slot === 1 ? colorId : colorEditorValues[1];
|
||||
natives.changeCarColour(veh, col1, col2);
|
||||
showNotification("Color " + (slot + 1) + ": " + colorInfo.name);
|
||||
}
|
||||
} catch(e2) {
|
||||
console.log("[ColorEditor] Failed: " + e2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Load current vehicle colors into editor
|
||||
function loadVehicleColorsToEditor() {
|
||||
if (!localPlayer || !localPlayer.vehicle) return;
|
||||
|
||||
let veh = localPlayer.vehicle;
|
||||
try {
|
||||
colorEditorValues[0] = veh.colour1 || 0;
|
||||
colorEditorValues[1] = veh.colour2 || 0;
|
||||
colorEditorValues[2] = veh.colour3 || 0;
|
||||
colorEditorValues[3] = veh.colour4 || 0;
|
||||
} catch(e) {
|
||||
// Default to black if can't read
|
||||
colorEditorValues = [0, 0, 0, 0];
|
||||
}
|
||||
}
|
||||
|
||||
function navigateUp() {
|
||||
let items = getCurrentMenuItems();
|
||||
do {
|
||||
@@ -1348,6 +1498,17 @@ function updateScroll(items) {
|
||||
}
|
||||
|
||||
function goBack() {
|
||||
// Deactivate color editor when leaving
|
||||
if (currentMenu === "vehColorEditor") {
|
||||
colorEditorActive = false;
|
||||
}
|
||||
|
||||
// Deactivate handling editor when leaving handling menus
|
||||
if (currentMenu === "handlingEditor" || currentMenu.startsWith("handling_")) {
|
||||
handlingEditorActive = false;
|
||||
selectedHandlingParam = "";
|
||||
}
|
||||
|
||||
if (menuStack.length > 0) {
|
||||
let prev = menuStack.pop();
|
||||
currentMenu = prev.menu;
|
||||
@@ -1445,6 +1606,12 @@ function selectItem() {
|
||||
refreshPlayerList();
|
||||
}
|
||||
|
||||
// Load vehicle colors when entering color editor
|
||||
if (item.target === "vehColorEditor") {
|
||||
loadVehicleColorsToEditor();
|
||||
colorEditorActive = true;
|
||||
}
|
||||
|
||||
// Activate handling editor visualization when entering handling menus
|
||||
if (item.target === "handlingEditor" || item.target.startsWith("handling_")) {
|
||||
handlingEditorActive = true;
|
||||
@@ -1670,6 +1837,37 @@ function selectItem() {
|
||||
}
|
||||
break;
|
||||
|
||||
case "color_slot_edit":
|
||||
// Color editor slot - pressing Enter does nothing, use LEFT/RIGHT
|
||||
showNotification("Use LEFT/RIGHT arrows to change color");
|
||||
break;
|
||||
|
||||
case "color_preset":
|
||||
// Apply preset colors to all 4 slots
|
||||
if (localPlayer && localPlayer.vehicle) {
|
||||
let veh = localPlayer.vehicle;
|
||||
let vals = item.values;
|
||||
try {
|
||||
veh.colour1 = vals[0];
|
||||
veh.colour2 = vals[1];
|
||||
veh.colour3 = vals[2];
|
||||
veh.colour4 = vals[3];
|
||||
colorEditorValues = [vals[0], vals[1], vals[2], vals[3]];
|
||||
showNotification("Preset applied: " + item.label);
|
||||
} catch(e) {
|
||||
try {
|
||||
natives.changeCarColour(veh, vals[0], vals[1]);
|
||||
colorEditorValues = [vals[0], vals[1], 0, 0];
|
||||
showNotification("Preset applied (2 colors)");
|
||||
} catch(e2) {
|
||||
console.log("[ColorEditor] Preset failed: " + e2);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
showNotification("Not in vehicle!");
|
||||
}
|
||||
break;
|
||||
|
||||
case "veh_upgrade_add":
|
||||
// Add upgrade using vehicle.addUpgrade(upgradeId)
|
||||
if (localPlayer && localPlayer.vehicle) {
|
||||
@@ -2999,6 +3197,62 @@ addEventHandler("OnDrawnHUD", function(event) {
|
||||
toColour(UI.textMuted.r, UI.textMuted.g, UI.textMuted.b, animAlpha);
|
||||
drawText(">", arrowX, textY, arrowCol, textSize);
|
||||
}
|
||||
|
||||
// Color Editor Slot - show color preview box and left/right arrows with color ID
|
||||
if (item.action === "color_slot_edit") {
|
||||
let slot = item.slot;
|
||||
let colorId = colorEditorValues[slot];
|
||||
let colorInfo = getColorById(colorId);
|
||||
|
||||
// Color preview box (on the right side)
|
||||
let boxX = baseX + menu.width - 145;
|
||||
let boxY = itemY + 8;
|
||||
let boxW = 28;
|
||||
let boxH = 28;
|
||||
|
||||
// Color box shadow
|
||||
let shadowCol = toColour(0, 0, 0, Math.floor(80 * menuOpenAnim));
|
||||
drawRect(boxX + 2, boxY + 2, boxW, boxH, shadowCol);
|
||||
|
||||
// Color box background (the actual color)
|
||||
let colorCol = toColour(colorInfo.r, colorInfo.g, colorInfo.b, animAlpha);
|
||||
drawRect(boxX, boxY, boxW, boxH, colorCol);
|
||||
|
||||
// Color box border
|
||||
let borderCol = isSelected ?
|
||||
toColour(theme.accent.r, theme.accent.g, theme.accent.b, animAlpha) :
|
||||
toColour(UI.border.r, UI.border.g, UI.border.b, animAlpha);
|
||||
drawRect(boxX, boxY, boxW, 1, borderCol);
|
||||
drawRect(boxX, boxY + boxH - 1, boxW, 1, borderCol);
|
||||
drawRect(boxX, boxY, 1, boxH, borderCol);
|
||||
drawRect(boxX + boxW - 1, boxY, 1, boxH, borderCol);
|
||||
|
||||
// Left arrow "<"
|
||||
let leftArrowX = boxX - 22;
|
||||
let arrowY = boxY + 6;
|
||||
let arrowCol = isSelected ?
|
||||
toColour(theme.accent.r, theme.accent.g, theme.accent.b, animAlpha) :
|
||||
toColour(UI.textMuted.r, UI.textMuted.g, UI.textMuted.b, Math.floor(animAlpha * 0.5));
|
||||
drawText("<", leftArrowX, arrowY, arrowCol, 14);
|
||||
|
||||
// Color ID number between arrows and box
|
||||
let idTextX = boxX + boxW + 8;
|
||||
let idCol = isSelected ?
|
||||
toColour(UI.textPrimary.r, UI.textPrimary.g, UI.textPrimary.b, animAlpha) :
|
||||
toColour(UI.textSecondary.r, UI.textSecondary.g, UI.textSecondary.b, animAlpha);
|
||||
drawText(String(colorId), idTextX, arrowY, idCol, 12);
|
||||
|
||||
// Right arrow ">"
|
||||
let rightArrowX = idTextX + 28;
|
||||
drawText(">", rightArrowX, arrowY, arrowCol, 14);
|
||||
|
||||
// Glow effect when selected
|
||||
if (isSelected) {
|
||||
let glowAlpha = Math.floor(40 * menuOpenAnim * selectionGlow);
|
||||
let glowCol = toColour(colorInfo.r, colorInfo.g, colorInfo.b, glowAlpha);
|
||||
drawRect(boxX - 4, boxY - 4, boxW + 8, boxH + 8, glowCol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ===== FOOTER =====
|
||||
@@ -3016,20 +3270,43 @@ addEventHandler("OnDrawnHUD", function(event) {
|
||||
let hintCol = toColour(UI.textMuted.r, UI.textMuted.g, UI.textMuted.b, animAlpha);
|
||||
let keyCol = toColour(UI.textSecondary.r, UI.textSecondary.g, UI.textSecondary.b, animAlpha);
|
||||
|
||||
drawText("[", baseX + 15, hintY, hintCol, 10);
|
||||
drawText("UP/DOWN", baseX + 22, hintY, keyCol, 10);
|
||||
drawText("]", baseX + 72, hintY, hintCol, 10);
|
||||
drawText("Navigate", baseX + 82, hintY, hintCol, 10);
|
||||
// Show different hints for color editor
|
||||
if (currentMenu === "vehColorEditor") {
|
||||
drawText("[", baseX + 10, hintY, hintCol, 10);
|
||||
drawText("UP/DN", baseX + 17, hintY, keyCol, 10);
|
||||
drawText("]", baseX + 52, hintY, hintCol, 10);
|
||||
drawText("Slot", baseX + 60, hintY, hintCol, 10);
|
||||
|
||||
drawText("[", baseX + 145, hintY, hintCol, 10);
|
||||
drawText("ENTER", baseX + 152, hintY, keyCol, 10);
|
||||
drawText("]", baseX + 190, hintY, hintCol, 10);
|
||||
drawText("Select", baseX + 200, hintY, hintCol, 10);
|
||||
drawText("[", baseX + 95, hintY, hintCol, 10);
|
||||
drawText("L/R", baseX + 102, hintY, keyCol, 10);
|
||||
drawText("]", baseX + 125, hintY, hintCol, 10);
|
||||
drawText("Color", baseX + 133, hintY, hintCol, 10);
|
||||
|
||||
drawText("[", baseX + 255, hintY, hintCol, 10);
|
||||
drawText("BACK", baseX + 262, hintY, keyCol, 10);
|
||||
drawText("]", baseX + 295, hintY, hintCol, 10);
|
||||
drawText("Return", baseX + 305, hintY, hintCol, 10);
|
||||
drawText("[", baseX + 175, hintY, hintCol, 10);
|
||||
drawText("ENTER", baseX + 182, hintY, keyCol, 10);
|
||||
drawText("]", baseX + 220, hintY, hintCol, 10);
|
||||
drawText("Preset", baseX + 228, hintY, hintCol, 10);
|
||||
|
||||
drawText("[", baseX + 280, hintY, hintCol, 10);
|
||||
drawText("BACK", baseX + 287, hintY, keyCol, 10);
|
||||
drawText("]", baseX + 320, hintY, hintCol, 10);
|
||||
drawText("Exit", baseX + 328, hintY, hintCol, 10);
|
||||
} else {
|
||||
drawText("[", baseX + 15, hintY, hintCol, 10);
|
||||
drawText("UP/DOWN", baseX + 22, hintY, keyCol, 10);
|
||||
drawText("]", baseX + 72, hintY, hintCol, 10);
|
||||
drawText("Navigate", baseX + 82, hintY, hintCol, 10);
|
||||
|
||||
drawText("[", baseX + 145, hintY, hintCol, 10);
|
||||
drawText("ENTER", baseX + 152, hintY, keyCol, 10);
|
||||
drawText("]", baseX + 190, hintY, hintCol, 10);
|
||||
drawText("Select", baseX + 200, hintY, hintCol, 10);
|
||||
|
||||
drawText("[", baseX + 255, hintY, hintCol, 10);
|
||||
drawText("BACK", baseX + 262, hintY, keyCol, 10);
|
||||
drawText("]", baseX + 295, hintY, hintCol, 10);
|
||||
drawText("Return", baseX + 305, hintY, hintCol, 10);
|
||||
}
|
||||
|
||||
// ===== GLOWING SCROLLBAR =====
|
||||
if (items.length > menu.maxVisibleItems) {
|
||||
|
||||
Reference in New Issue
Block a user