mirror of
https://github.com/iDisaster/GTAConnected.git
synced 2026-03-08 09:25:23 +00:00
Merge pull request #20 from iDisaster/claude/vehicle-options-cleanup-RlGVO
Cleanup vehicle options and enhance player interaction features
This commit is contained in:
@@ -360,11 +360,21 @@ const itemDescriptions = {
|
|||||||
"color_slot_edit": "🎨 Use LEFT/RIGHT arrows to change color (0-133 from GTA IV carcols.dat)",
|
"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!",
|
"color_preset": "🎨 Apply preset colors to all 4 vehicle color slots instantly!",
|
||||||
|
|
||||||
// Vehicle Upgrade descriptions
|
// Vehicle Extras descriptions
|
||||||
"veh_upgrade_add": "🔧 Add upgrade - Enhance your vehicle with this mod!",
|
"veh_extra_toggle": "🔧 Toggle vehicle extra part ON/OFF - Shows current state!",
|
||||||
"veh_upgrade_remove": "❌ Remove upgrade - Take off this modification!",
|
"veh_extras": "🔧 EXTRAS - Toggle vehicle extra parts like bumpers, spoilers, etc!",
|
||||||
"veh_upgrade_remove_all": "🗑️ REMOVE ALL - Strip all upgrades from vehicle!",
|
"veh_extra_refresh": "🔄 Refresh the ON/OFF status of all extras!",
|
||||||
"veh_upgrades": "🔧 UPGRADES - Add NOS, hydraulics, wheels, spoilers and more!",
|
|
||||||
|
// Vehicle Flip toggle
|
||||||
|
"vehFlipped": "🔄 FLIP VEHICLE - Flips your vehicle upright when ON!",
|
||||||
|
|
||||||
|
// Super Jump toggle
|
||||||
|
"superJump": "🦘 SUPER JUMP - Jump extra high when enabled!",
|
||||||
|
|
||||||
|
// Player options
|
||||||
|
"teleport_to_player": "📍 Teleport directly to this player's location!",
|
||||||
|
"heal_player": "💊 Heal this player to full health!",
|
||||||
|
"spectate_player": "👁️ Watch this player from their perspective!",
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -434,6 +444,7 @@ const menuData = {
|
|||||||
{ label: "God Mode", action: "toggle", target: "godMode", state: false },
|
{ label: "God Mode", action: "toggle", target: "godMode", state: false },
|
||||||
{ label: "Invincible", action: "toggle", target: "invincible", state: false },
|
{ label: "Invincible", action: "toggle", target: "invincible", state: false },
|
||||||
{ label: "Super Run", action: "toggle", target: "superRun", state: false },
|
{ label: "Super Run", action: "toggle", target: "superRun", state: false },
|
||||||
|
{ label: "Super Jump", action: "toggle", target: "superJump", state: false },
|
||||||
{ label: "No Ragdoll", action: "toggle", target: "noRagdoll", state: false },
|
{ label: "No Ragdoll", action: "toggle", target: "noRagdoll", state: false },
|
||||||
{ label: "Never Wanted", action: "toggle", target: "neverWanted", state: false },
|
{ label: "Never Wanted", action: "toggle", target: "neverWanted", state: false },
|
||||||
{ label: "Invisible", action: "toggle", target: "invisible", state: false },
|
{ label: "Invisible", action: "toggle", target: "invisible", state: false },
|
||||||
@@ -954,10 +965,10 @@ const menuData = {
|
|||||||
vehicleOptions: {
|
vehicleOptions: {
|
||||||
title: "VEHICLE OPTIONS",
|
title: "VEHICLE OPTIONS",
|
||||||
items: [
|
items: [
|
||||||
{ label: "Repair Vehicle", action: "veh_repair" },
|
{ label: "Repair & Clean Vehicle", action: "veh_repair" },
|
||||||
{ label: "Flip Vehicle", action: "veh_flip" },
|
{ label: "Flip Vehicle", action: "toggle", target: "vehFlipped", state: false },
|
||||||
{ label: "Vehicle Colors", action: "submenu", target: "veh_colors" },
|
{ label: "Vehicle Colors", action: "submenu", target: "veh_colors" },
|
||||||
{ label: "Vehicle Upgrades", action: "submenu", target: "veh_upgrades" },
|
{ label: "Vehicle Extras", action: "submenu", target: "veh_extras" },
|
||||||
{ label: "--- Toggles ---", action: "none" },
|
{ label: "--- Toggles ---", action: "none" },
|
||||||
{ label: "God Mode", action: "toggle", target: "vehGodMode", state: false },
|
{ label: "God Mode", action: "toggle", target: "vehGodMode", state: false },
|
||||||
{ label: "Nitro Boost", action: "veh_nitro" },
|
{ label: "Nitro Boost", action: "veh_nitro" },
|
||||||
@@ -975,51 +986,20 @@ const menuData = {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
veh_upgrades: {
|
veh_extras: {
|
||||||
title: "VEHICLE UPGRADES",
|
title: "VEHICLE EXTRAS",
|
||||||
items: [
|
items: [
|
||||||
{ label: "--- Performance ---", action: "none" },
|
{ label: "Extra 1", action: "veh_extra_toggle", value: 1 },
|
||||||
{ label: "Add Nitro", action: "veh_upgrade_add", value: 1010 },
|
{ label: "Extra 2", action: "veh_extra_toggle", value: 2 },
|
||||||
{ label: "Add Hydraulics", action: "veh_upgrade_add", value: 1087 },
|
{ label: "Extra 3", action: "veh_extra_toggle", value: 3 },
|
||||||
{ label: "--- Wheels ---", action: "none" },
|
{ label: "Extra 4", action: "veh_extra_toggle", value: 4 },
|
||||||
{ label: "Offroad Wheels", action: "veh_upgrade_add", value: 1025 },
|
{ label: "Extra 5", action: "veh_extra_toggle", value: 5 },
|
||||||
{ label: "Shadow Wheels", action: "veh_upgrade_add", value: 1073 },
|
{ label: "Extra 6", action: "veh_extra_toggle", value: 6 },
|
||||||
{ label: "Mega Wheels", action: "veh_upgrade_add", value: 1074 },
|
{ label: "Extra 7", action: "veh_extra_toggle", value: 7 },
|
||||||
{ label: "Rimshine Wheels", action: "veh_upgrade_add", value: 1075 },
|
{ label: "Extra 8", action: "veh_extra_toggle", value: 8 },
|
||||||
{ label: "Wires Wheels", action: "veh_upgrade_add", value: 1076 },
|
{ label: "Extra 9", action: "veh_extra_toggle", value: 9 },
|
||||||
{ label: "Classic Wheels", action: "veh_upgrade_add", value: 1077 },
|
{ label: "--- Refresh ---", action: "none" },
|
||||||
{ label: "Twist Wheels", action: "veh_upgrade_add", value: 1078 },
|
{ label: "Refresh Extra Status", action: "veh_extra_refresh" }
|
||||||
{ label: "Cutter Wheels", action: "veh_upgrade_add", value: 1079 },
|
|
||||||
{ label: "Switch Wheels", action: "veh_upgrade_add", value: 1080 },
|
|
||||||
{ label: "Grove Wheels", action: "veh_upgrade_add", value: 1081 },
|
|
||||||
{ label: "Import Wheels", action: "veh_upgrade_add", value: 1082 },
|
|
||||||
{ label: "Dollar Wheels", action: "veh_upgrade_add", value: 1083 },
|
|
||||||
{ label: "--- Exhausts ---", action: "none" },
|
|
||||||
{ label: "Upswept Exhaust", action: "veh_upgrade_add", value: 1018 },
|
|
||||||
{ label: "Twin Exhaust", action: "veh_upgrade_add", value: 1019 },
|
|
||||||
{ label: "Large Exhaust", action: "veh_upgrade_add", value: 1020 },
|
|
||||||
{ label: "Medium Exhaust", action: "veh_upgrade_add", value: 1021 },
|
|
||||||
{ label: "Small Exhaust", action: "veh_upgrade_add", value: 1022 },
|
|
||||||
{ label: "--- Spoilers ---", action: "none" },
|
|
||||||
{ label: "Pro Spoiler", action: "veh_upgrade_add", value: 1000 },
|
|
||||||
{ label: "Win Spoiler", action: "veh_upgrade_add", value: 1001 },
|
|
||||||
{ label: "Drag Spoiler", action: "veh_upgrade_add", value: 1002 },
|
|
||||||
{ label: "Alpha Spoiler", action: "veh_upgrade_add", value: 1003 },
|
|
||||||
{ label: "Champ Spoiler", action: "veh_upgrade_add", value: 1014 },
|
|
||||||
{ label: "Fury Spoiler", action: "veh_upgrade_add", value: 1015 },
|
|
||||||
{ label: "--- Roof ---", action: "none" },
|
|
||||||
{ label: "Roof Scoop", action: "veh_upgrade_add", value: 1006 },
|
|
||||||
{ label: "Roof Vent", action: "veh_upgrade_add", value: 1032 },
|
|
||||||
{ label: "Alien Roof Vent", action: "veh_upgrade_add", value: 1033 },
|
|
||||||
{ label: "--- Side Skirts ---", action: "none" },
|
|
||||||
{ label: "Right Alien Skirt", action: "veh_upgrade_add", value: 1007 },
|
|
||||||
{ label: "Left Alien Skirt", action: "veh_upgrade_add", value: 1017 },
|
|
||||||
{ label: "Right Chrome Skirt", action: "veh_upgrade_add", value: 1027 },
|
|
||||||
{ label: "Left Chrome Skirt", action: "veh_upgrade_add", value: 1031 },
|
|
||||||
{ label: "--- Remove Upgrades ---", action: "none" },
|
|
||||||
{ label: "Remove Nitro", action: "veh_upgrade_remove", value: 1010 },
|
|
||||||
{ label: "Remove Hydraulics", action: "veh_upgrade_remove", value: 1087 },
|
|
||||||
{ label: "Remove All Upgrades", action: "veh_upgrade_remove_all" }
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -1330,7 +1310,6 @@ const menuData = {
|
|||||||
items: [
|
items: [
|
||||||
{ label: "--- Physics Fun ---", action: "none" },
|
{ label: "--- Physics Fun ---", action: "none" },
|
||||||
{ label: "Launch Me Up", action: "fun_launch" },
|
{ label: "Launch Me Up", action: "fun_launch" },
|
||||||
{ label: "Super Jump", action: "fun_superjump" },
|
|
||||||
{ label: "Moon Gravity", action: "toggle", target: "moonGravity", state: false },
|
{ label: "Moon Gravity", action: "toggle", target: "moonGravity", state: false },
|
||||||
{ label: "Drunk Mode", action: "toggle", target: "drunkMode", state: false },
|
{ label: "Drunk Mode", action: "toggle", target: "drunkMode", state: false },
|
||||||
{ label: "Spinbot", action: "toggle", target: "spinbot", state: false },
|
{ label: "Spinbot", action: "toggle", target: "spinbot", state: false },
|
||||||
@@ -1361,12 +1340,14 @@ let toggleStates = {
|
|||||||
godMode: false,
|
godMode: false,
|
||||||
invincible: false,
|
invincible: false,
|
||||||
superRun: false,
|
superRun: false,
|
||||||
|
superJump: false,
|
||||||
noRagdoll: false,
|
noRagdoll: false,
|
||||||
neverWanted: false,
|
neverWanted: false,
|
||||||
invisible: false,
|
invisible: false,
|
||||||
infiniteSprint: false,
|
infiniteSprint: false,
|
||||||
freezePlayer: false,
|
freezePlayer: false,
|
||||||
vehGodMode: false,
|
vehGodMode: false,
|
||||||
|
vehFlipped: false,
|
||||||
driveOnWater: false,
|
driveOnWater: false,
|
||||||
rainbowCar: false,
|
rainbowCar: false,
|
||||||
neonLights: false,
|
neonLights: false,
|
||||||
@@ -1643,7 +1624,8 @@ function getNetworkMenuItems() {
|
|||||||
for (let i = 0; i < playerList.length; i++) {
|
for (let i = 0; i < playerList.length; i++) {
|
||||||
items.push({
|
items.push({
|
||||||
label: playerList[i].name + " [ID: " + playerList[i].id + "]",
|
label: playerList[i].name + " [ID: " + playerList[i].id + "]",
|
||||||
action: "teleport_to_player_direct",
|
action: "submenu",
|
||||||
|
target: "player_options",
|
||||||
playerData: playerList[i]
|
playerData: playerList[i]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1661,6 +1643,31 @@ function refreshPlayerList() {
|
|||||||
showNotification("Refreshing players...");
|
showNotification("Refreshing players...");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Refresh vehicle extras status - updates menu items with current ON/OFF state
|
||||||
|
function refreshVehicleExtras() {
|
||||||
|
if (!localPlayer || !localPlayer.vehicle) return;
|
||||||
|
|
||||||
|
let veh = localPlayer.vehicle;
|
||||||
|
if (menuData.veh_extras && menuData.veh_extras.items) {
|
||||||
|
for (let i = 0; i < menuData.veh_extras.items.length; i++) {
|
||||||
|
let item = menuData.veh_extras.items[i];
|
||||||
|
if (item.action === "veh_extra_toggle" && item.value) {
|
||||||
|
try {
|
||||||
|
let hasExtra = natives.doesExtraExist(veh, item.value);
|
||||||
|
if (hasExtra) {
|
||||||
|
let isOn = natives.isVehicleExtraTurnedOn(veh, item.value);
|
||||||
|
item.label = "Extra " + item.value + " [" + (isOn ? "ON" : "OFF") + "]";
|
||||||
|
} else {
|
||||||
|
item.label = "Extra " + item.value + " [N/A]";
|
||||||
|
}
|
||||||
|
} catch(e) {
|
||||||
|
item.label = "Extra " + item.value + " [?]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// ACTION HANDLING
|
// ACTION HANDLING
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -1719,6 +1726,11 @@ function selectItem() {
|
|||||||
colorEditorActive = true;
|
colorEditorActive = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Refresh vehicle extras status when entering extras menu
|
||||||
|
if (item.target === "veh_extras") {
|
||||||
|
refreshVehicleExtras();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1810,7 +1822,7 @@ function selectItem() {
|
|||||||
|
|
||||||
case "veh_repair":
|
case "veh_repair":
|
||||||
triggerNetworkEvent("ModMenu:VehicleOption", "repair");
|
triggerNetworkEvent("ModMenu:VehicleOption", "repair");
|
||||||
showNotification("Repaired!");
|
showNotification("Repaired & Cleaned!");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "veh_flip":
|
case "veh_flip":
|
||||||
@@ -2048,6 +2060,51 @@ function selectItem() {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "heal_player":
|
||||||
|
if (selectedPlayer) {
|
||||||
|
triggerNetworkEvent("ModMenu:HealPlayer", selectedPlayer.id);
|
||||||
|
showNotification("Healing " + selectedPlayer.name);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "spectate_player":
|
||||||
|
if (selectedPlayer) {
|
||||||
|
triggerNetworkEvent("ModMenu:SpectatePlayer", selectedPlayer.id);
|
||||||
|
showNotification("Spectating " + selectedPlayer.name);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "veh_extra_toggle":
|
||||||
|
if (localPlayer && localPlayer.vehicle) {
|
||||||
|
try {
|
||||||
|
let veh = localPlayer.vehicle;
|
||||||
|
let extraId = item.value;
|
||||||
|
// Check if extra exists first
|
||||||
|
let hasExtra = natives.doesExtraExist(veh, extraId);
|
||||||
|
if (hasExtra) {
|
||||||
|
let isOn = natives.isVehicleExtraTurnedOn(veh, extraId);
|
||||||
|
natives.turnOffVehicleExtra(veh, extraId, isOn); // Toggle: if ON, turn OFF; if OFF, turn ON
|
||||||
|
showNotification("Extra " + extraId + ": " + (isOn ? "OFF" : "ON"));
|
||||||
|
} else {
|
||||||
|
showNotification("Extra " + extraId + " not available");
|
||||||
|
}
|
||||||
|
} catch(e) {
|
||||||
|
showNotification("Extra toggle failed");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
showNotification("Get in a vehicle first!");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "veh_extra_refresh":
|
||||||
|
if (localPlayer && localPlayer.vehicle) {
|
||||||
|
refreshVehicleExtras();
|
||||||
|
showNotification("Extras refreshed!");
|
||||||
|
} else {
|
||||||
|
showNotification("Get in a vehicle first!");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case "fun_launch":
|
case "fun_launch":
|
||||||
triggerNetworkEvent("ModMenu:Fun", "launch");
|
triggerNetworkEvent("ModMenu:Fun", "launch");
|
||||||
showNotification("LAUNCH!");
|
showNotification("LAUNCH!");
|
||||||
@@ -2151,17 +2208,6 @@ function selectItem() {
|
|||||||
} catch(e) {}
|
} catch(e) {}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "fun_superjump":
|
|
||||||
if (localPlayer) {
|
|
||||||
try {
|
|
||||||
let vel = localPlayer.velocity;
|
|
||||||
vel.z = 15.0;
|
|
||||||
localPlayer.velocity = vel;
|
|
||||||
showNotification("SUPER JUMP!");
|
|
||||||
} catch(e) {}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "fun_random_explosion":
|
case "fun_random_explosion":
|
||||||
if (localPlayer) {
|
if (localPlayer) {
|
||||||
try {
|
try {
|
||||||
@@ -2310,10 +2356,13 @@ function selectItem() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function openPlayerMenu(playerData) {
|
function openPlayerMenu(playerData) {
|
||||||
|
selectedPlayer = playerData;
|
||||||
menuData.player_options = {
|
menuData.player_options = {
|
||||||
title: playerData.name,
|
title: playerData.name,
|
||||||
items: [
|
items: [
|
||||||
{ label: "Teleport to Player", action: "teleport_to_player" }
|
{ label: "Teleport to Player", action: "teleport_to_player" },
|
||||||
|
{ label: "Heal Player", action: "heal_player" },
|
||||||
|
{ label: "Spectate Player", action: "spectate_player" }
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
menuStack.push({ menu: currentMenu, index: selectedIndex, scroll: scrollOffset });
|
menuStack.push({ menu: currentMenu, index: selectedIndex, scroll: scrollOffset });
|
||||||
@@ -2492,6 +2541,70 @@ addNetworkHandler("ModMenu:ExecuteTeleportToPlayer", function(targetId) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Execute heal - heal the player
|
||||||
|
addNetworkHandler("ModMenu:ExecuteHeal", function() {
|
||||||
|
if (!localPlayer) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
localPlayer.health = 200;
|
||||||
|
localPlayer.armour = 100;
|
||||||
|
showNotification("You were healed!");
|
||||||
|
} catch(e) {
|
||||||
|
console.log("[ModMenu] Heal error: " + e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Spectate state tracking
|
||||||
|
let spectateTarget = null;
|
||||||
|
let spectateActive = false;
|
||||||
|
let priorPosition = null;
|
||||||
|
|
||||||
|
// Execute spectate - camera follows target player
|
||||||
|
addNetworkHandler("ModMenu:ExecuteSpectate", function(targetId, targetName, x, y, z) {
|
||||||
|
if (!localPlayer) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (spectateActive && spectateTarget === targetId) {
|
||||||
|
// Toggle off spectate
|
||||||
|
spectateActive = false;
|
||||||
|
spectateTarget = null;
|
||||||
|
// Return to prior position
|
||||||
|
if (priorPosition) {
|
||||||
|
localPlayer.position = priorPosition;
|
||||||
|
priorPosition = null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
natives.setCharVisible(localPlayer, true);
|
||||||
|
} catch(e) {}
|
||||||
|
showNotification("Stopped spectating");
|
||||||
|
} else {
|
||||||
|
// Start spectating
|
||||||
|
priorPosition = localPlayer.position;
|
||||||
|
spectateActive = true;
|
||||||
|
spectateTarget = targetId;
|
||||||
|
// Make player invisible and teleport near target
|
||||||
|
try {
|
||||||
|
natives.setCharVisible(localPlayer, false);
|
||||||
|
} catch(e) {}
|
||||||
|
localPlayer.position = new Vec3(x + 5, y + 5, z + 10);
|
||||||
|
showNotification("Spectating " + targetName + " (click again to stop)");
|
||||||
|
}
|
||||||
|
} catch(e) {
|
||||||
|
console.log("[ModMenu] Spectate error: " + e);
|
||||||
|
showNotification("Spectate failed");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update spectate position - follow target player
|
||||||
|
addNetworkHandler("ModMenu:SpectatePosition", function(x, y, z) {
|
||||||
|
if (!localPlayer || !spectateActive) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Keep player near target but at a viewing distance
|
||||||
|
localPlayer.position = new Vec3(x + 5, y + 5, z + 10);
|
||||||
|
} catch(e) {}
|
||||||
|
});
|
||||||
|
|
||||||
// Vehicle model names (cleaned up for proper spawning)
|
// Vehicle model names (cleaned up for proper spawning)
|
||||||
const vehicleModels = [
|
const vehicleModels = [
|
||||||
// Sports Cars
|
// Sports Cars
|
||||||
@@ -2737,7 +2850,15 @@ addNetworkHandler("ModMenu:ExecuteVehicleOption", function(option) {
|
|||||||
switch(option) {
|
switch(option) {
|
||||||
case "repair":
|
case "repair":
|
||||||
natives.fixCar(veh);
|
natives.fixCar(veh);
|
||||||
showNotification("Vehicle repaired!");
|
try {
|
||||||
|
natives.washVehicleTextures(veh, 255);
|
||||||
|
} catch(e) {
|
||||||
|
// Try alternative method
|
||||||
|
try {
|
||||||
|
veh.dirt = 0;
|
||||||
|
} catch(e2) {}
|
||||||
|
}
|
||||||
|
showNotification("Vehicle repaired & cleaned!");
|
||||||
break;
|
break;
|
||||||
case "flip":
|
case "flip":
|
||||||
let rot = veh.rotation;
|
let rot = veh.rotation;
|
||||||
@@ -3933,10 +4054,14 @@ function showNotification(text) {
|
|||||||
let lastGodMode = false;
|
let lastGodMode = false;
|
||||||
let lastInvincible = false;
|
let lastInvincible = false;
|
||||||
let lastSuperRun = false;
|
let lastSuperRun = false;
|
||||||
|
let lastSuperJump = false;
|
||||||
let lastNoRagdoll = false;
|
let lastNoRagdoll = false;
|
||||||
let lastVehGodMode = false;
|
let lastVehGodMode = false;
|
||||||
|
let lastVehFlipped = false;
|
||||||
let lastInvisible = false;
|
let lastInvisible = false;
|
||||||
let processCounter = 0;
|
let processCounter = 0;
|
||||||
|
let isJumping = false;
|
||||||
|
let wasOnGround = true;
|
||||||
|
|
||||||
// Spinbot speed control (lower = slower)
|
// Spinbot speed control (lower = slower)
|
||||||
let spinbotSpeed = 2;
|
let spinbotSpeed = 2;
|
||||||
@@ -3980,6 +4105,21 @@ addEventHandler("OnProcess", function(event) {
|
|||||||
lastSuperRun = toggleStates.superRun;
|
lastSuperRun = toggleStates.superRun;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Super Jump - boost player up when jumping
|
||||||
|
if (toggleStates.superJump) {
|
||||||
|
try {
|
||||||
|
let vel = localPlayer.velocity;
|
||||||
|
let isOnGround = vel.z > -0.5 && vel.z < 0.5;
|
||||||
|
|
||||||
|
// Detect when player just started jumping (was on ground, now moving up)
|
||||||
|
if (wasOnGround && vel.z > 0.1 && vel.z < 5.0) {
|
||||||
|
// Boost the jump
|
||||||
|
localPlayer.velocity = new Vec3(vel.x, vel.y, 12.0);
|
||||||
|
}
|
||||||
|
wasOnGround = isOnGround;
|
||||||
|
} catch(e) {}
|
||||||
|
}
|
||||||
|
|
||||||
// No Ragdoll - prevent ragdoll using multiple methods
|
// No Ragdoll - prevent ragdoll using multiple methods
|
||||||
if (toggleStates.noRagdoll !== lastNoRagdoll) {
|
if (toggleStates.noRagdoll !== lastNoRagdoll) {
|
||||||
try {
|
try {
|
||||||
@@ -4098,6 +4238,27 @@ addEventHandler("OnProcess", function(event) {
|
|||||||
try { natives.fixCar(veh); } catch(e) {}
|
try { natives.fixCar(veh); } catch(e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Vehicle Flip toggle - flip vehicle upright when enabled
|
||||||
|
if (toggleStates.vehFlipped !== lastVehFlipped) {
|
||||||
|
if (toggleStates.vehFlipped) {
|
||||||
|
try {
|
||||||
|
let rot = veh.rotation;
|
||||||
|
veh.rotation = new Vec3(0, 0, rot.z);
|
||||||
|
} catch(e) {}
|
||||||
|
}
|
||||||
|
lastVehFlipped = toggleStates.vehFlipped;
|
||||||
|
}
|
||||||
|
// Keep vehicle upright when toggle is ON
|
||||||
|
if (toggleStates.vehFlipped) {
|
||||||
|
try {
|
||||||
|
let rot = veh.rotation;
|
||||||
|
// Check if vehicle is upside down or significantly tilted
|
||||||
|
if (Math.abs(rot.x) > 0.5 || Math.abs(rot.y) > 0.5) {
|
||||||
|
veh.rotation = new Vec3(0, 0, rot.z);
|
||||||
|
}
|
||||||
|
} catch(e) {}
|
||||||
|
}
|
||||||
|
|
||||||
// Drive on water - keep vehicle above water level
|
// Drive on water - keep vehicle above water level
|
||||||
if (toggleStates.driveOnWater) {
|
if (toggleStates.driveOnWater) {
|
||||||
try {
|
try {
|
||||||
@@ -4186,6 +4347,14 @@ addEventHandler("OnProcess", function(event) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Spectate mode - follow target player position
|
||||||
|
if (spectateActive && spectateTarget !== null && processCounter % 10 === 0) {
|
||||||
|
try {
|
||||||
|
// Request updated position from server
|
||||||
|
triggerNetworkEvent("ModMenu:UpdateSpectate", spectateTarget);
|
||||||
|
} catch(e) {}
|
||||||
|
}
|
||||||
|
|
||||||
// Rainbow sky effect
|
// Rainbow sky effect
|
||||||
if (toggleStates.rainbowSky && processCounter % 3 === 0) {
|
if (toggleStates.rainbowSky && processCounter % 3 === 0) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -278,6 +278,78 @@ addNetworkHandler("ModMenu:Fun", function(client, option) {
|
|||||||
triggerNetworkEvent("ModMenu:ExecuteFun", client, option);
|
triggerNetworkEvent("ModMenu:ExecuteFun", client, option);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// NETWORK HANDLERS - Player Actions
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
addNetworkHandler("ModMenu:HealPlayer", function(client, targetId) {
|
||||||
|
console.log("[ModMenu] " + client.name + " requesting to heal player ID: " + targetId);
|
||||||
|
|
||||||
|
let clients = getClients();
|
||||||
|
for (let i = 0; i < clients.length; i++) {
|
||||||
|
if (clients[i].index == targetId) {
|
||||||
|
console.log("[ModMenu] Found target player: " + clients[i].name);
|
||||||
|
|
||||||
|
if (clients[i].player) {
|
||||||
|
try {
|
||||||
|
// Tell the target client to heal themselves
|
||||||
|
triggerNetworkEvent("ModMenu:ExecuteHeal", clients[i]);
|
||||||
|
triggerNetworkEvent("ModMenu:Notification", client, "Healed: " + clients[i].name);
|
||||||
|
triggerNetworkEvent("ModMenu:Notification", clients[i], client.name + " healed you!");
|
||||||
|
console.log("[ModMenu] Heal event sent to " + clients[i].name);
|
||||||
|
} catch(e) {
|
||||||
|
console.log("[ModMenu] Error healing player: " + e);
|
||||||
|
triggerNetworkEvent("ModMenu:Notification", client, "Error healing player!");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
triggerNetworkEvent("ModMenu:Notification", client, "Player not spawned!");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
triggerNetworkEvent("ModMenu:Notification", client, "Player not found!");
|
||||||
|
});
|
||||||
|
|
||||||
|
addNetworkHandler("ModMenu:SpectatePlayer", function(client, targetId) {
|
||||||
|
console.log("[ModMenu] " + client.name + " requesting to spectate player ID: " + targetId);
|
||||||
|
|
||||||
|
let clients = getClients();
|
||||||
|
for (let i = 0; i < clients.length; i++) {
|
||||||
|
if (clients[i].index == targetId) {
|
||||||
|
console.log("[ModMenu] Found target player: " + clients[i].name);
|
||||||
|
|
||||||
|
if (clients[i].player) {
|
||||||
|
try {
|
||||||
|
let targetPos = clients[i].player.position;
|
||||||
|
// Send spectate event to client with target info
|
||||||
|
triggerNetworkEvent("ModMenu:ExecuteSpectate", client, targetId, clients[i].name, targetPos.x, targetPos.y, targetPos.z);
|
||||||
|
console.log("[ModMenu] Spectate event sent to " + client.name);
|
||||||
|
} catch(e) {
|
||||||
|
console.log("[ModMenu] Error getting spectate info: " + e);
|
||||||
|
triggerNetworkEvent("ModMenu:Notification", client, "Error spectating player!");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
triggerNetworkEvent("ModMenu:Notification", client, "Player not spawned!");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
triggerNetworkEvent("ModMenu:Notification", client, "Player not found!");
|
||||||
|
});
|
||||||
|
|
||||||
|
addNetworkHandler("ModMenu:UpdateSpectate", function(client, targetId) {
|
||||||
|
let clients = getClients();
|
||||||
|
for (let i = 0; i < clients.length; i++) {
|
||||||
|
if (clients[i].index == targetId && clients[i].player) {
|
||||||
|
try {
|
||||||
|
let targetPos = clients[i].player.position;
|
||||||
|
triggerNetworkEvent("ModMenu:SpectatePosition", client, targetPos.x, targetPos.y, targetPos.z);
|
||||||
|
} catch(e) {}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// INITIALIZATION
|
// INITIALIZATION
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|||||||
Reference in New Issue
Block a user