Add interactive mod menu with GUI for all players

Features:
- Press F5 to open/close the mod menu
- Self options: health, armor, weapons, god mode, skins
- Vehicle spawner: 50+ vehicles organized by category
- Vehicle options: repair, flip, colors, drift mode, handling
- Network options: player list, teleport to other players
- Teleport locations: 15+ Liberty City locations
- World options: time and weather control
- Weapons menu: individual and all weapons
- Fun options: launch, ragdoll, ped spawning

Menu navigation via arrow keys, Enter to select, Backspace to go back
This commit is contained in:
Claude
2026-01-10 23:21:39 +00:00
parent c24c883252
commit dad2741754
5 changed files with 1579 additions and 2 deletions

View File

@@ -11,6 +11,7 @@ A comprehensive GTA IV freeroam server for GTAConnected with multiple features i
- **World Control** - Weather and time manipulation
- **Enhanced Chat** - Private messages, local chat, actions, and OOC chat
- **Kill Tracking** - Statistics for kills, deaths, and K/D ratio
- **Interactive Mod Menu** - Press F5 to access a full GUI menu with all features
## Installation
@@ -41,9 +42,13 @@ GTAConnected/
├── chat/ # Enhanced chat system
│ ├── meta.xml
│ └── server.js
── teleport/ # Teleportation system
── teleport/ # Teleportation system
│ ├── meta.xml
│ └── server.js
└── modmenu/ # Interactive GUI mod menu
├── meta.xml
── server.js
── server.js
└── client.js
```
## Commands
@@ -221,6 +226,71 @@ const admins = [
];
```
## Mod Menu (F5)
The server includes an interactive GUI mod menu accessible to all players by pressing **F5**.
### Menu Controls
| Key | Action |
|-----|--------|
| F5 | Open/Close Menu |
| UP/DOWN | Navigate items |
| ENTER | Select item |
| BACKSPACE/ESC | Go back |
| LEFT/RIGHT | Adjust values |
### Menu Categories
**Self Options**
- Restore health/armor
- Get all weapons
- Clear wanted level
- God Mode toggle
- Infinite ammo
- Super jump / Fast run
- Change player skin
**Vehicle Spawner**
- Sports Cars (Infernus, Turismo, Comet, etc.)
- Super Cars (Entity XF, Adder, Vacca, etc.)
- Muscle Cars (Sabre GT, Dukes, Ruiner, etc.)
- SUVs & Trucks
- Motorcycles
- Emergency Vehicles
- Aircraft & Boats
**Vehicle Options**
- Repair / Flip / Clean vehicle
- Change vehicle colors
- Drift Mode toggle
- Handling adjustments (Grip, Acceleration, Top Speed)
- Indestructible vehicle
- Nitro boost
**Network Options**
- View online players
- Teleport to any player
- Spectate players
**Teleport Locations**
- Quick teleport to 15+ Liberty City locations
- All boroughs covered (Algonquin, Broker, Bohan, Alderney)
**World Options**
- Set time of day
- Change weather
**Weapons**
- Get individual weapons
- Get all weapons at once
**Fun Options**
- Launch yourself into the air
- Spawn random peds
- Ragdoll mode
- Chaos mode
## Requirements
- GTAConnected Server (v1.0.72 or newer)

929
resources/modmenu/client.js Normal file
View File

@@ -0,0 +1,929 @@
// ============================================================================
// MOD MENU - Client Side
// Interactive GUI menu for all players
// Press F5 to open/close menu, Arrow keys to navigate, Enter to select
// ============================================================================
// Menu state
let menuOpen = false;
let currentMenu = "main";
let selectedIndex = 0;
let menuStack = []; // For back navigation
// Menu colors
const colors = {
background: toColour(20, 20, 20, 200),
header: toColour(200, 50, 50, 255),
headerText: toColour(255, 255, 255, 255),
itemBg: toColour(40, 40, 40, 200),
itemBgSelected: toColour(200, 50, 50, 220),
itemText: toColour(255, 255, 255, 255),
itemTextSelected: toColour(255, 255, 255, 255),
footer: toColour(30, 30, 30, 200),
footerText: toColour(180, 180, 180, 255),
subText: toColour(150, 150, 150, 255)
};
// Menu dimensions
const menu = {
x: 50,
y: 100,
width: 300,
headerHeight: 40,
itemHeight: 35,
footerHeight: 30,
maxVisibleItems: 12
};
// Scroll offset for long menus
let scrollOffset = 0;
// Player list cache
let playerList = [];
let lastPlayerUpdate = 0;
// Vehicle handling values
let handlingMods = {
grip: 1.0,
acceleration: 1.0,
topSpeed: 1.0,
braking: 1.0,
driftMode: false
};
// ============================================================================
// MENU DATA STRUCTURE
// ============================================================================
const menuData = {
main: {
title: "MOD MENU",
items: [
{ label: "Self Options", action: "submenu", target: "self" },
{ label: "Vehicle Spawner", action: "submenu", target: "vehicles" },
{ label: "Vehicle Options", action: "submenu", target: "vehicleOptions" },
{ label: "Network Options", action: "submenu", target: "network" },
{ label: "Teleport Locations", action: "submenu", target: "teleport" },
{ label: "World Options", action: "submenu", target: "world" },
{ label: "Weapons", action: "submenu", target: "weapons" },
{ label: "Fun Options", action: "submenu", target: "fun" }
]
},
self: {
title: "SELF OPTIONS",
items: [
{ label: "Restore Health", action: "self_health" },
{ label: "Restore Armor", action: "self_armor" },
{ label: "Max Health & Armor", action: "self_max" },
{ label: "Give All Weapons", action: "self_weapons" },
{ label: "Clear Wanted Level", action: "self_wanted" },
{ label: "Never Wanted", action: "toggle", target: "neverWanted", state: false },
{ label: "God Mode", action: "toggle", target: "godMode", state: false },
{ label: "Infinite Ammo", action: "toggle", target: "infiniteAmmo", state: false },
{ label: "Super Jump", action: "toggle", target: "superJump", state: false },
{ label: "Fast Run", action: "toggle", target: "fastRun", state: false },
{ label: "Respawn", action: "self_respawn" },
{ label: "Suicide", action: "self_suicide" },
{ label: "Change Skin", action: "submenu", target: "skins" }
]
},
skins: {
title: "PLAYER SKINS",
items: [
{ label: "Niko Bellic", action: "skin", value: -1667301416 },
{ label: "Roman Bellic", action: "skin", value: -163448165 },
{ label: "Little Jacob", action: "skin", value: 1936355839 },
{ label: "Brucie Kibbutz", action: "skin", value: -1938475496 },
{ label: "Playboy X", action: "skin", value: 970234525 },
{ label: "Johnny Klebitz", action: "skin", value: -1784875845 },
{ label: "Luis Lopez", action: "skin", value: -1403507487 },
{ label: "Police Officer", action: "skin", value: -1320879687 },
{ label: "NOOSE", action: "skin", value: -1306011498 },
{ label: "Paramedic", action: "skin", value: 2136829318 },
{ label: "Firefighter", action: "skin", value: 1616659040 },
{ label: "Business Man", action: "skin", value: -268651930 },
{ label: "Hobo", action: "skin", value: 1943617350 },
{ label: "Random Skin", action: "skin_random" }
]
},
vehicles: {
title: "VEHICLE SPAWNER",
items: [
{ label: "Sports Cars", action: "submenu", target: "veh_sports" },
{ label: "Super Cars", action: "submenu", target: "veh_super" },
{ label: "Muscle Cars", action: "submenu", target: "veh_muscle" },
{ label: "SUVs & Trucks", action: "submenu", target: "veh_suv" },
{ label: "Sedans & Compacts", action: "submenu", target: "veh_sedan" },
{ label: "Motorcycles", action: "submenu", target: "veh_bikes" },
{ label: "Emergency Vehicles", action: "submenu", target: "veh_emergency" },
{ label: "Aircraft", action: "submenu", target: "veh_aircraft" },
{ label: "Boats", action: "submenu", target: "veh_boats" },
{ label: "Special Vehicles", action: "submenu", target: "veh_special" },
{ label: "Delete My Vehicles", action: "vehicle_delete" }
]
},
veh_sports: {
title: "SPORTS CARS",
items: [
{ label: "Infernus", action: "spawn_vehicle", value: "infernus" },
{ label: "Turismo", action: "spawn_vehicle", value: "turismo" },
{ label: "Comet", action: "spawn_vehicle", value: "comet" },
{ label: "Banshee", action: "spawn_vehicle", value: "banshee" },
{ label: "Sultan", action: "spawn_vehicle", value: "sultan" },
{ label: "Coquette", action: "spawn_vehicle", value: "coquette" },
{ label: "Feltzer", action: "spawn_vehicle", value: "feltzer" },
{ label: "F620", action: "spawn_vehicle", value: "f620" },
{ label: "Buffalo", action: "spawn_vehicle", value: "buffalo" }
]
},
veh_super: {
title: "SUPER CARS",
items: [
{ label: "Entity XF", action: "spawn_vehicle", value: "entityxf" },
{ label: "Adder", action: "spawn_vehicle", value: "adder" },
{ label: "Vacca", action: "spawn_vehicle", value: "vacca" },
{ label: "Bullet", action: "spawn_vehicle", value: "bullet" },
{ label: "Cheetah", action: "spawn_vehicle", value: "cheetah" }
]
},
veh_muscle: {
title: "MUSCLE CARS",
items: [
{ label: "Sabre GT", action: "spawn_vehicle", value: "sabregt" },
{ label: "Stallion", action: "spawn_vehicle", value: "stalion" },
{ label: "Vigero", action: "spawn_vehicle", value: "vigero" },
{ label: "Dukes", action: "spawn_vehicle", value: "dukes" },
{ label: "Ruiner", action: "spawn_vehicle", value: "ruiner" },
{ label: "Phoenix", action: "spawn_vehicle", value: "phoenix" },
{ label: "Gauntlet", action: "spawn_vehicle", value: "gauntlet" },
{ label: "Dominator", action: "spawn_vehicle", value: "dominator" }
]
},
veh_suv: {
title: "SUVs & TRUCKS",
items: [
{ label: "Patriot", action: "spawn_vehicle", value: "patriot" },
{ label: "Cavalcade", action: "spawn_vehicle", value: "cavalcade" },
{ label: "Granger", action: "spawn_vehicle", value: "granger" },
{ label: "Huntley", action: "spawn_vehicle", value: "huntley" },
{ label: "Landstalker", action: "spawn_vehicle", value: "landstalker" },
{ label: "Habanero", action: "spawn_vehicle", value: "habanero" },
{ label: "Serrano", action: "spawn_vehicle", value: "serrano" },
{ label: "Rebla", action: "spawn_vehicle", value: "rebla" }
]
},
veh_sedan: {
title: "SEDANS & COMPACTS",
items: [
{ label: "Oracle", action: "spawn_vehicle", value: "oracle" },
{ label: "Schafter", action: "spawn_vehicle", value: "schafter" },
{ label: "Admiral", action: "spawn_vehicle", value: "admiral" },
{ label: "Vincent", action: "spawn_vehicle", value: "vincent" },
{ label: "Presidente", action: "spawn_vehicle", value: "presidente" },
{ label: "Cognoscenti", action: "spawn_vehicle", value: "cognoscenti" },
{ label: "Blista", action: "spawn_vehicle", value: "blista" },
{ label: "Premier", action: "spawn_vehicle", value: "premier" }
]
},
veh_bikes: {
title: "MOTORCYCLES",
items: [
{ label: "NRG 900", action: "spawn_vehicle", value: "nrg900" },
{ label: "PCJ 600", action: "spawn_vehicle", value: "pcj600" },
{ label: "Sanchez", action: "spawn_vehicle", value: "sanchez" },
{ label: "Faggio", action: "spawn_vehicle", value: "faggio" },
{ label: "Bati", action: "spawn_vehicle", value: "bati" },
{ label: "Akuma", action: "spawn_vehicle", value: "akuma" },
{ label: "Double T", action: "spawn_vehicle", value: "double" },
{ label: "Hakuchou", action: "spawn_vehicle", value: "hakuchou" },
{ label: "Hexer", action: "spawn_vehicle", value: "hexer" },
{ label: "Daemon", action: "spawn_vehicle", value: "daemon" }
]
},
veh_emergency: {
title: "EMERGENCY VEHICLES",
items: [
{ label: "Police Cruiser", action: "spawn_vehicle", value: "police" },
{ label: "Police Buffalo", action: "spawn_vehicle", value: "police2" },
{ label: "FBI Car", action: "spawn_vehicle", value: "fbi" },
{ label: "NOOSE Cruiser", action: "spawn_vehicle", value: "noose" },
{ label: "Ambulance", action: "spawn_vehicle", value: "ambulance" },
{ label: "Fire Truck", action: "spawn_vehicle", value: "firetruk" },
{ label: "Enforcer (SWAT)", action: "spawn_vehicle", value: "enforcer" }
]
},
veh_aircraft: {
title: "AIRCRAFT",
items: [
{ label: "Annihilator", action: "spawn_vehicle", value: "annihilator" },
{ label: "Maverick", action: "spawn_vehicle", value: "maverick" },
{ label: "Police Maverick", action: "spawn_vehicle", value: "polmav" },
{ label: "Buzzard", action: "spawn_vehicle", value: "buzzard" },
{ label: "Shamal (Jet)", action: "spawn_vehicle", value: "shamal" }
]
},
veh_boats: {
title: "BOATS",
items: [
{ label: "Jetmax", action: "spawn_vehicle", value: "jetmax" },
{ label: "Marquis", action: "spawn_vehicle", value: "marquis" },
{ label: "Predator", action: "spawn_vehicle", value: "predator" },
{ label: "Tropic", action: "spawn_vehicle", value: "tropic" },
{ label: "Dinghy", action: "spawn_vehicle", value: "dinghy" },
{ label: "Squalo", action: "spawn_vehicle", value: "squalo" },
{ label: "Reefer", action: "spawn_vehicle", value: "reefer" }
]
},
veh_special: {
title: "SPECIAL VEHICLES",
items: [
{ label: "Taxi", action: "spawn_vehicle", value: "taxi" },
{ label: "Stretch Limo", action: "spawn_vehicle", value: "stretch" },
{ label: "Bus", action: "spawn_vehicle", value: "bus" },
{ label: "Trashmaster", action: "spawn_vehicle", value: "trashmaster" },
{ label: "Forklift", action: "spawn_vehicle", value: "forklift" },
{ label: "Caddy", action: "spawn_vehicle", value: "caddy" },
{ label: "Bulldozer", action: "spawn_vehicle", value: "bulldozer" },
{ label: "Phantom", action: "spawn_vehicle", value: "phantom" }
]
},
vehicleOptions: {
title: "VEHICLE OPTIONS",
items: [
{ label: "Repair Vehicle", action: "veh_repair" },
{ label: "Flip Vehicle", action: "veh_flip" },
{ label: "Clean Vehicle", action: "veh_clean" },
{ label: "Max Upgrade", action: "veh_upgrade" },
{ label: "Vehicle Colors", action: "submenu", target: "veh_colors" },
{ label: "--- Handling ---", action: "none" },
{ label: "Drift Mode", action: "toggle", target: "driftMode", state: false },
{ label: "Grip +", action: "handling", target: "grip", delta: 0.2 },
{ label: "Grip -", action: "handling", target: "grip", delta: -0.2 },
{ label: "Acceleration +", action: "handling", target: "acceleration", delta: 0.5 },
{ label: "Acceleration -", action: "handling", target: "acceleration", delta: -0.5 },
{ label: "Top Speed +", action: "handling", target: "topSpeed", delta: 0.3 },
{ label: "Top Speed -", action: "handling", target: "topSpeed", delta: -0.3 },
{ label: "Reset Handling", action: "handling_reset" },
{ label: "--- Special ---", action: "none" },
{ label: "Indestructible", action: "toggle", target: "vehGodMode", state: false },
{ label: "Nitro Boost", action: "veh_nitro" },
{ label: "Super Brakes", action: "toggle", target: "superBrakes", state: false }
]
},
veh_colors: {
title: "VEHICLE COLORS",
items: [
{ label: "Black", action: "veh_color", value: [0, 0] },
{ label: "White", action: "veh_color", value: [1, 1] },
{ label: "Red", action: "veh_color", value: [27, 27] },
{ label: "Blue", action: "veh_color", value: [51, 51] },
{ label: "Yellow", action: "veh_color", value: [42, 42] },
{ label: "Green", action: "veh_color", value: [53, 53] },
{ label: "Orange", action: "veh_color", value: [38, 38] },
{ label: "Purple", action: "veh_color", value: [61, 61] },
{ label: "Pink", action: "veh_color", value: [68, 68] },
{ label: "Gold", action: "veh_color", value: [37, 37] },
{ label: "Chrome", action: "veh_color", value: [120, 120] },
{ label: "Random", action: "veh_color_random" }
]
},
network: {
title: "NETWORK OPTIONS",
items: [
{ label: ">> Refresh Player List <<", action: "refresh_players" },
{ label: "--- Players Online ---", action: "none" }
// Players will be added dynamically
]
},
teleport: {
title: "TELEPORT LOCATIONS",
items: [
{ label: "-- Algonquin --", action: "none" },
{ label: "Star Junction", action: "teleport", value: { x: -252.0, y: 947.0, z: 15.0 } },
{ label: "Middle Park", action: "teleport", value: { x: -365.0, y: 1163.0, z: 14.0 } },
{ label: "Rotterdam Tower", action: "teleport", value: { x: 237.0, y: 1002.0, z: 18.0 } },
{ label: "Chinatown", action: "teleport", value: { x: -141.0, y: 289.0, z: 14.0 } },
{ label: "Happiness Island", action: "teleport", value: { x: -722.0, y: -17.0, z: 3.0 } },
{ label: "-- Broker --", action: "none" },
{ label: "Broker Bridge", action: "teleport", value: { x: 932.0, y: -495.0, z: 15.0 } },
{ label: "Hove Beach", action: "teleport", value: { x: 1017.0, y: -505.0, z: 19.0 } },
{ label: "Airport", action: "teleport", value: { x: 2140.0, y: 465.0, z: 6.0 } },
{ label: "-- Bohan --", action: "none" },
{ label: "South Bohan", action: "teleport", value: { x: 1243.0, y: -196.0, z: 26.0 } },
{ label: "-- Alderney --", action: "none" },
{ label: "Alderney City", action: "teleport", value: { x: -1149.0, y: 380.0, z: 21.0 } },
{ label: "Westdyke", action: "teleport", value: { x: -1745.0, y: 1157.0, z: 25.0 } },
{ label: "-- Special --", action: "none" },
{ label: "Helipad (High)", action: "teleport", value: { x: -290.0, y: -400.0, z: 81.0 } },
{ label: "Tower Top", action: "teleport", value: { x: 237.0, y: 1002.0, z: 200.0 } },
{ label: "Waypoint (Marker)", action: "teleport_waypoint" }
]
},
world: {
title: "WORLD OPTIONS",
items: [
{ label: "-- Time --", action: "none" },
{ label: "Morning (8:00)", action: "world_time", value: 8 },
{ label: "Noon (12:00)", action: "world_time", value: 12 },
{ label: "Evening (18:00)", action: "world_time", value: 18 },
{ label: "Night (0:00)", action: "world_time", value: 0 },
{ label: "-- Weather --", action: "none" },
{ label: "Extra Sunny", action: "world_weather", value: 0 },
{ label: "Sunny", action: "world_weather", value: 1 },
{ label: "Cloudy", action: "world_weather", value: 3 },
{ label: "Rainy", action: "world_weather", value: 4 },
{ label: "Thunder", action: "world_weather", value: 7 },
{ label: "Foggy", action: "world_weather", value: 6 }
]
},
weapons: {
title: "WEAPONS",
items: [
{ label: "Get All Weapons", action: "weapon_all" },
{ label: "-- Melee --", action: "none" },
{ label: "Baseball Bat", action: "weapon", value: 1 },
{ label: "Knife", action: "weapon", value: 2 },
{ label: "-- Pistols --", action: "none" },
{ label: "Pistol", action: "weapon", value: 5 },
{ label: "Desert Eagle", action: "weapon", value: 6 },
{ label: "-- Shotguns --", action: "none" },
{ label: "Shotgun", action: "weapon", value: 9 },
{ label: "Combat Shotgun", action: "weapon", value: 10 },
{ label: "-- SMGs --", action: "none" },
{ label: "Micro SMG", action: "weapon", value: 11 },
{ label: "SMG", action: "weapon", value: 12 },
{ label: "-- Rifles --", action: "none" },
{ label: "Assault Rifle", action: "weapon", value: 14 },
{ label: "Carbine Rifle", action: "weapon", value: 15 },
{ label: "Sniper Rifle", action: "weapon", value: 16 },
{ label: "-- Explosives --", action: "none" },
{ label: "RPG", action: "weapon", value: 18 },
{ label: "Grenades", action: "weapon", value: 19 },
{ label: "Molotov", action: "weapon", value: 20 }
]
},
fun: {
title: "FUN OPTIONS",
items: [
{ label: "Launch Me Up", action: "fun_launch" },
{ label: "Explode Me", action: "fun_explode" },
{ label: "Spawn Random Ped", action: "fun_ped" },
{ label: "Ragdoll", action: "fun_ragdoll" },
{ label: "Clear Area Peds", action: "fun_clearpeds" },
{ label: "Clear Area Vehicles", action: "fun_clearvehicles" },
{ label: "Chaos Mode", action: "toggle", target: "chaosMode", state: false },
{ label: "Drunk Mode", action: "toggle", target: "drunkMode", state: false }
]
}
};
// Toggle states
let toggleStates = {
godMode: false,
neverWanted: false,
infiniteAmmo: false,
superJump: false,
fastRun: false,
driftMode: false,
vehGodMode: false,
superBrakes: false,
chaosMode: false,
drunkMode: false
};
// ============================================================================
// INPUT HANDLING
// ============================================================================
addEventHandler("OnKeyUp", function(event, key, scanCode, mods) {
// F5 to toggle menu
if (key === SDLK_F5) {
menuOpen = !menuOpen;
if (menuOpen) {
currentMenu = "main";
selectedIndex = 0;
scrollOffset = 0;
menuStack = [];
gta.setCursorEnabled(true);
} else {
gta.setCursorEnabled(false);
}
return;
}
if (!menuOpen) return;
// Navigation
if (key === SDLK_UP) {
navigateUp();
} else if (key === SDLK_DOWN) {
navigateDown();
} else if (key === SDLK_RETURN || key === SDLK_KP_ENTER) {
selectItem();
} else if (key === SDLK_BACKSPACE || key === SDLK_ESCAPE) {
goBack();
} else if (key === SDLK_LEFT) {
// For sliders/adjustable options
adjustValue(-1);
} else if (key === SDLK_RIGHT) {
adjustValue(1);
}
});
function navigateUp() {
let items = getCurrentMenuItems();
do {
selectedIndex--;
if (selectedIndex < 0) {
selectedIndex = items.length - 1;
}
} while (items[selectedIndex] && items[selectedIndex].action === "none");
updateScroll(items);
}
function navigateDown() {
let items = getCurrentMenuItems();
do {
selectedIndex++;
if (selectedIndex >= items.length) {
selectedIndex = 0;
}
} while (items[selectedIndex] && items[selectedIndex].action === "none");
updateScroll(items);
}
function updateScroll(items) {
if (selectedIndex < scrollOffset) {
scrollOffset = selectedIndex;
} else if (selectedIndex >= scrollOffset + menu.maxVisibleItems) {
scrollOffset = selectedIndex - menu.maxVisibleItems + 1;
}
}
function goBack() {
if (menuStack.length > 0) {
let prev = menuStack.pop();
currentMenu = prev.menu;
selectedIndex = prev.index;
scrollOffset = prev.scroll;
} else {
menuOpen = false;
gta.setCursorEnabled(false);
}
}
function getCurrentMenuItems() {
if (currentMenu === "network") {
return getNetworkMenuItems();
}
return menuData[currentMenu] ? menuData[currentMenu].items : [];
}
function getNetworkMenuItems() {
let items = [
{ label: ">> Refresh Player List <<", action: "refresh_players" },
{ label: "--- Players Online ---", action: "none" }
];
for (let i = 0; i < playerList.length; i++) {
items.push({
label: playerList[i].name,
action: "submenu",
target: "player_options",
playerData: playerList[i]
});
}
return items;
}
// ============================================================================
// ACTION HANDLING
// ============================================================================
function selectItem() {
let items = getCurrentMenuItems();
let item = items[selectedIndex];
if (!item || item.action === "none") return;
switch (item.action) {
case "submenu":
if (item.target === "player_options" && item.playerData) {
// Store selected player for network options
selectedPlayer = item.playerData;
openPlayerMenu(item.playerData);
} else {
menuStack.push({ menu: currentMenu, index: selectedIndex, scroll: scrollOffset });
currentMenu = item.target;
selectedIndex = 0;
scrollOffset = 0;
}
break;
case "toggle":
toggleStates[item.target] = !toggleStates[item.target];
item.state = toggleStates[item.target];
triggerNetworkEvent("ModMenu:Toggle", item.target, toggleStates[item.target]);
showNotification(item.label + ": " + (toggleStates[item.target] ? "ON" : "OFF"));
break;
case "spawn_vehicle":
triggerNetworkEvent("ModMenu:SpawnVehicle", item.value);
showNotification("Spawning: " + item.label);
break;
case "teleport":
triggerNetworkEvent("ModMenu:Teleport", item.value.x, item.value.y, item.value.z);
showNotification("Teleporting to: " + item.label);
break;
case "teleport_waypoint":
triggerNetworkEvent("ModMenu:TeleportWaypoint");
showNotification("Teleporting to waypoint...");
break;
case "self_health":
triggerNetworkEvent("ModMenu:SelfOption", "health");
showNotification("Health restored!");
break;
case "self_armor":
triggerNetworkEvent("ModMenu:SelfOption", "armor");
showNotification("Armor restored!");
break;
case "self_max":
triggerNetworkEvent("ModMenu:SelfOption", "max");
showNotification("Max health & armor!");
break;
case "self_weapons":
triggerNetworkEvent("ModMenu:SelfOption", "weapons");
showNotification("All weapons given!");
break;
case "self_wanted":
triggerNetworkEvent("ModMenu:SelfOption", "wanted");
showNotification("Wanted level cleared!");
break;
case "self_respawn":
triggerNetworkEvent("ModMenu:SelfOption", "respawn");
showNotification("Respawning...");
break;
case "self_suicide":
triggerNetworkEvent("ModMenu:SelfOption", "suicide");
break;
case "skin":
triggerNetworkEvent("ModMenu:ChangeSkin", item.value);
showNotification("Skin changed!");
break;
case "skin_random":
triggerNetworkEvent("ModMenu:ChangeSkin", "random");
showNotification("Random skin applied!");
break;
case "veh_repair":
triggerNetworkEvent("ModMenu:VehicleOption", "repair");
showNotification("Vehicle repaired!");
break;
case "veh_flip":
triggerNetworkEvent("ModMenu:VehicleOption", "flip");
showNotification("Vehicle flipped!");
break;
case "veh_clean":
triggerNetworkEvent("ModMenu:VehicleOption", "clean");
showNotification("Vehicle cleaned!");
break;
case "veh_upgrade":
triggerNetworkEvent("ModMenu:VehicleOption", "upgrade");
showNotification("Vehicle upgraded!");
break;
case "veh_nitro":
triggerNetworkEvent("ModMenu:VehicleOption", "nitro");
showNotification("NITRO BOOST!");
break;
case "veh_color":
triggerNetworkEvent("ModMenu:VehicleColor", item.value[0], item.value[1]);
showNotification("Color changed!");
break;
case "veh_color_random":
let c1 = Math.floor(Math.random() * 132);
let c2 = Math.floor(Math.random() * 132);
triggerNetworkEvent("ModMenu:VehicleColor", c1, c2);
showNotification("Random color applied!");
break;
case "vehicle_delete":
triggerNetworkEvent("ModMenu:DeleteVehicles");
showNotification("Vehicles deleted!");
break;
case "handling":
handlingMods[item.target] = Math.max(0.1, Math.min(5.0, handlingMods[item.target] + item.delta));
triggerNetworkEvent("ModMenu:Handling", item.target, handlingMods[item.target]);
showNotification(item.target + ": " + handlingMods[item.target].toFixed(1));
break;
case "handling_reset":
handlingMods = { grip: 1.0, acceleration: 1.0, topSpeed: 1.0, braking: 1.0, driftMode: false };
triggerNetworkEvent("ModMenu:HandlingReset");
showNotification("Handling reset!");
break;
case "world_time":
triggerNetworkEvent("ModMenu:WorldTime", item.value);
showNotification("Time set to: " + item.value + ":00");
break;
case "world_weather":
triggerNetworkEvent("ModMenu:WorldWeather", item.value);
showNotification("Weather changed!");
break;
case "weapon":
triggerNetworkEvent("ModMenu:GiveWeapon", item.value);
showNotification("Weapon given: " + item.label);
break;
case "weapon_all":
triggerNetworkEvent("ModMenu:SelfOption", "weapons");
showNotification("All weapons given!");
break;
case "refresh_players":
triggerNetworkEvent("ModMenu:GetPlayers");
showNotification("Refreshing player list...");
break;
case "teleport_to_player":
if (selectedPlayer) {
triggerNetworkEvent("ModMenu:TeleportToPlayer", selectedPlayer.id);
showNotification("Teleporting to: " + selectedPlayer.name);
}
break;
case "fun_launch":
triggerNetworkEvent("ModMenu:Fun", "launch");
showNotification("LAUNCH!");
break;
case "fun_explode":
triggerNetworkEvent("ModMenu:Fun", "explode");
break;
case "fun_ped":
triggerNetworkEvent("ModMenu:Fun", "ped");
showNotification("Ped spawned!");
break;
case "fun_ragdoll":
triggerNetworkEvent("ModMenu:Fun", "ragdoll");
break;
case "fun_clearpeds":
triggerNetworkEvent("ModMenu:Fun", "clearpeds");
showNotification("Area cleared!");
break;
case "fun_clearvehicles":
triggerNetworkEvent("ModMenu:Fun", "clearvehicles");
showNotification("Vehicles cleared!");
break;
}
}
function adjustValue(direction) {
// For handling options when using left/right keys
let items = getCurrentMenuItems();
let item = items[selectedIndex];
if (!item) return;
if (item.action === "handling") {
let delta = item.delta * direction;
handlingMods[item.target] = Math.max(0.1, Math.min(5.0, handlingMods[item.target] + delta));
triggerNetworkEvent("ModMenu:Handling", item.target, handlingMods[item.target]);
showNotification(item.target + ": " + handlingMods[item.target].toFixed(1));
}
}
// Selected player for network options
let selectedPlayer = null;
function openPlayerMenu(playerData) {
// Create dynamic player options menu
menuData.player_options = {
title: playerData.name,
items: [
{ label: "Teleport to Player", action: "teleport_to_player" },
{ label: "Spectate Player", action: "spectate_player" },
{ label: "Copy Position", action: "copy_pos" }
]
};
menuStack.push({ menu: currentMenu, index: selectedIndex, scroll: scrollOffset });
currentMenu = "player_options";
selectedIndex = 0;
scrollOffset = 0;
}
// ============================================================================
// NETWORK EVENT HANDLERS
// ============================================================================
addNetworkHandler("ModMenu:PlayerList", function(players) {
playerList = players;
showNotification("Found " + players.length + " players");
});
addNetworkHandler("ModMenu:Notification", function(message) {
showNotification(message);
});
// ============================================================================
// RENDERING
// ============================================================================
addEventHandler("OnDrawnHUD", function(event) {
if (!menuOpen) return;
let currentData = menuData[currentMenu];
let items = getCurrentMenuItems();
let title = currentData ? currentData.title : currentMenu.toUpperCase();
// Calculate visible items
let visibleCount = Math.min(items.length, menu.maxVisibleItems);
let totalHeight = menu.headerHeight + (visibleCount * menu.itemHeight) + menu.footerHeight;
// Draw background
drawing.drawRectangle(null, menu.x - 5, menu.y - 5, menu.width + 10, totalHeight + 10, colors.background, colors.background, 0, 0, 0, false);
// Draw header
drawing.drawRectangle(null, menu.x, menu.y, menu.width, menu.headerHeight, colors.header, colors.header, 0, 0, 0, false);
drawing.drawText(title, menu.x + menu.width / 2, menu.y + 8, menu.width, menu.headerHeight, colors.headerText, 1.0, 1, true, false, false, true);
// Draw items
let yPos = menu.y + menu.headerHeight;
for (let i = scrollOffset; i < scrollOffset + visibleCount && i < items.length; i++) {
let item = items[i];
let isSelected = (i === selectedIndex);
let bgColor = isSelected ? colors.itemBgSelected : colors.itemBg;
let textColor = isSelected ? colors.itemTextSelected : colors.itemText;
// Draw item background
drawing.drawRectangle(null, menu.x, yPos, menu.width, menu.itemHeight, bgColor, bgColor, 0, 0, 0, false);
// Draw item text
let label = item.label;
// Add toggle state indicator
if (item.action === "toggle") {
let state = toggleStates[item.target];
label += state ? " [ON]" : " [OFF]";
}
// Add handling value indicator
if (item.action === "handling" && handlingMods[item.target] !== undefined) {
label += " [" + handlingMods[item.target].toFixed(1) + "]";
}
// Add submenu indicator
if (item.action === "submenu") {
label += " >>";
}
drawing.drawText(label, menu.x + 15, yPos + 8, menu.width - 30, menu.itemHeight, textColor, 0.9, 1, true, false, false, false);
yPos += menu.itemHeight;
}
// Draw footer
drawing.drawRectangle(null, menu.x, yPos, menu.width, menu.footerHeight, colors.footer, colors.footer, 0, 0, 0, false);
// Footer text with controls
let footerText = "UP/DOWN: Navigate | ENTER: Select | BACKSPACE: Back";
drawing.drawText(footerText, menu.x + menu.width / 2, yPos + 7, menu.width, menu.footerHeight, colors.footerText, 0.6, 1, true, false, false, true);
// Draw scroll indicator if needed
if (items.length > menu.maxVisibleItems) {
let scrollText = (scrollOffset + 1) + "-" + Math.min(scrollOffset + visibleCount, items.length) + " / " + items.length;
drawing.drawText(scrollText, menu.x + menu.width - 70, menu.y + 12, 60, 20, colors.subText, 0.7, 1, true, false, false, false);
}
});
// ============================================================================
// NOTIFICATIONS
// ============================================================================
let notifications = [];
function showNotification(text) {
notifications.push({
text: text,
time: Date.now(),
duration: 3000
});
// Clean old notifications
let now = Date.now();
notifications = notifications.filter(n => now - n.time < n.duration);
}
addEventHandler("OnDrawnHUD", function(event) {
let now = Date.now();
let yPos = 200;
for (let i = 0; i < notifications.length; i++) {
let notif = notifications[i];
let elapsed = now - notif.time;
if (elapsed < notif.duration) {
let alpha = elapsed < notif.duration - 500 ? 200 : Math.floor(200 * (notif.duration - elapsed) / 500);
let bgColor = toColour(20, 20, 20, alpha);
let textColor = toColour(255, 255, 100, alpha + 55);
drawing.drawRectangle(null, 10, yPos, 300, 30, bgColor, bgColor, 0, 0, 0, false);
drawing.drawText(notif.text, 20, yPos + 6, 280, 25, textColor, 0.8, 1, true, false, false, false);
yPos += 35;
}
}
// Clean expired
notifications = notifications.filter(n => now - n.time < n.duration);
});
// ============================================================================
// TOGGLE EFFECTS (Client-side processing)
// ============================================================================
addEventHandler("OnProcess", function(event) {
if (!localPlayer) return;
// God Mode
if (toggleStates.godMode) {
localPlayer.health = 200;
localPlayer.armour = 100;
}
// Never Wanted
if (toggleStates.neverWanted) {
localPlayer.wantedLevel = 0;
}
// Super Jump (handled via natives if available)
// Fast Run (handled via natives if available)
// Drift Mode & Vehicle God Mode
if (localPlayer.vehicle) {
if (toggleStates.vehGodMode) {
localPlayer.vehicle.health = 1000;
}
}
});
// ============================================================================
// INITIALIZATION
// ============================================================================
addEventHandler("OnResourceStart", function(event, resource) {
console.log("[ModMenu] Client script loaded!");
console.log("[ModMenu] Press F5 to open the menu");
});
addEventHandler("OnLocalPlayerSpawn", function(event) {
showNotification("Press F5 to open Mod Menu");
});
console.log("[ModMenu] Client script loaded - Press F5 to open menu!");

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<meta>
<info author="GTAConnected Server" type="script" version="1.0.0" description="Interactive mod menu with vehicle spawner, player options, and more" />
<script src="server.js" type="server" language="javascript" />
<script src="client.js" type="client" language="javascript" />
</meta>

571
resources/modmenu/server.js Normal file
View File

@@ -0,0 +1,571 @@
// ============================================================================
// MOD MENU - Server Side
// Handles all server-side actions triggered from the client menu
// ============================================================================
// Vehicle model hashes for spawning
const vehicleModels = {
// Sports Cars
"infernus": -1461482751,
"turismo": -982130927,
"comet": 1063483177,
"banshee": -1823484407,
"sultan": 970598228,
"coquette": 108773431,
"feltzer": -349601129,
"f620": -591651781,
"buffalo": -304802106,
// Super Cars
"entityxf": -1291952903,
"adder": -1216765807,
"vacca": 338562499,
"bullet": -1696146015,
"cheetah": -1311154784,
// Muscle Cars
"sabregt": 1357660823,
"stalion": 1923400478,
"vigero": -825837129,
"dukes": 723973206,
"ruiner": -227741703,
"phoenix": -2095439403,
"gauntlet": -1800170043,
"dominator": 80636076,
// SUVs
"patriot": -808457413,
"cavalcade": 2006918058,
"granger": 1269098716,
"huntley": 486987393,
"landstalker": 1269098716,
"habanero": 884422927,
"serrano": 1337041428,
"rebla": 83136452,
// Sedans
"oracle": 1348744438,
"schafter": -888242983,
"admiral": -1645064850,
"vincent": -884237051,
"presidente": -1150599089,
"cognoscenti": -2030171296,
"blista": -344943009,
"premier": -1883869285,
// Motorcycles
"nrg900": -1706076364,
"pcj600": -909201658,
"sanchez": 788045382,
"faggio": 55628203,
"bati": -891462355,
"akuma": 1672195559,
"double": -1670998136,
"hakuchou": 1265391242,
"hexer": 301427732,
"daemon": 2006142190,
// Emergency
"police": 2046537925,
"police2": -1627000575,
"fbi": 1127131465,
"noose": -1683328900,
"ambulance": 1171614426,
"firetruk": 1938952078,
"enforcer": 2046537925,
// Aircraft
"annihilator": 837858166,
"maverick": -1660661558,
"polmav": 353883353,
"buzzard": 788747387,
"shamal": -1214293858,
// Boats
"jetmax": 861409633,
"marquis": -1043459709,
"predator": -488123221,
"tropic": 290013743,
"dinghy": 1033245328,
"squalo": 400514754,
"reefer": 1016996501,
// Special
"taxi": -956048545,
"stretch": -1961627517,
"bus": -713569950,
"trashmaster": 1917016601,
"forklift": 1491375716,
"caddy": 1147287684,
"bulldozer": 1886712733,
"phantom": -2137348917
};
// Player skin models
const skinModels = [
-1667301416, // Niko
-163448165, // Roman
1936355839, // Jacob
-1938475496, // Brucie
970234525, // Playboy X
-1784875845, // Johnny
-1403507487, // Luis
-1320879687, // Cop
-1306011498, // NOOSE
2136829318, // Paramedic
1616659040, // Firefighter
-268651930, // Business
1943617350 // Hobo
];
// Store spawned vehicles per player
let playerVehicles = {};
// Player toggle states (for server-validated features)
let playerToggles = {};
// ============================================================================
// EVENTS
// ============================================================================
addEventHandler("OnResourceStart", function(event, resource) {
console.log("[ModMenu] Server resource started!");
});
addEventHandler("OnPlayerJoined", function(event, client) {
playerVehicles[client.index] = [];
playerToggles[client.index] = {};
// Inform player about the menu
messageClient("[MOD MENU] Press F5 to open the mod menu!", client, [255, 200, 100, 255]);
});
addEventHandler("OnPlayerQuit", function(event, client, reason) {
// Clean up player vehicles
if (playerVehicles[client.index]) {
for (let i = 0; i < playerVehicles[client.index].length; i++) {
let veh = playerVehicles[client.index][i];
if (veh) {
destroyElement(veh);
}
}
delete playerVehicles[client.index];
}
delete playerToggles[client.index];
});
// ============================================================================
// NETWORK HANDLERS - Self Options
// ============================================================================
addNetworkHandler("ModMenu:SelfOption", function(client, option) {
if (!client.player) {
triggerNetworkEvent("ModMenu:Notification", client, "You need to spawn first!");
return;
}
switch(option) {
case "health":
client.player.health = 200;
break;
case "armor":
client.player.armour = 100;
break;
case "max":
client.player.health = 200;
client.player.armour = 100;
break;
case "weapons":
giveAllWeapons(client);
break;
case "wanted":
client.player.wantedLevel = 0;
break;
case "respawn":
// Respawn at random location
let spawns = [
{ x: -252.0, y: 947.0, z: 15.0 },
{ x: 932.0, y: -495.0, z: 15.0 },
{ x: -365.0, y: 1163.0, z: 14.0 },
{ x: 1243.0, y: -196.0, z: 26.0 }
];
let spawn = spawns[Math.floor(Math.random() * spawns.length)];
client.spawn([spawn.x, spawn.y, spawn.z], 0, -1667301416);
break;
case "suicide":
client.player.health = 0;
break;
}
console.log("[ModMenu] " + client.name + " used self option: " + option);
});
// ============================================================================
// NETWORK HANDLERS - Toggle Features
// ============================================================================
addNetworkHandler("ModMenu:Toggle", function(client, feature, state) {
if (!playerToggles[client.index]) {
playerToggles[client.index] = {};
}
playerToggles[client.index][feature] = state;
console.log("[ModMenu] " + client.name + " toggled " + feature + ": " + state);
});
// ============================================================================
// NETWORK HANDLERS - Skin Change
// ============================================================================
addNetworkHandler("ModMenu:ChangeSkin", function(client, skinId) {
if (!client.player) {
triggerNetworkEvent("ModMenu:Notification", client, "You need to spawn first!");
return;
}
if (skinId === "random") {
skinId = skinModels[Math.floor(Math.random() * skinModels.length)];
}
client.player.modelIndex = skinId;
console.log("[ModMenu] " + client.name + " changed skin to: " + skinId);
});
// ============================================================================
// NETWORK HANDLERS - Vehicle Spawning
// ============================================================================
addNetworkHandler("ModMenu:SpawnVehicle", function(client, vehicleName) {
if (!client.player) {
triggerNetworkEvent("ModMenu:Notification", client, "You need to spawn first!");
return;
}
let modelHash = vehicleModels[vehicleName];
if (!modelHash) {
triggerNetworkEvent("ModMenu:Notification", client, "Vehicle not found!");
return;
}
// Delete previous vehicles (limit to 1 per player)
deletePlayerVehicles(client);
// Get spawn position
let pos = client.player.position;
let heading = client.player.heading;
let spawnX = pos[0] + (Math.sin(heading) * 4);
let spawnY = pos[1] + (Math.cos(heading) * 4);
let spawnZ = pos[2] + 1;
// Create vehicle
let vehicle = gta.createVehicle(modelHash, [spawnX, spawnY, spawnZ], heading);
if (vehicle) {
if (!playerVehicles[client.index]) {
playerVehicles[client.index] = [];
}
playerVehicles[client.index].push(vehicle);
// Set vehicle properties
vehicle.health = 1000;
vehicle.locked = false;
vehicle.engine = true;
// Random color
let c1 = Math.floor(Math.random() * 132);
let c2 = Math.floor(Math.random() * 132);
vehicle.colour1 = c1;
vehicle.colour2 = c2;
triggerNetworkEvent("ModMenu:Notification", client, "Vehicle spawned: " + vehicleName.toUpperCase());
console.log("[ModMenu] " + client.name + " spawned " + vehicleName);
} else {
triggerNetworkEvent("ModMenu:Notification", client, "Failed to spawn vehicle!");
}
});
addNetworkHandler("ModMenu:DeleteVehicles", function(client) {
deletePlayerVehicles(client);
triggerNetworkEvent("ModMenu:Notification", client, "Your vehicles have been deleted!");
});
function deletePlayerVehicles(client) {
if (playerVehicles[client.index]) {
for (let i = 0; i < playerVehicles[client.index].length; i++) {
let veh = playerVehicles[client.index][i];
if (veh) {
destroyElement(veh);
}
}
playerVehicles[client.index] = [];
}
}
// ============================================================================
// NETWORK HANDLERS - Vehicle Options
// ============================================================================
addNetworkHandler("ModMenu:VehicleOption", function(client, option) {
if (!client.player || !client.player.vehicle) {
triggerNetworkEvent("ModMenu:Notification", client, "You need to be in a vehicle!");
return;
}
let vehicle = client.player.vehicle;
switch(option) {
case "repair":
vehicle.health = 1000;
break;
case "flip":
let rot = vehicle.rotation;
vehicle.rotation = [0, 0, rot[2]];
break;
case "clean":
vehicle.dirtLevel = 0;
break;
case "upgrade":
// Max out visual mods if supported
vehicle.health = 1000;
break;
case "nitro":
// Boost vehicle forward
let pos = vehicle.position;
let heading = vehicle.heading;
let boost = 50;
vehicle.position = [
pos[0] + (Math.sin(heading) * boost),
pos[1] + (Math.cos(heading) * boost),
pos[2]
];
break;
}
console.log("[ModMenu] " + client.name + " used vehicle option: " + option);
});
addNetworkHandler("ModMenu:VehicleColor", function(client, color1, color2) {
if (!client.player || !client.player.vehicle) {
triggerNetworkEvent("ModMenu:Notification", client, "You need to be in a vehicle!");
return;
}
client.player.vehicle.colour1 = color1;
client.player.vehicle.colour2 = color2;
console.log("[ModMenu] " + client.name + " changed vehicle color to: " + color1 + ", " + color2);
});
addNetworkHandler("ModMenu:Handling", function(client, property, value) {
// Store handling modifications for the player
// Note: Actual handling modification depends on GTAC's native support
if (!playerToggles[client.index]) {
playerToggles[client.index] = {};
}
playerToggles[client.index]["handling_" + property] = value;
console.log("[ModMenu] " + client.name + " set handling " + property + " to: " + value);
});
addNetworkHandler("ModMenu:HandlingReset", function(client) {
if (playerToggles[client.index]) {
delete playerToggles[client.index].handling_grip;
delete playerToggles[client.index].handling_acceleration;
delete playerToggles[client.index].handling_topSpeed;
delete playerToggles[client.index].handling_braking;
}
console.log("[ModMenu] " + client.name + " reset vehicle handling");
});
// ============================================================================
// NETWORK HANDLERS - Teleportation
// ============================================================================
addNetworkHandler("ModMenu:Teleport", function(client, x, y, z) {
if (!client.player) {
triggerNetworkEvent("ModMenu:Notification", client, "You need to spawn first!");
return;
}
if (client.player.vehicle) {
client.player.vehicle.position = [x, y, z];
} else {
client.player.position = [x, y, z];
}
console.log("[ModMenu] " + client.name + " teleported to: " + x + ", " + y + ", " + z);
});
addNetworkHandler("ModMenu:TeleportWaypoint", function(client) {
// Teleport to map waypoint - requires client-side waypoint data
triggerNetworkEvent("ModMenu:Notification", client, "Set a waypoint on the map first!");
});
addNetworkHandler("ModMenu:TeleportToPlayer", function(client, targetId) {
if (!client.player) {
triggerNetworkEvent("ModMenu:Notification", client, "You need to spawn first!");
return;
}
let clients = getClients();
let target = null;
for (let i = 0; i < clients.length; i++) {
if (clients[i].index == targetId) {
target = clients[i];
break;
}
}
if (target && target.player) {
let pos = target.player.position;
if (client.player.vehicle) {
client.player.vehicle.position = [pos[0] + 3, pos[1], pos[2]];
} else {
client.player.position = [pos[0] + 3, pos[1], pos[2]];
}
triggerNetworkEvent("ModMenu:Notification", client, "Teleported to: " + target.name);
console.log("[ModMenu] " + client.name + " teleported to " + target.name);
} else {
triggerNetworkEvent("ModMenu:Notification", client, "Player not found or not spawned!");
}
});
// ============================================================================
// NETWORK HANDLERS - Get Players
// ============================================================================
addNetworkHandler("ModMenu:GetPlayers", function(client) {
let clients = getClients();
let playerList = [];
for (let i = 0; i < clients.length; i++) {
let c = clients[i];
playerList.push({
id: c.index,
name: c.name
});
}
triggerNetworkEvent("ModMenu:PlayerList", client, playerList);
});
// ============================================================================
// NETWORK HANDLERS - World Options
// ============================================================================
addNetworkHandler("ModMenu:WorldTime", function(client, hour) {
gta.time = [hour, 0];
message("[WORLD] " + client.name + " changed time to: " + hour + ":00", [100, 200, 255, 255]);
console.log("[ModMenu] " + client.name + " changed time to: " + hour);
});
addNetworkHandler("ModMenu:WorldWeather", function(client, weatherId) {
gta.weather = weatherId;
message("[WORLD] " + client.name + " changed the weather", [100, 200, 255, 255]);
console.log("[ModMenu] " + client.name + " changed weather to: " + weatherId);
});
// ============================================================================
// NETWORK HANDLERS - Weapons
// ============================================================================
addNetworkHandler("ModMenu:GiveWeapon", function(client, weaponId) {
if (!client.player) {
triggerNetworkEvent("ModMenu:Notification", client, "You need to spawn first!");
return;
}
client.giveWeapon(weaponId, 500);
console.log("[ModMenu] " + client.name + " got weapon: " + weaponId);
});
function giveAllWeapons(client) {
if (!client.player) return;
// GTA IV Weapons
client.giveWeapon(1, 1); // Bat
client.giveWeapon(2, 1); // Knife
client.giveWeapon(5, 500); // Pistol
client.giveWeapon(6, 500); // Deagle
client.giveWeapon(9, 200); // Shotgun
client.giveWeapon(10, 200); // Combat Shotgun
client.giveWeapon(11, 500); // Micro SMG
client.giveWeapon(12, 500); // SMG
client.giveWeapon(14, 500); // AK47
client.giveWeapon(15, 500); // M4
client.giveWeapon(16, 100); // Sniper
client.giveWeapon(18, 20); // RPG
client.giveWeapon(19, 20); // Grenades
client.giveWeapon(20, 20); // Molotov
}
// ============================================================================
// NETWORK HANDLERS - Fun Options
// ============================================================================
addNetworkHandler("ModMenu:Fun", function(client, option) {
if (!client.player) {
triggerNetworkEvent("ModMenu:Notification", client, "You need to spawn first!");
return;
}
let pos = client.player.position;
switch(option) {
case "launch":
client.player.position = [pos[0], pos[1], pos[2] + 50];
break;
case "explode":
gta.createExplosion(pos, 0, 5.0);
break;
case "ped":
// Spawn a random ped near player
let pedSkin = skinModels[Math.floor(Math.random() * skinModels.length)];
let ped = gta.createPed(pedSkin, [pos[0] + 3, pos[1] + 3, pos[2]], 0);
if (ped) {
console.log("[ModMenu] " + client.name + " spawned a ped");
}
break;
case "ragdoll":
// Trigger ragdoll via health damage
let currentHealth = client.player.health;
client.player.health = currentHealth - 10;
setTimeout(function() {
if (client.player) {
client.player.health = currentHealth;
}
}, 100);
break;
case "clearpeds":
// Clear peds in area - limited implementation
triggerNetworkEvent("ModMenu:Notification", client, "Area clearing requested");
break;
case "clearvehicles":
// Clear vehicles in area - limited implementation
triggerNetworkEvent("ModMenu:Notification", client, "Vehicle clearing requested");
break;
}
console.log("[ModMenu] " + client.name + " used fun option: " + option);
});
// ============================================================================
// INITIALIZATION
// ============================================================================
console.log("[ModMenu] Server script loaded!");

View File

@@ -33,5 +33,6 @@
<resource src="chat" />
<resource src="teleport" />
<resource src="vehicles" />
<resource src="modmenu" />
</resources>
</server>