mirror of
https://github.com/iDisaster/GTAConnected.git
synced 2026-03-08 09:25:23 +00:00
Add files via upload
This commit is contained in:
889
Trident/menu.js
Normal file
889
Trident/menu.js
Normal file
@@ -0,0 +1,889 @@
|
||||
/**
|
||||
* MD TRIDENT Menu - GTAConnected Port
|
||||
* Original by DEVILSDESIGN, IIV_NATHAN_VII, SHOCKixiXixiWAVE
|
||||
* Ported for GTA IV GTAConnected Server
|
||||
*/
|
||||
|
||||
// ============================================================================
|
||||
// MENU CONFIGURATION & CONSTANTS
|
||||
// ============================================================================
|
||||
|
||||
const MENU_CONFIG = {
|
||||
// Menu Position
|
||||
posX: 0.695,
|
||||
posY: 0.155,
|
||||
|
||||
// Menu Dimensions
|
||||
width: 0.25,
|
||||
itemHeight: 0.028,
|
||||
headerHeight: 0.067,
|
||||
|
||||
// Max items visible
|
||||
maxVisibleItems: 12,
|
||||
startScrolling: 8,
|
||||
|
||||
// Colors (RGBA)
|
||||
colors: {
|
||||
background: [70, 130, 180, 180], // Steel Blue
|
||||
header: [164, 134, 35, 255], // Gold
|
||||
subHeader: [58, 95, 205, 255], // Royal Blue
|
||||
item: [180, 180, 180, 255], // Gray
|
||||
itemHighlight: [255, 143, 0, 255], // Orange
|
||||
scrollbar: [100, 100, 200, 150], // Light Blue
|
||||
line: [255, 255, 255, 255], // White
|
||||
bool: [255, 128, 0, 255], // Orange
|
||||
submenu: [139, 134, 130, 255], // Gray
|
||||
jumpover: [58, 95, 205, 255], // Blue
|
||||
error: [177, 19, 26, 255], // Red
|
||||
boolOn: [0, 204, 0, 255], // Green
|
||||
boolOff: [204, 0, 0, 255], // Red
|
||||
},
|
||||
|
||||
// Text Sizes
|
||||
textSize: {
|
||||
header: 0.45,
|
||||
subHeader: 0.32,
|
||||
item: 0.35,
|
||||
version: 0.95
|
||||
},
|
||||
|
||||
// Header text
|
||||
headerText: "TRIDENT",
|
||||
subHeaderText: "MD EXTEND+ v13",
|
||||
versionText: "MD"
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// MENU ITEM TYPES
|
||||
// ============================================================================
|
||||
|
||||
const ITEM_TYPE = {
|
||||
SUBMENU: 1,
|
||||
FUNCTION: 2,
|
||||
BOOL: 3,
|
||||
VALUE_NUM: 4,
|
||||
VALUE_STRING: 5,
|
||||
VEHICLE: 6,
|
||||
PLAYER: 7,
|
||||
JUMPOVER: 8,
|
||||
ERROR: 9,
|
||||
NOT_PRESENT: 10
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// MENU STATE
|
||||
// ============================================================================
|
||||
|
||||
let menuState = {
|
||||
isOpen: false,
|
||||
currentLevel: 0,
|
||||
selectedIndex: 0,
|
||||
scrollOffset: 0,
|
||||
items: [],
|
||||
menuStack: [],
|
||||
lastSelected: [],
|
||||
glowValue: 0,
|
||||
glowIncrement: true,
|
||||
flashValue: 255,
|
||||
flashIncrement: false,
|
||||
|
||||
// Player selection for network options
|
||||
selectedPlayer: null,
|
||||
|
||||
// Input state
|
||||
inputCooldown: 0,
|
||||
holdCounter: 0,
|
||||
pressCounter: 2,
|
||||
pressMultiplier: 1
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// MENU ITEMS DATA
|
||||
// ============================================================================
|
||||
|
||||
function createMenuItem(name, type, options = {}) {
|
||||
return {
|
||||
name: name,
|
||||
type: type,
|
||||
action: options.action || null,
|
||||
submenu: options.submenu || null,
|
||||
value: options.value !== undefined ? options.value : 0,
|
||||
maxValue: options.maxValue || 0,
|
||||
minValue: options.minValue || 0,
|
||||
boolState: options.boolState || false,
|
||||
stringValues: options.stringValues || [],
|
||||
vehicleModel: options.vehicleModel || 0,
|
||||
playerId: options.playerId || -1
|
||||
};
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// MAIN MENU STRUCTURE
|
||||
// ============================================================================
|
||||
|
||||
function getMainMenuItems() {
|
||||
return [
|
||||
createMenuItem("Player Options", ITEM_TYPE.SUBMENU, { submenu: "player" }),
|
||||
createMenuItem("Network Options", ITEM_TYPE.SUBMENU, { submenu: "network" }),
|
||||
createMenuItem("Vehicle Garage", ITEM_TYPE.SUBMENU, { submenu: "vehicle" }),
|
||||
createMenuItem("Weapon Options", ITEM_TYPE.SUBMENU, { submenu: "weapon" }),
|
||||
createMenuItem("Teleport Options", ITEM_TYPE.SUBMENU, { submenu: "teleport" }),
|
||||
createMenuItem("Weather / Time", ITEM_TYPE.SUBMENU, { submenu: "weather" }),
|
||||
createMenuItem("Model Changer", ITEM_TYPE.SUBMENU, { submenu: "model" }),
|
||||
createMenuItem("Animations", ITEM_TYPE.SUBMENU, { submenu: "animation" }),
|
||||
createMenuItem("Object Spawner", ITEM_TYPE.SUBMENU, { submenu: "objects" }),
|
||||
createMenuItem("~~ M E N U S E T T I N G S ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("Menu Settings", ITEM_TYPE.SUBMENU, { submenu: "settings" }),
|
||||
createMenuItem("~~ C R E D I T S ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("Credits", ITEM_TYPE.SUBMENU, { submenu: "credits" })
|
||||
];
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// DRAWING FUNCTIONS
|
||||
// ============================================================================
|
||||
|
||||
function drawRect(x, y, width, height, r, g, b, a) {
|
||||
natives.DRAW_RECT(x, y, width, height, r, g, b, a);
|
||||
}
|
||||
|
||||
function drawText(text, x, y, size, r, g, b, a, centered = false, rightJustify = false) {
|
||||
natives.SET_TEXT_FONT(0);
|
||||
natives.SET_TEXT_SCALE(size, size);
|
||||
natives.SET_TEXT_COLOUR(r, g, b, a);
|
||||
|
||||
if (centered) {
|
||||
natives.SET_TEXT_CENTRE(true);
|
||||
}
|
||||
if (rightJustify) {
|
||||
natives.SET_TEXT_RIGHT_JUSTIFY(true);
|
||||
natives.SET_TEXT_WRAP(0.0, x);
|
||||
}
|
||||
|
||||
natives.SET_TEXT_DROPSHADOW(0, 0, 0, 0, 255);
|
||||
natives.DISPLAY_TEXT_WITH_LITERAL_STRING(x, y, "STRING", text);
|
||||
}
|
||||
|
||||
function setupDraw(sizeX, sizeY, r, g, b, a) {
|
||||
natives.SET_TEXT_FONT(0);
|
||||
natives.SET_TEXT_SCALE(sizeX, sizeY);
|
||||
natives.SET_TEXT_COLOUR(r, g, b, a);
|
||||
natives.SET_TEXT_DROPSHADOW(0, 0, 0, 0, 255);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// MENU RENDERING
|
||||
// ============================================================================
|
||||
|
||||
function renderMenu() {
|
||||
if (!menuState.isOpen) return;
|
||||
|
||||
updateEffects();
|
||||
|
||||
let posX = MENU_CONFIG.posX;
|
||||
let posY = MENU_CONFIG.posY;
|
||||
let width = MENU_CONFIG.width;
|
||||
|
||||
// Calculate window height based on visible items
|
||||
let visibleCount = Math.min(menuState.items.length, MENU_CONFIG.maxVisibleItems);
|
||||
let windowHeight = MENU_CONFIG.headerHeight + (visibleCount * MENU_CONFIG.itemHeight) + 0.02;
|
||||
|
||||
// Draw background window
|
||||
let bgColor = MENU_CONFIG.colors.background;
|
||||
drawRect(
|
||||
posX + width / 2,
|
||||
posY + windowHeight / 2,
|
||||
width,
|
||||
windowHeight,
|
||||
bgColor[0], bgColor[1], bgColor[2], bgColor[3]
|
||||
);
|
||||
|
||||
// Draw header
|
||||
renderHeader(posX, posY);
|
||||
|
||||
// Draw separator line
|
||||
let lineY = posY + MENU_CONFIG.headerHeight;
|
||||
drawRect(
|
||||
posX + width / 2,
|
||||
lineY,
|
||||
width,
|
||||
0.002,
|
||||
MENU_CONFIG.colors.line[0],
|
||||
MENU_CONFIG.colors.line[1],
|
||||
MENU_CONFIG.colors.line[2],
|
||||
MENU_CONFIG.colors.line[3]
|
||||
);
|
||||
|
||||
// Draw items
|
||||
renderItems(posX, lineY + 0.01);
|
||||
|
||||
// Draw scroll indicators if needed
|
||||
if (menuState.items.length > MENU_CONFIG.maxVisibleItems) {
|
||||
renderScrollIndicators(posX, posY, windowHeight);
|
||||
}
|
||||
|
||||
// Draw helper text at bottom
|
||||
renderHelperText();
|
||||
}
|
||||
|
||||
function renderHeader(x, y) {
|
||||
let headerColor = MENU_CONFIG.colors.header;
|
||||
let subHeaderColor = MENU_CONFIG.colors.subHeader;
|
||||
|
||||
// MD Text (version prefix)
|
||||
setupDraw(0.42, 0.95, subHeaderColor[0], subHeaderColor[1], subHeaderColor[2], 255);
|
||||
natives.DISPLAY_TEXT_WITH_LITERAL_STRING(x + 0.02, y + 0.005, "STRING", MENU_CONFIG.versionText);
|
||||
|
||||
// Header Text (TRIDENT)
|
||||
setupDraw(0.303, 0.45, headerColor[0], headerColor[1], headerColor[2], menuState.flashValue);
|
||||
natives.DISPLAY_TEXT_WITH_LITERAL_STRING(x + 0.055, y + 0.01, "STRING", MENU_CONFIG.headerText);
|
||||
|
||||
// Sub Header (version/description)
|
||||
setupDraw(0.2, 0.32, subHeaderColor[0], subHeaderColor[1], subHeaderColor[2], 255);
|
||||
natives.SET_TEXT_CENTRE(true);
|
||||
natives.DISPLAY_TEXT_WITH_LITERAL_STRING(x + MENU_CONFIG.width / 2, y + 0.04, "STRING", MENU_CONFIG.subHeaderText);
|
||||
}
|
||||
|
||||
function renderItems(startX, startY) {
|
||||
let items = menuState.items;
|
||||
let scrollOffset = menuState.scrollOffset;
|
||||
let selectedIndex = menuState.selectedIndex;
|
||||
|
||||
let visibleCount = Math.min(items.length, MENU_CONFIG.maxVisibleItems);
|
||||
let itemY = startY;
|
||||
|
||||
for (let i = 0; i < visibleCount; i++) {
|
||||
let itemIndex = scrollOffset + i;
|
||||
if (itemIndex >= items.length) break;
|
||||
|
||||
let item = items[itemIndex];
|
||||
let isSelected = (itemIndex === selectedIndex);
|
||||
|
||||
// Draw selection highlight
|
||||
if (isSelected) {
|
||||
drawRect(
|
||||
startX + MENU_CONFIG.width / 2,
|
||||
itemY + MENU_CONFIG.itemHeight / 2,
|
||||
MENU_CONFIG.width,
|
||||
MENU_CONFIG.itemHeight,
|
||||
menuState.glowValue,
|
||||
menuState.glowValue,
|
||||
200,
|
||||
150
|
||||
);
|
||||
}
|
||||
|
||||
// Render item based on type
|
||||
renderItem(item, startX, itemY, isSelected);
|
||||
|
||||
itemY += MENU_CONFIG.itemHeight;
|
||||
}
|
||||
}
|
||||
|
||||
function renderItem(item, x, y, isSelected) {
|
||||
let textX = x + 0.02;
|
||||
let textY = y + 0.003;
|
||||
|
||||
let color;
|
||||
let text = item.name;
|
||||
|
||||
switch (item.type) {
|
||||
case ITEM_TYPE.SUBMENU:
|
||||
color = isSelected ? MENU_CONFIG.colors.itemHighlight : MENU_CONFIG.colors.submenu;
|
||||
setupDraw(0.19, 0.35, color[0], color[1], color[2], 255);
|
||||
natives.DISPLAY_TEXT_WITH_LITERAL_STRING(textX, textY, "STRING", "MD " + text + " >>");
|
||||
break;
|
||||
|
||||
case ITEM_TYPE.FUNCTION:
|
||||
color = isSelected ? MENU_CONFIG.colors.itemHighlight : MENU_CONFIG.colors.item;
|
||||
setupDraw(0.19, 0.35, color[0], color[1], color[2], 255);
|
||||
natives.DISPLAY_TEXT_WITH_LITERAL_STRING(textX, textY, "STRING", text);
|
||||
break;
|
||||
|
||||
case ITEM_TYPE.BOOL:
|
||||
color = item.boolState ? MENU_CONFIG.colors.boolOn : MENU_CONFIG.colors.boolOff;
|
||||
if (isSelected) color = MENU_CONFIG.colors.itemHighlight;
|
||||
setupDraw(0.19, 0.35, color[0], color[1], color[2], 255);
|
||||
natives.DISPLAY_TEXT_WITH_LITERAL_STRING(textX, textY, "STRING", text);
|
||||
|
||||
// Draw ON/OFF indicator
|
||||
let stateText = item.boolState ? "ON" : "OFF";
|
||||
let stateColor = item.boolState ? MENU_CONFIG.colors.boolOn : MENU_CONFIG.colors.boolOff;
|
||||
setupDraw(0.19, 0.35, stateColor[0], stateColor[1], stateColor[2], 255);
|
||||
natives.SET_TEXT_RIGHT_JUSTIFY(true);
|
||||
natives.SET_TEXT_WRAP(0.0, x + MENU_CONFIG.width - 0.02);
|
||||
natives.DISPLAY_TEXT_WITH_LITERAL_STRING(0.0, textY, "STRING", stateText);
|
||||
break;
|
||||
|
||||
case ITEM_TYPE.VALUE_NUM:
|
||||
color = isSelected ? MENU_CONFIG.colors.itemHighlight : MENU_CONFIG.colors.item;
|
||||
setupDraw(0.19, 0.35, color[0], color[1], color[2], 255);
|
||||
natives.DISPLAY_TEXT_WITH_LITERAL_STRING(textX, textY, "STRING", text);
|
||||
|
||||
// Draw value
|
||||
setupDraw(0.19, 0.35, 255, 255, 255, 255);
|
||||
natives.SET_TEXT_RIGHT_JUSTIFY(true);
|
||||
natives.SET_TEXT_WRAP(0.0, x + MENU_CONFIG.width - 0.02);
|
||||
natives.DISPLAY_TEXT_WITH_LITERAL_STRING(0.0, textY, "STRING", "< " + item.value.toString() + " >");
|
||||
break;
|
||||
|
||||
case ITEM_TYPE.VALUE_STRING:
|
||||
color = isSelected ? MENU_CONFIG.colors.itemHighlight : MENU_CONFIG.colors.item;
|
||||
setupDraw(0.19, 0.35, color[0], color[1], color[2], 255);
|
||||
natives.DISPLAY_TEXT_WITH_LITERAL_STRING(textX, textY, "STRING", text);
|
||||
|
||||
// Draw string value
|
||||
let strValue = item.stringValues[item.value] || "None";
|
||||
setupDraw(0.19, 0.35, 255, 255, 255, 255);
|
||||
natives.SET_TEXT_RIGHT_JUSTIFY(true);
|
||||
natives.SET_TEXT_WRAP(0.0, x + MENU_CONFIG.width - 0.02);
|
||||
natives.DISPLAY_TEXT_WITH_LITERAL_STRING(0.0, textY, "STRING", "< " + strValue + " >");
|
||||
break;
|
||||
|
||||
case ITEM_TYPE.VEHICLE:
|
||||
color = isSelected ? MENU_CONFIG.colors.itemHighlight : MENU_CONFIG.colors.item;
|
||||
setupDraw(0.19, 0.35, color[0], color[1], color[2], 255);
|
||||
// Get vehicle display name
|
||||
let vehName = natives.GET_DISPLAY_NAME_FROM_VEHICLE_MODEL(item.vehicleModel);
|
||||
let displayName = natives.GET_STRING_FROM_TEXT_FILE(vehName) || text;
|
||||
natives.DISPLAY_TEXT_WITH_LITERAL_STRING(textX, textY, "STRING", displayName);
|
||||
break;
|
||||
|
||||
case ITEM_TYPE.PLAYER:
|
||||
// Get player color
|
||||
let playerColor = getPlayerColor(item.playerId);
|
||||
if (isSelected) playerColor = MENU_CONFIG.colors.itemHighlight;
|
||||
setupDraw(0.19, 0.35, playerColor[0], playerColor[1], playerColor[2], 255);
|
||||
natives.DISPLAY_TEXT_WITH_LITERAL_STRING(textX, textY, "STRING", text);
|
||||
break;
|
||||
|
||||
case ITEM_TYPE.JUMPOVER:
|
||||
color = MENU_CONFIG.colors.jumpover;
|
||||
setupDraw(0.21, 0.385, color[0], color[1], color[2], menuState.flashValue);
|
||||
natives.SET_TEXT_CENTRE(true);
|
||||
natives.DISPLAY_TEXT_WITH_LITERAL_STRING(x + MENU_CONFIG.width / 2, textY, "STRING", text);
|
||||
break;
|
||||
|
||||
case ITEM_TYPE.ERROR:
|
||||
color = MENU_CONFIG.colors.error;
|
||||
setupDraw(0.19, 0.35, color[0], color[1], menuState.glowValue, 255);
|
||||
natives.DISPLAY_TEXT_WITH_LITERAL_STRING(textX, textY, "STRING", text);
|
||||
break;
|
||||
|
||||
case ITEM_TYPE.NOT_PRESENT:
|
||||
color = MENU_CONFIG.colors.error;
|
||||
setupDraw(0.19, 0.35, color[0], menuState.glowValue, menuState.glowValue, 255);
|
||||
natives.DISPLAY_TEXT_WITH_LITERAL_STRING(textX, textY, "STRING", text + " (N/A)");
|
||||
break;
|
||||
|
||||
default:
|
||||
color = MENU_CONFIG.colors.item;
|
||||
setupDraw(0.19, 0.35, color[0], color[1], color[2], 255);
|
||||
natives.DISPLAY_TEXT_WITH_LITERAL_STRING(textX, textY, "STRING", text);
|
||||
}
|
||||
}
|
||||
|
||||
function renderScrollIndicators(x, y, height) {
|
||||
// Draw scroll position indicator
|
||||
let totalItems = menuState.items.length;
|
||||
let visibleItems = MENU_CONFIG.maxVisibleItems;
|
||||
let scrollOffset = menuState.scrollOffset;
|
||||
|
||||
let scrollBarHeight = height - MENU_CONFIG.headerHeight - 0.04;
|
||||
let scrollThumbHeight = (visibleItems / totalItems) * scrollBarHeight;
|
||||
let scrollThumbY = y + MENU_CONFIG.headerHeight + 0.02 + (scrollOffset / (totalItems - visibleItems)) * (scrollBarHeight - scrollThumbHeight);
|
||||
|
||||
// Draw scroll track
|
||||
drawRect(
|
||||
x + MENU_CONFIG.width - 0.008,
|
||||
y + MENU_CONFIG.headerHeight + scrollBarHeight / 2,
|
||||
0.004,
|
||||
scrollBarHeight,
|
||||
50, 50, 50, 150
|
||||
);
|
||||
|
||||
// Draw scroll thumb
|
||||
drawRect(
|
||||
x + MENU_CONFIG.width - 0.008,
|
||||
scrollThumbY + scrollThumbHeight / 2,
|
||||
0.004,
|
||||
scrollThumbHeight,
|
||||
MENU_CONFIG.colors.header[0],
|
||||
MENU_CONFIG.colors.header[1],
|
||||
MENU_CONFIG.colors.header[2],
|
||||
255
|
||||
);
|
||||
}
|
||||
|
||||
function renderHelperText() {
|
||||
let y = 0.92;
|
||||
|
||||
setupDraw(0.15, 0.28, 255, 255, 255, 200);
|
||||
|
||||
if (menuState.currentLevel === 0) {
|
||||
natives.DISPLAY_TEXT_WITH_LITERAL_STRING(0.3, y, "STRING", "UP/DOWN: Navigate | ENTER: Select | BACKSPACE: Close");
|
||||
} else {
|
||||
natives.DISPLAY_TEXT_WITH_LITERAL_STRING(0.3, y, "STRING", "UP/DOWN: Navigate | ENTER: Select | BACKSPACE: Back");
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// MENU EFFECTS
|
||||
// ============================================================================
|
||||
|
||||
function updateEffects() {
|
||||
// Glow effect
|
||||
if (menuState.glowIncrement) {
|
||||
menuState.glowValue += 3;
|
||||
if (menuState.glowValue >= 190) {
|
||||
menuState.glowIncrement = false;
|
||||
}
|
||||
} else {
|
||||
menuState.glowValue -= 3;
|
||||
if (menuState.glowValue <= 0) {
|
||||
menuState.glowIncrement = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Flash effect
|
||||
if (menuState.flashIncrement) {
|
||||
menuState.flashValue += 3;
|
||||
if (menuState.flashValue >= 255) {
|
||||
menuState.flashIncrement = false;
|
||||
}
|
||||
} else {
|
||||
menuState.flashValue -= 2;
|
||||
if (menuState.flashValue <= 150) {
|
||||
menuState.flashIncrement = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// MENU INPUT HANDLING
|
||||
// ============================================================================
|
||||
|
||||
function handleMenuInput() {
|
||||
if (menuState.inputCooldown > 0) {
|
||||
menuState.inputCooldown--;
|
||||
}
|
||||
|
||||
// Open/Close menu with specific key combo (F5 or Insert)
|
||||
if (natives.IS_GAME_KEYBOARD_KEY_JUST_PRESSED(0x74) || // F5
|
||||
natives.IS_GAME_KEYBOARD_KEY_JUST_PRESSED(0x2D)) { // Insert
|
||||
toggleMenu();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!menuState.isOpen) return;
|
||||
|
||||
// Navigation
|
||||
if (isInputPressed("up")) {
|
||||
navigateUp();
|
||||
}
|
||||
if (isInputPressed("down")) {
|
||||
navigateDown();
|
||||
}
|
||||
if (isInputPressed("left")) {
|
||||
adjustValue(-1);
|
||||
}
|
||||
if (isInputPressed("right")) {
|
||||
adjustValue(1);
|
||||
}
|
||||
|
||||
// Selection
|
||||
if (isInputJustPressed("select")) {
|
||||
selectItem();
|
||||
menuState.inputCooldown = 8;
|
||||
}
|
||||
|
||||
// Back
|
||||
if (isInputJustPressed("back")) {
|
||||
goBack();
|
||||
menuState.inputCooldown = 8;
|
||||
}
|
||||
}
|
||||
|
||||
function isInputPressed(action) {
|
||||
let pressed = false;
|
||||
let justPressed = false;
|
||||
|
||||
switch (action) {
|
||||
case "up":
|
||||
pressed = natives.IS_GAME_KEYBOARD_KEY_PRESSED(0x26) || // UP Arrow
|
||||
natives.IS_BUTTON_PRESSED(0, 1); // DPAD UP
|
||||
justPressed = natives.IS_GAME_KEYBOARD_KEY_JUST_PRESSED(0x26) ||
|
||||
natives.IS_BUTTON_JUST_PRESSED(0, 1);
|
||||
break;
|
||||
case "down":
|
||||
pressed = natives.IS_GAME_KEYBOARD_KEY_PRESSED(0x28) || // DOWN Arrow
|
||||
natives.IS_BUTTON_PRESSED(0, 2); // DPAD DOWN
|
||||
justPressed = natives.IS_GAME_KEYBOARD_KEY_JUST_PRESSED(0x28) ||
|
||||
natives.IS_BUTTON_JUST_PRESSED(0, 2);
|
||||
break;
|
||||
case "left":
|
||||
pressed = natives.IS_GAME_KEYBOARD_KEY_PRESSED(0x25) || // LEFT Arrow
|
||||
natives.IS_BUTTON_PRESSED(0, 3); // DPAD LEFT
|
||||
justPressed = natives.IS_GAME_KEYBOARD_KEY_JUST_PRESSED(0x25) ||
|
||||
natives.IS_BUTTON_JUST_PRESSED(0, 3);
|
||||
break;
|
||||
case "right":
|
||||
pressed = natives.IS_GAME_KEYBOARD_KEY_PRESSED(0x27) || // RIGHT Arrow
|
||||
natives.IS_BUTTON_PRESSED(0, 4); // DPAD RIGHT
|
||||
justPressed = natives.IS_GAME_KEYBOARD_KEY_JUST_PRESSED(0x27) ||
|
||||
natives.IS_BUTTON_JUST_PRESSED(0, 4);
|
||||
break;
|
||||
}
|
||||
|
||||
// Handle press with repeat
|
||||
if (justPressed) {
|
||||
menuState.holdCounter = 0;
|
||||
menuState.pressCounter = 2;
|
||||
menuState.pressMultiplier = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pressed && menuState.inputCooldown === 0) {
|
||||
menuState.holdCounter++;
|
||||
if (menuState.holdCounter > 15) {
|
||||
menuState.pressCounter++;
|
||||
menuState.pressCounter *= menuState.pressMultiplier;
|
||||
|
||||
if (menuState.holdCounter > 40) {
|
||||
menuState.pressMultiplier = 2;
|
||||
menuState.holdCounter = 16;
|
||||
}
|
||||
|
||||
if (menuState.pressCounter > 6) {
|
||||
menuState.inputCooldown = 3;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (!pressed) {
|
||||
menuState.holdCounter = 0;
|
||||
menuState.pressMultiplier = 1;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function isInputJustPressed(action) {
|
||||
switch (action) {
|
||||
case "select":
|
||||
return natives.IS_GAME_KEYBOARD_KEY_JUST_PRESSED(0x0D) || // Enter
|
||||
natives.IS_BUTTON_JUST_PRESSED(0, 16); // A button
|
||||
case "back":
|
||||
return natives.IS_GAME_KEYBOARD_KEY_JUST_PRESSED(0x08) || // Backspace
|
||||
natives.IS_BUTTON_JUST_PRESSED(0, 32); // B button
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// MENU NAVIGATION
|
||||
// ============================================================================
|
||||
|
||||
function toggleMenu() {
|
||||
menuState.isOpen = !menuState.isOpen;
|
||||
|
||||
if (menuState.isOpen) {
|
||||
openMenu();
|
||||
} else {
|
||||
closeMenu();
|
||||
}
|
||||
}
|
||||
|
||||
function openMenu() {
|
||||
menuState.isOpen = true;
|
||||
menuState.currentLevel = 0;
|
||||
menuState.items = getMainMenuItems();
|
||||
menuState.selectedIndex = 0;
|
||||
menuState.scrollOffset = 0;
|
||||
menuState.menuStack = [];
|
||||
menuState.lastSelected = [];
|
||||
|
||||
// Block weapon switching while menu is open
|
||||
let playerPed = natives.GET_PLAYER_PED(natives.GET_PLAYER_ID());
|
||||
natives.BLOCK_PED_WEAPON_SWITCHING(playerPed, true);
|
||||
|
||||
// Play open sound
|
||||
natives.PLAY_AUDIO_EVENT("FRONTEND_MENU_MP_READY");
|
||||
|
||||
// Notification
|
||||
showNotification("~b~MD TRIDENT ~s~Menu Opened");
|
||||
}
|
||||
|
||||
function closeMenu() {
|
||||
menuState.isOpen = false;
|
||||
|
||||
// Unblock weapon switching
|
||||
let playerPed = natives.GET_PLAYER_PED(natives.GET_PLAYER_ID());
|
||||
natives.BLOCK_PED_WEAPON_SWITCHING(playerPed, false);
|
||||
|
||||
// Play close sound
|
||||
natives.PLAY_AUDIO_EVENT("FRONTEND_MENU_MP_UNREADY");
|
||||
}
|
||||
|
||||
function navigateUp() {
|
||||
// Skip jumpover items
|
||||
do {
|
||||
if (menuState.selectedIndex === 0) {
|
||||
menuState.selectedIndex = menuState.items.length - 1;
|
||||
// Adjust scroll for wrap-around
|
||||
if (menuState.items.length > MENU_CONFIG.maxVisibleItems) {
|
||||
menuState.scrollOffset = menuState.items.length - MENU_CONFIG.maxVisibleItems;
|
||||
}
|
||||
} else {
|
||||
menuState.selectedIndex--;
|
||||
// Adjust scroll
|
||||
if (menuState.selectedIndex < menuState.scrollOffset) {
|
||||
menuState.scrollOffset = menuState.selectedIndex;
|
||||
}
|
||||
}
|
||||
} while (menuState.items[menuState.selectedIndex].type === ITEM_TYPE.JUMPOVER);
|
||||
|
||||
natives.PLAY_AUDIO_EVENT("RADIO_RETUNE_BEEP");
|
||||
}
|
||||
|
||||
function navigateDown() {
|
||||
// Skip jumpover items
|
||||
do {
|
||||
if (menuState.selectedIndex === menuState.items.length - 1) {
|
||||
menuState.selectedIndex = 0;
|
||||
menuState.scrollOffset = 0;
|
||||
} else {
|
||||
menuState.selectedIndex++;
|
||||
// Adjust scroll
|
||||
if (menuState.selectedIndex >= menuState.scrollOffset + MENU_CONFIG.maxVisibleItems) {
|
||||
menuState.scrollOffset = menuState.selectedIndex - MENU_CONFIG.maxVisibleItems + 1;
|
||||
}
|
||||
}
|
||||
} while (menuState.items[menuState.selectedIndex].type === ITEM_TYPE.JUMPOVER);
|
||||
|
||||
natives.PLAY_AUDIO_EVENT("RADIO_RETUNE_BEEP");
|
||||
}
|
||||
|
||||
function adjustValue(delta) {
|
||||
let item = menuState.items[menuState.selectedIndex];
|
||||
|
||||
if (item.type === ITEM_TYPE.VALUE_NUM) {
|
||||
item.value += delta;
|
||||
if (item.value > item.maxValue) item.value = item.minValue;
|
||||
if (item.value < item.minValue) item.value = item.maxValue;
|
||||
natives.PLAY_AUDIO_EVENT("RADIO_RETUNE_BEEP");
|
||||
} else if (item.type === ITEM_TYPE.VALUE_STRING) {
|
||||
item.value += delta;
|
||||
if (item.value >= item.stringValues.length) item.value = 0;
|
||||
if (item.value < 0) item.value = item.stringValues.length - 1;
|
||||
natives.PLAY_AUDIO_EVENT("RADIO_RETUNE_BEEP");
|
||||
}
|
||||
}
|
||||
|
||||
function selectItem() {
|
||||
let item = menuState.items[menuState.selectedIndex];
|
||||
|
||||
if (item.type === ITEM_TYPE.JUMPOVER || item.type === ITEM_TYPE.NOT_PRESENT) {
|
||||
return;
|
||||
}
|
||||
|
||||
natives.PLAY_AUDIO_EVENT("FRONTEND_MENU_MP_SERVER_HIGHLIGHT");
|
||||
|
||||
if (item.type === ITEM_TYPE.SUBMENU) {
|
||||
// Save current state
|
||||
menuState.menuStack.push({
|
||||
items: menuState.items,
|
||||
selectedIndex: menuState.selectedIndex,
|
||||
scrollOffset: menuState.scrollOffset
|
||||
});
|
||||
|
||||
// Load submenu
|
||||
menuState.items = getSubmenuItems(item.submenu);
|
||||
menuState.selectedIndex = 0;
|
||||
menuState.scrollOffset = 0;
|
||||
menuState.currentLevel++;
|
||||
|
||||
} else if (item.type === ITEM_TYPE.BOOL) {
|
||||
item.boolState = !item.boolState;
|
||||
if (item.action) {
|
||||
item.action(item.boolState);
|
||||
}
|
||||
|
||||
} else if (item.type === ITEM_TYPE.FUNCTION) {
|
||||
if (item.action) {
|
||||
item.action();
|
||||
}
|
||||
|
||||
} else if (item.type === ITEM_TYPE.VALUE_NUM || item.type === ITEM_TYPE.VALUE_STRING) {
|
||||
if (item.action) {
|
||||
item.action(item.value);
|
||||
}
|
||||
|
||||
} else if (item.type === ITEM_TYPE.VEHICLE) {
|
||||
if (item.action) {
|
||||
item.action(item.vehicleModel);
|
||||
} else {
|
||||
spawnVehicle(item.vehicleModel);
|
||||
}
|
||||
|
||||
} else if (item.type === ITEM_TYPE.PLAYER) {
|
||||
menuState.selectedPlayer = item.playerId;
|
||||
if (item.action) {
|
||||
item.action(item.playerId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function goBack() {
|
||||
if (menuState.currentLevel === 0) {
|
||||
closeMenu();
|
||||
return;
|
||||
}
|
||||
|
||||
// Restore previous state
|
||||
let prevState = menuState.menuStack.pop();
|
||||
if (prevState) {
|
||||
menuState.items = prevState.items;
|
||||
menuState.selectedIndex = prevState.selectedIndex;
|
||||
menuState.scrollOffset = prevState.scrollOffset;
|
||||
menuState.currentLevel--;
|
||||
}
|
||||
|
||||
natives.PLAY_AUDIO_EVENT("RADIO_RETUNE_BEEP");
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// SUBMENU DEFINITIONS
|
||||
// ============================================================================
|
||||
|
||||
function getSubmenuItems(submenuId) {
|
||||
switch (submenuId) {
|
||||
case "player":
|
||||
return getPlayerMenuItems();
|
||||
case "network":
|
||||
return getNetworkMenuItems();
|
||||
case "vehicle":
|
||||
return getVehicleMenuItems();
|
||||
case "weapon":
|
||||
return getWeaponMenuItems();
|
||||
case "teleport":
|
||||
return getTeleportMenuItems();
|
||||
case "weather":
|
||||
return getWeatherMenuItems();
|
||||
case "model":
|
||||
return getModelMenuItems();
|
||||
case "animation":
|
||||
return getAnimationMenuItems();
|
||||
case "objects":
|
||||
return getObjectMenuItems();
|
||||
case "settings":
|
||||
return getSettingsMenuItems();
|
||||
case "credits":
|
||||
return getCreditsMenuItems();
|
||||
// Vehicle sub-categories
|
||||
case "vehicle_sports":
|
||||
return getSportsVehicleItems();
|
||||
case "vehicle_muscle":
|
||||
return getMuscleVehicleItems();
|
||||
case "vehicle_suv":
|
||||
return getSUVVehicleItems();
|
||||
case "vehicle_sedan":
|
||||
return getSedanVehicleItems();
|
||||
case "vehicle_emergency":
|
||||
return getEmergencyVehicleItems();
|
||||
case "vehicle_bikes":
|
||||
return getBikeVehicleItems();
|
||||
case "vehicle_boats":
|
||||
return getBoatVehicleItems();
|
||||
case "vehicle_helicopters":
|
||||
return getHelicopterVehicleItems();
|
||||
default:
|
||||
return [createMenuItem("Not Implemented", ITEM_TYPE.ERROR)];
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// UTILITY FUNCTIONS
|
||||
// ============================================================================
|
||||
|
||||
function showNotification(text) {
|
||||
natives.PRINT_STRING_WITH_LITERAL_STRING_NOW("STRING", text, 3000, true);
|
||||
}
|
||||
|
||||
function getPlayerColor(playerId) {
|
||||
let r = 255, g = 255, b = 255;
|
||||
// Try to get player color
|
||||
try {
|
||||
let result = natives.GET_PLAYER_RGB_COLOUR(playerId);
|
||||
if (result) {
|
||||
r = result[0] || 255;
|
||||
g = result[1] || 255;
|
||||
b = result[2] || 255;
|
||||
}
|
||||
} catch (e) {
|
||||
// Default white if failed
|
||||
}
|
||||
return [r, g, b, 255];
|
||||
}
|
||||
|
||||
function spawnVehicle(modelHash) {
|
||||
// Get player position and heading
|
||||
let playerId = natives.GET_PLAYER_ID();
|
||||
let playerPed = natives.GET_PLAYER_PED(playerId);
|
||||
|
||||
let pos = natives.GET_CHAR_COORDINATES(playerPed);
|
||||
let heading = natives.GET_CHAR_HEADING(playerPed);
|
||||
|
||||
// Request model
|
||||
natives.REQUEST_MODEL(modelHash);
|
||||
|
||||
// Wait for model to load (simplified - actual implementation should use async)
|
||||
let attempts = 0;
|
||||
while (!natives.HAS_MODEL_LOADED(modelHash) && attempts < 100) {
|
||||
natives.WAIT(10);
|
||||
attempts++;
|
||||
}
|
||||
|
||||
if (!natives.HAS_MODEL_LOADED(modelHash)) {
|
||||
showNotification("~r~Failed to load vehicle model!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Create vehicle in front of player
|
||||
let spawnX = pos[0] + Math.sin(heading * Math.PI / 180) * 5;
|
||||
let spawnY = pos[1] + Math.cos(heading * Math.PI / 180) * 5;
|
||||
let spawnZ = pos[2];
|
||||
|
||||
let vehicle = natives.CREATE_CAR(modelHash, spawnX, spawnY, spawnZ, true, true);
|
||||
|
||||
if (vehicle) {
|
||||
natives.SET_CAR_HEADING(vehicle, heading);
|
||||
natives.SET_CAR_ON_GROUND_PROPERLY(vehicle);
|
||||
showNotification("~g~Vehicle spawned!");
|
||||
}
|
||||
|
||||
// Mark model as no longer needed
|
||||
natives.MARK_MODEL_AS_NO_LONGER_NEEDED(modelHash);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// EVENT HANDLERS
|
||||
// ============================================================================
|
||||
|
||||
addEventHandler("OnProcess", function(event) {
|
||||
handleMenuInput();
|
||||
});
|
||||
|
||||
addEventHandler("OnDrawnHUD", function(event) {
|
||||
renderMenu();
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
// EXPORTS
|
||||
// ============================================================================
|
||||
|
||||
// Export menu state and functions for other scripts
|
||||
this.menuState = menuState;
|
||||
this.showNotification = showNotification;
|
||||
this.createMenuItem = createMenuItem;
|
||||
this.ITEM_TYPE = ITEM_TYPE;
|
||||
this.toggleMenu = toggleMenu;
|
||||
508
Trident/player.js
Normal file
508
Trident/player.js
Normal file
@@ -0,0 +1,508 @@
|
||||
/**
|
||||
* MD TRIDENT - Player Options Module
|
||||
* GTAConnected Port for GTA IV
|
||||
*/
|
||||
|
||||
// ============================================================================
|
||||
// PLAYER OPTIONS STATE
|
||||
// ============================================================================
|
||||
|
||||
let playerOptions = {
|
||||
godmode: false,
|
||||
neverWanted: false,
|
||||
infiniteAmmo: false,
|
||||
superRun: false,
|
||||
superJump: false,
|
||||
superPunch: false,
|
||||
invisible: false,
|
||||
flyMode: false,
|
||||
inferno: false,
|
||||
forceField: false,
|
||||
juggernaut: false,
|
||||
rapidFire: false,
|
||||
autoAim: false,
|
||||
gravity: true,
|
||||
slowMotion: false
|
||||
};
|
||||
|
||||
// Fly mode state
|
||||
let flyModeState = {
|
||||
active: false,
|
||||
camera: null,
|
||||
pitch: 0,
|
||||
speed: 1.0
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// PLAYER MENU ITEMS
|
||||
// ============================================================================
|
||||
|
||||
function getPlayerMenuItems() {
|
||||
let playerId = natives.GET_PLAYER_ID();
|
||||
let playerPed = natives.GET_PLAYER_PED(playerId);
|
||||
|
||||
return [
|
||||
createMenuItem("~~ PLAYER PROTECTION ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("God Mode", ITEM_TYPE.BOOL, {
|
||||
boolState: playerOptions.godmode,
|
||||
action: toggleGodMode
|
||||
}),
|
||||
createMenuItem("Juggernaut (Auto Health/Armor)", ITEM_TYPE.BOOL, {
|
||||
boolState: playerOptions.juggernaut,
|
||||
action: toggleJuggernaut
|
||||
}),
|
||||
createMenuItem("Never Wanted", ITEM_TYPE.BOOL, {
|
||||
boolState: playerOptions.neverWanted,
|
||||
action: toggleNeverWanted
|
||||
}),
|
||||
|
||||
createMenuItem("~~ PLAYER ABILITIES ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("Super Run", ITEM_TYPE.BOOL, {
|
||||
boolState: playerOptions.superRun,
|
||||
action: toggleSuperRun
|
||||
}),
|
||||
createMenuItem("Super Jump", ITEM_TYPE.BOOL, {
|
||||
boolState: playerOptions.superJump,
|
||||
action: toggleSuperJump
|
||||
}),
|
||||
createMenuItem("Super Punch", ITEM_TYPE.BOOL, {
|
||||
boolState: playerOptions.superPunch,
|
||||
action: toggleSuperPunch
|
||||
}),
|
||||
createMenuItem("Fly Mode", ITEM_TYPE.BOOL, {
|
||||
boolState: playerOptions.flyMode,
|
||||
action: toggleFlyMode
|
||||
}),
|
||||
|
||||
createMenuItem("~~ PLAYER EFFECTS ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("Invisible", ITEM_TYPE.BOOL, {
|
||||
boolState: playerOptions.invisible,
|
||||
action: toggleInvisible
|
||||
}),
|
||||
createMenuItem("Inferno Mode", ITEM_TYPE.BOOL, {
|
||||
boolState: playerOptions.inferno,
|
||||
action: toggleInferno
|
||||
}),
|
||||
createMenuItem("Force Field", ITEM_TYPE.BOOL, {
|
||||
boolState: playerOptions.forceField,
|
||||
action: toggleForceField
|
||||
}),
|
||||
|
||||
createMenuItem("~~ PLAYER PHYSICS ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("Normal Gravity", ITEM_TYPE.BOOL, {
|
||||
boolState: playerOptions.gravity,
|
||||
action: toggleGravity
|
||||
}),
|
||||
createMenuItem("Slow Motion", ITEM_TYPE.BOOL, {
|
||||
boolState: playerOptions.slowMotion,
|
||||
action: toggleSlowMotion
|
||||
}),
|
||||
|
||||
createMenuItem("~~ PLAYER ACTIONS ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("Give Health", ITEM_TYPE.FUNCTION, { action: giveHealth }),
|
||||
createMenuItem("Give Armor", ITEM_TYPE.FUNCTION, { action: giveArmor }),
|
||||
createMenuItem("Give All Weapons", ITEM_TYPE.FUNCTION, { action: giveAllWeapons }),
|
||||
createMenuItem("Remove All Weapons", ITEM_TYPE.FUNCTION, { action: removeAllWeapons }),
|
||||
createMenuItem("Spawn Money", ITEM_TYPE.FUNCTION, { action: spawnMoney }),
|
||||
createMenuItem("Fix Player", ITEM_TYPE.FUNCTION, { action: fixPlayer }),
|
||||
createMenuItem("Change to Niko", ITEM_TYPE.FUNCTION, { action: changeToNiko }),
|
||||
createMenuItem("Explode Self", ITEM_TYPE.FUNCTION, { action: explodeSelf }),
|
||||
createMenuItem("Resurrect", ITEM_TYPE.FUNCTION, { action: resurrectPlayer }),
|
||||
|
||||
createMenuItem("~~ WANTED LEVEL ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("Set Wanted Level", ITEM_TYPE.VALUE_NUM, {
|
||||
value: 0,
|
||||
minValue: 0,
|
||||
maxValue: 6,
|
||||
action: setWantedLevel
|
||||
}),
|
||||
createMenuItem("Clear Wanted Level", ITEM_TYPE.FUNCTION, { action: clearWantedLevel })
|
||||
];
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// TOGGLE FUNCTIONS
|
||||
// ============================================================================
|
||||
|
||||
function toggleGodMode(state) {
|
||||
playerOptions.godmode = state;
|
||||
let playerId = natives.GET_PLAYER_ID();
|
||||
let playerPed = natives.GET_PLAYER_PED(playerId);
|
||||
|
||||
natives.SET_CHAR_INVINCIBLE(playerPed, state);
|
||||
natives.SET_PLAYER_NEVER_GETS_TIRED(playerId, state);
|
||||
natives.SET_PLAYER_FAST_RELOAD(playerId, state);
|
||||
natives.SET_CHAR_NEVER_TARGETTED(playerPed, state);
|
||||
natives.ENABLE_MAX_AMMO_CAP(!state);
|
||||
|
||||
showNotification(state ? "~g~God Mode ~s~ON" : "~r~God Mode ~s~OFF");
|
||||
}
|
||||
|
||||
function toggleJuggernaut(state) {
|
||||
playerOptions.juggernaut = state;
|
||||
showNotification(state ? "~g~Juggernaut ~s~ON" : "~r~Juggernaut ~s~OFF");
|
||||
}
|
||||
|
||||
function toggleNeverWanted(state) {
|
||||
playerOptions.neverWanted = state;
|
||||
if (state) {
|
||||
natives.CLEAR_WANTED_LEVEL(natives.GET_PLAYER_ID());
|
||||
}
|
||||
showNotification(state ? "~g~Never Wanted ~s~ON" : "~r~Never Wanted ~s~OFF");
|
||||
}
|
||||
|
||||
function toggleSuperRun(state) {
|
||||
playerOptions.superRun = state;
|
||||
showNotification(state ? "~g~Super Run ~s~ON (Hold LB/RB + A)" : "~r~Super Run ~s~OFF");
|
||||
}
|
||||
|
||||
function toggleSuperJump(state) {
|
||||
playerOptions.superJump = state;
|
||||
showNotification(state ? "~g~Super Jump ~s~ON (Hold LB/RB + X)" : "~r~Super Jump ~s~OFF");
|
||||
}
|
||||
|
||||
function toggleSuperPunch(state) {
|
||||
playerOptions.superPunch = state;
|
||||
showNotification(state ? "~g~Super Punch ~s~ON (Hold LB + B)" : "~r~Super Punch ~s~OFF");
|
||||
}
|
||||
|
||||
function toggleFlyMode(state) {
|
||||
playerOptions.flyMode = state;
|
||||
flyModeState.active = state;
|
||||
|
||||
let playerId = natives.GET_PLAYER_ID();
|
||||
let playerPed = natives.GET_PLAYER_PED(playerId);
|
||||
|
||||
if (state) {
|
||||
// Create fly mode camera
|
||||
flyModeState.camera = natives.CREATE_CAM(14);
|
||||
natives.SET_CAM_ACTIVE(flyModeState.camera, true);
|
||||
natives.SET_CAM_PROPAGATE(flyModeState.camera, true);
|
||||
natives.ACTIVATE_SCRIPTED_CAMS(true, true);
|
||||
natives.ATTACH_CAM_TO_PED(flyModeState.camera, playerPed);
|
||||
natives.POINT_CAM_AT_PED(flyModeState.camera, playerPed);
|
||||
flyModeState.pitch = 0;
|
||||
showNotification("~g~Fly Mode ~s~ON");
|
||||
} else {
|
||||
// Destroy fly mode camera
|
||||
if (flyModeState.camera) {
|
||||
natives.SET_CAM_ACTIVE(flyModeState.camera, false);
|
||||
natives.SET_CAM_PROPAGATE(flyModeState.camera, false);
|
||||
natives.ACTIVATE_SCRIPTED_CAMS(false, false);
|
||||
natives.DESTROY_CAM(flyModeState.camera);
|
||||
flyModeState.camera = null;
|
||||
}
|
||||
natives.FREEZE_CHAR_POSITION(playerPed, false);
|
||||
showNotification("~r~Fly Mode ~s~OFF");
|
||||
}
|
||||
}
|
||||
|
||||
function toggleInvisible(state) {
|
||||
playerOptions.invisible = state;
|
||||
let playerPed = natives.GET_PLAYER_PED(natives.GET_PLAYER_ID());
|
||||
natives.SET_CHAR_VISIBLE(playerPed, !state);
|
||||
showNotification(state ? "~g~Invisible ~s~ON" : "~r~Invisible ~s~OFF");
|
||||
}
|
||||
|
||||
function toggleInferno(state) {
|
||||
playerOptions.inferno = state;
|
||||
showNotification(state ? "~g~Inferno Mode ~s~ON" : "~r~Inferno Mode ~s~OFF");
|
||||
}
|
||||
|
||||
function toggleForceField(state) {
|
||||
playerOptions.forceField = state;
|
||||
if (state && !playerOptions.godmode) {
|
||||
toggleGodMode(true);
|
||||
showNotification("~y~God Mode auto-enabled for Force Field");
|
||||
}
|
||||
showNotification(state ? "~g~Force Field ~s~ON" : "~r~Force Field ~s~OFF");
|
||||
}
|
||||
|
||||
function toggleGravity(state) {
|
||||
playerOptions.gravity = state;
|
||||
natives.SET_GRAVITY_OFF(!state);
|
||||
showNotification(state ? "~g~Gravity ~s~ON" : "~r~Gravity ~s~OFF");
|
||||
}
|
||||
|
||||
function toggleSlowMotion(state) {
|
||||
playerOptions.slowMotion = state;
|
||||
natives.SET_TIME_SCALE(state ? 0.3 : 1.0);
|
||||
showNotification(state ? "~g~Slow Motion ~s~ON" : "~r~Slow Motion ~s~OFF");
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ACTION FUNCTIONS
|
||||
// ============================================================================
|
||||
|
||||
function giveHealth() {
|
||||
let playerPed = natives.GET_PLAYER_PED(natives.GET_PLAYER_ID());
|
||||
natives.SET_CHAR_HEALTH(playerPed, 200);
|
||||
showNotification("~g~Health restored!");
|
||||
}
|
||||
|
||||
function giveArmor() {
|
||||
let playerPed = natives.GET_PLAYER_PED(natives.GET_PLAYER_ID());
|
||||
natives.ADD_ARMOUR_TO_CHAR(playerPed, 100);
|
||||
showNotification("~g~Armor added!");
|
||||
}
|
||||
|
||||
function giveAllWeapons() {
|
||||
let playerPed = natives.GET_PLAYER_PED(natives.GET_PLAYER_ID());
|
||||
let episode = natives.GET_CURRENT_EPISODE();
|
||||
natives.GIVE_EPISODIC_WEAPONS_TO_CHAR(playerPed, episode);
|
||||
showNotification("~g~All weapons given!");
|
||||
}
|
||||
|
||||
function removeAllWeapons() {
|
||||
let playerPed = natives.GET_PLAYER_PED(natives.GET_PLAYER_ID());
|
||||
natives.REMOVE_ALL_CHAR_WEAPONS(playerPed);
|
||||
showNotification("~r~All weapons removed!");
|
||||
}
|
||||
|
||||
function spawnMoney() {
|
||||
let playerPed = natives.GET_PLAYER_PED(natives.GET_PLAYER_ID());
|
||||
for (let i = 0; i < 4; i++) {
|
||||
natives.GIVE_CASH_PICKUP_TO_CHAR(playerPed, 10000);
|
||||
}
|
||||
showNotification("~g~Money spawned around you!");
|
||||
}
|
||||
|
||||
function fixPlayer() {
|
||||
let playerId = natives.GET_PLAYER_ID();
|
||||
let playerPed = natives.GET_PLAYER_PED(playerId);
|
||||
|
||||
natives.SET_CHAR_HEALTH(playerPed, 200);
|
||||
natives.ADD_ARMOUR_TO_CHAR(playerPed, 100);
|
||||
natives.CLEAR_CHAR_TASKS(playerPed);
|
||||
natives.CLEAR_CHAR_TASKS_IMMEDIATELY(playerPed);
|
||||
|
||||
showNotification("~g~Player fixed!");
|
||||
}
|
||||
|
||||
function changeToNiko() {
|
||||
let playerId = natives.GET_PLAYER_ID();
|
||||
let playerPed = natives.GET_PLAYER_PED(playerId);
|
||||
|
||||
// MODEL_PLAYER is Niko's model hash
|
||||
let nikoModel = natives.GET_HASH_KEY("PLAYER");
|
||||
natives.REQUEST_MODEL(nikoModel);
|
||||
|
||||
let attempts = 0;
|
||||
while (!natives.HAS_MODEL_LOADED(nikoModel) && attempts < 100) {
|
||||
natives.WAIT(10);
|
||||
attempts++;
|
||||
}
|
||||
|
||||
if (natives.HAS_MODEL_LOADED(nikoModel)) {
|
||||
natives.CHANGE_PLAYER_MODEL(playerId, nikoModel);
|
||||
natives.SET_CHAR_HEALTH(playerPed, 200);
|
||||
natives.ADD_ARMOUR_TO_CHAR(playerPed, 100);
|
||||
natives.MARK_MODEL_AS_NO_LONGER_NEEDED(nikoModel);
|
||||
showNotification("~g~Changed to Niko!");
|
||||
} else {
|
||||
showNotification("~r~Failed to load model!");
|
||||
}
|
||||
}
|
||||
|
||||
function explodeSelf() {
|
||||
let playerPed = natives.GET_PLAYER_PED(natives.GET_PLAYER_ID());
|
||||
let pos = natives.GET_CHAR_COORDINATES(playerPed);
|
||||
|
||||
natives.ADD_EXPLOSION(pos[0], pos[1], pos[2], 2, 10.0, true, false, 0.7);
|
||||
showNotification("~r~BOOM!");
|
||||
}
|
||||
|
||||
function resurrectPlayer() {
|
||||
let playerId = natives.GET_PLAYER_ID();
|
||||
let playerPed = natives.GET_PLAYER_PED(playerId);
|
||||
let pos = natives.GET_CHAR_COORDINATES(playerPed);
|
||||
|
||||
natives.RESURRECT_NETWORK_PLAYER(playerId, pos[0], pos[1], pos[2], 0);
|
||||
natives.SET_CHAR_HEALTH(playerPed, 200);
|
||||
showNotification("~g~Resurrected!");
|
||||
}
|
||||
|
||||
function setWantedLevel(level) {
|
||||
let playerId = natives.GET_PLAYER_ID();
|
||||
natives.ALTER_WANTED_LEVEL(playerId, level);
|
||||
natives.APPLY_WANTED_LEVEL_CHANGE_NOW(playerId);
|
||||
showNotification("~b~Wanted level set to: ~s~" + level);
|
||||
}
|
||||
|
||||
function clearWantedLevel() {
|
||||
let playerId = natives.GET_PLAYER_ID();
|
||||
natives.CLEAR_WANTED_LEVEL(playerId);
|
||||
showNotification("~g~Wanted level cleared!");
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// PLAYER OPTIONS LOOP
|
||||
// ============================================================================
|
||||
|
||||
function playerOptionsLoop() {
|
||||
let playerId = natives.GET_PLAYER_ID();
|
||||
let playerPed = natives.GET_PLAYER_PED(playerId);
|
||||
|
||||
if (!natives.DOES_CHAR_EXIST(playerPed)) return;
|
||||
|
||||
// God Mode maintenance
|
||||
if (playerOptions.godmode) {
|
||||
natives.SET_CHAR_INVINCIBLE(playerPed, true);
|
||||
}
|
||||
|
||||
// Juggernaut (auto health/armor)
|
||||
if (playerOptions.juggernaut) {
|
||||
let health = natives.GET_CHAR_HEALTH(playerPed);
|
||||
let armor = natives.GET_CHAR_ARMOUR(playerPed);
|
||||
|
||||
if (health < 200) natives.SET_CHAR_HEALTH(playerPed, 200);
|
||||
if (armor < 100) natives.ADD_ARMOUR_TO_CHAR(playerPed, 100 - armor);
|
||||
}
|
||||
|
||||
// Never Wanted
|
||||
if (playerOptions.neverWanted) {
|
||||
natives.CLEAR_WANTED_LEVEL(playerId);
|
||||
}
|
||||
|
||||
// Infinite Ammo
|
||||
if (playerOptions.infiniteAmmo && natives.IS_CHAR_SHOOTING(playerPed)) {
|
||||
let weapon = natives.GET_CURRENT_CHAR_WEAPON(playerPed);
|
||||
if (weapon !== 16 && weapon !== 17) { // Not grenade or molotov
|
||||
let maxAmmo = natives.GET_MAX_AMMO_IN_CLIP(playerPed, weapon);
|
||||
natives.SET_AMMO_IN_CLIP(playerPed, weapon, maxAmmo);
|
||||
}
|
||||
}
|
||||
|
||||
// Super Powers (only when not in vehicle)
|
||||
let inVehicle = natives.IS_CHAR_IN_ANY_CAR(playerPed);
|
||||
if (!inVehicle) {
|
||||
let lbPressed = natives.IS_BUTTON_PRESSED(0, 256); // LB
|
||||
let rbPressed = natives.IS_BUTTON_PRESSED(0, 512); // RB
|
||||
|
||||
// Super Run (LB/RB + A)
|
||||
if (playerOptions.superRun && (lbPressed || rbPressed) && natives.IS_BUTTON_PRESSED(0, 16)) {
|
||||
let force = lbPressed ? 100.0 : 10.0;
|
||||
natives.APPLY_FORCE_TO_PED(playerPed, true, 0.0, force, 0.0, 0.0, 0.0, 0.0, true, true, true, true);
|
||||
}
|
||||
|
||||
// Super Jump (LB/RB + X)
|
||||
if (playerOptions.superJump && (lbPressed || rbPressed) && natives.IS_BUTTON_PRESSED(0, 64)) {
|
||||
let upForce = lbPressed ? 11.0 : 50.0;
|
||||
let fwdForce = lbPressed ? 1.2 : 0.0;
|
||||
natives.APPLY_FORCE_TO_PED(playerPed, true, 0.0, fwdForce, upForce, 0.0, 0.0, 0.0, true, true, true, true);
|
||||
}
|
||||
|
||||
// Super Punch (LB + B with fist)
|
||||
if (playerOptions.superPunch && lbPressed && natives.IS_BUTTON_PRESSED(0, 32)) {
|
||||
let weapon = natives.GET_CURRENT_CHAR_WEAPON(playerPed);
|
||||
if (weapon === 0) { // Unarmed
|
||||
let offset = natives.GET_OFFSET_FROM_CHAR_IN_WORLD_COORDS(playerPed, 0, 2, 0);
|
||||
natives.ADD_EXPLOSION(offset[0], offset[1], offset[2], 2, 10, false, true, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Inferno Mode
|
||||
if (playerOptions.inferno) {
|
||||
let pos = natives.GET_CHAR_COORDINATES(playerPed);
|
||||
natives.ADD_EXPLOSION(pos[0], pos[1], pos[2], 5, 7.5, true, false, 0.0);
|
||||
}
|
||||
|
||||
// Force Field
|
||||
if (playerOptions.forceField) {
|
||||
let pos = natives.GET_CHAR_COORDINATES(playerPed);
|
||||
natives.ADD_EXPLOSION(pos[0], pos[1], pos[2], 2, 10.0, false, true, 0.0);
|
||||
}
|
||||
|
||||
// Fly Mode
|
||||
if (flyModeState.active) {
|
||||
processFlyMode();
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// FLY MODE PROCESSING
|
||||
// ============================================================================
|
||||
|
||||
function processFlyMode() {
|
||||
let playerId = natives.GET_PLAYER_ID();
|
||||
let playerPed = natives.GET_PLAYER_PED(playerId);
|
||||
|
||||
if (!flyModeState.camera) return;
|
||||
|
||||
natives.FREEZE_CHAR_POSITION(playerPed, true);
|
||||
|
||||
let pos = natives.GET_CHAR_COORDINATES(playerPed);
|
||||
let heading = natives.GET_CHAR_HEADING(playerPed);
|
||||
|
||||
// Get analog stick input
|
||||
let sticks = natives.GET_POSITION_OF_ANALOGUE_STICKS(0);
|
||||
let leftX = sticks[0] || 0;
|
||||
let leftY = sticks[1] || 0;
|
||||
let rightX = sticks[2] || 0;
|
||||
let rightY = sticks[3] || 0;
|
||||
|
||||
// Adjust heading with right stick
|
||||
heading = heading - (rightX * 0.035);
|
||||
if (heading > 360) heading -= 360;
|
||||
if (heading < 0) heading += 360;
|
||||
|
||||
// Adjust pitch
|
||||
flyModeState.pitch = flyModeState.pitch - (rightY * 0.035);
|
||||
if (flyModeState.pitch < -70) flyModeState.pitch = -70;
|
||||
if (flyModeState.pitch > 70) flyModeState.pitch = 70;
|
||||
|
||||
// Speed modifiers
|
||||
let moveSpeed = 1.0;
|
||||
if (natives.IS_BUTTON_PRESSED(0, 512)) moveSpeed = 4.0; // RB - Fast
|
||||
if (natives.IS_BUTTON_PRESSED(0, 256)) moveSpeed = 0.25; // LB - Slow
|
||||
|
||||
// Calculate movement
|
||||
let moveTrig = (leftY * 0.0133) * Math.cos(flyModeState.pitch * Math.PI / 180);
|
||||
let newX = pos[0] + (moveSpeed * ((moveTrig * Math.sin(heading * Math.PI / 180)) + (leftX * 0.0133) * Math.cos(heading * Math.PI / 180)));
|
||||
let newY = pos[1] - (moveSpeed * ((moveTrig * Math.cos(heading * Math.PI / 180)) - (leftX * 0.0133) * Math.sin(heading * Math.PI / 180)));
|
||||
let newZ = pos[2] - (moveSpeed * ((leftY * 0.0133) * Math.sin(flyModeState.pitch * Math.PI / 180)));
|
||||
|
||||
// Height adjustment with triggers
|
||||
let lt = natives.GET_CONTROL_VALUE(0, 6); // LT
|
||||
let rt = natives.GET_CONTROL_VALUE(0, 5); // RT
|
||||
newZ = newZ + (moveSpeed * ((rt * 0.0025) - (lt * 0.0025)));
|
||||
|
||||
// Update position
|
||||
natives.SET_CHAR_COORDINATES_NO_OFFSET(playerPed, newX, newY, newZ);
|
||||
natives.SET_CHAR_HEADING(playerPed, heading);
|
||||
|
||||
// Update camera
|
||||
let camDistance = 4.0;
|
||||
let camOffsetTrig = camDistance * Math.cos((flyModeState.pitch - 18) * Math.PI / 180);
|
||||
let camOffsetX = camOffsetTrig * Math.sin(heading * Math.PI / 180);
|
||||
let camOffsetY = -camOffsetTrig * Math.cos(heading * Math.PI / 180);
|
||||
let camOffsetZ = -camDistance * Math.sin((flyModeState.pitch - 18) * Math.PI / 180);
|
||||
|
||||
natives.SET_CAM_ATTACH_OFFSET(flyModeState.camera, camOffsetX, camOffsetY, camOffsetZ);
|
||||
|
||||
// Exit fly mode with all shoulder buttons
|
||||
if (natives.IS_BUTTON_PRESSED(0, 256) && natives.IS_BUTTON_PRESSED(0, 512) &&
|
||||
natives.IS_BUTTON_PRESSED(0, 1024) && natives.IS_BUTTON_PRESSED(0, 2048)) {
|
||||
toggleFlyMode(false);
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// EVENT HANDLERS
|
||||
// ============================================================================
|
||||
|
||||
addEventHandler("OnProcess", function(event) {
|
||||
playerOptionsLoop();
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
// EXPORTS
|
||||
// ============================================================================
|
||||
|
||||
this.playerOptions = playerOptions;
|
||||
this.getPlayerMenuItems = getPlayerMenuItems;
|
||||
this.toggleGodMode = toggleGodMode;
|
||||
this.toggleNeverWanted = toggleNeverWanted;
|
||||
this.giveHealth = giveHealth;
|
||||
this.giveArmor = giveArmor;
|
||||
276
Trident/teleport.js
Normal file
276
Trident/teleport.js
Normal file
@@ -0,0 +1,276 @@
|
||||
/**
|
||||
* MD TRIDENT - Teleport Options Module
|
||||
* GTAConnected Port for GTA IV
|
||||
*/
|
||||
|
||||
// ============================================================================
|
||||
// TELEPORT LOCATIONS (Liberty City)
|
||||
// ============================================================================
|
||||
|
||||
const TELEPORT_LOCATIONS = {
|
||||
// Broker/Dukes
|
||||
BROKER_SAFEHOUSE: { x: 875.59, y: -482.13, z: 15.65, name: "Broker Safehouse" },
|
||||
ROTTERDAM_HILL: { x: 1030.25, y: -618.87, z: 25.12, name: "Rotterdam Hill" },
|
||||
EAST_HOOK: { x: 1224.36, y: -244.15, z: 20.34, name: "East Hook" },
|
||||
STEINWAY: { x: 1414.54, y: 498.27, z: 35.76, name: "Steinway" },
|
||||
DUKES_BAY_BRIDGE: { x: 1586.32, y: 1231.45, z: 22.89, name: "Dukes Bay Bridge" },
|
||||
|
||||
// Bohan
|
||||
BOHAN_SAFEHOUSE: { x: 579.45, y: 1436.32, z: 16.87, name: "Bohan Safehouse" },
|
||||
NORTHERN_GARDENS: { x: 428.67, y: 1652.43, z: 17.54, name: "Northern Gardens" },
|
||||
SOUTH_BOHAN: { x: 715.23, y: 1245.67, z: 15.43, name: "South Bohan" },
|
||||
|
||||
// Algonquin
|
||||
MIDDLE_PARK: { x: -21.45, y: 532.87, z: 15.23, name: "Middle Park" },
|
||||
STAR_JUNCTION: { x: -234.56, y: 234.78, z: 14.67, name: "Star Junction (Times Sq)" },
|
||||
ALGONQUIN_SAFEHOUSE: { x: -432.12, y: 1245.43, z: 20.34, name: "Algonquin Safehouse" },
|
||||
HAPPINESS_ISLAND: { x: -1032.45, y: -721.34, z: 4.21, name: "Happiness Island" },
|
||||
STATUE_OF_HAPPINESS: { x: -1032.45, y: -721.34, z: 96.45, name: "Statue of Happiness (Top)" },
|
||||
LIBERTY_FERRY_TERMINAL: { x: -784.56, y: -286.43, z: 5.67, name: "Liberty Ferry Terminal" },
|
||||
AIRPORT: { x: 2165.34, y: 487.65, z: 6.23, name: "Francis Intl Airport" },
|
||||
|
||||
// Alderney
|
||||
ALDERNEY_SAFEHOUSE: { x: -1134.56, y: 743.21, z: 21.45, name: "Alderney Safehouse" },
|
||||
WESTDYKE: { x: -1423.67, y: 1234.56, z: 23.78, name: "Westdyke" },
|
||||
ACTER_INDUSTRIAL: { x: -1087.32, y: 256.78, z: 17.34, name: "Acter Industrial" },
|
||||
PORT_TUDOR: { x: -1256.43, y: -78.65, z: 6.54, name: "Port Tudor" },
|
||||
|
||||
// Special
|
||||
HOSPITAL: { x: 1197.23, y: -476.54, z: 18.76, name: "Hospital" },
|
||||
POLICE_STATION: { x: 945.67, y: -367.89, z: 15.43, name: "Police Station" },
|
||||
BOWLING_ALLEY: { x: 754.32, y: -612.45, z: 12.34, name: "Bowling Alley" },
|
||||
BURGER_SHOT: { x: 1087.65, y: -234.56, z: 17.89, name: "Burger Shot" }
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// TELEPORT MENU ITEMS
|
||||
// ============================================================================
|
||||
|
||||
function getTeleportMenuItems() {
|
||||
return [
|
||||
createMenuItem("~~ QUICK TELEPORTS ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("Teleport to Waypoint", ITEM_TYPE.FUNCTION, { action: teleportToWaypoint }),
|
||||
createMenuItem("Teleport Forward", ITEM_TYPE.FUNCTION, { action: teleportForward }),
|
||||
|
||||
createMenuItem("~~ BROKER / DUKES ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("Broker Safehouse", ITEM_TYPE.FUNCTION, {
|
||||
action: () => teleportTo(TELEPORT_LOCATIONS.BROKER_SAFEHOUSE)
|
||||
}),
|
||||
createMenuItem("Rotterdam Hill", ITEM_TYPE.FUNCTION, {
|
||||
action: () => teleportTo(TELEPORT_LOCATIONS.ROTTERDAM_HILL)
|
||||
}),
|
||||
createMenuItem("East Hook", ITEM_TYPE.FUNCTION, {
|
||||
action: () => teleportTo(TELEPORT_LOCATIONS.EAST_HOOK)
|
||||
}),
|
||||
createMenuItem("Steinway", ITEM_TYPE.FUNCTION, {
|
||||
action: () => teleportTo(TELEPORT_LOCATIONS.STEINWAY)
|
||||
}),
|
||||
|
||||
createMenuItem("~~ BOHAN ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("Bohan Safehouse", ITEM_TYPE.FUNCTION, {
|
||||
action: () => teleportTo(TELEPORT_LOCATIONS.BOHAN_SAFEHOUSE)
|
||||
}),
|
||||
createMenuItem("Northern Gardens", ITEM_TYPE.FUNCTION, {
|
||||
action: () => teleportTo(TELEPORT_LOCATIONS.NORTHERN_GARDENS)
|
||||
}),
|
||||
createMenuItem("South Bohan", ITEM_TYPE.FUNCTION, {
|
||||
action: () => teleportTo(TELEPORT_LOCATIONS.SOUTH_BOHAN)
|
||||
}),
|
||||
|
||||
createMenuItem("~~ ALGONQUIN ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("Middle Park", ITEM_TYPE.FUNCTION, {
|
||||
action: () => teleportTo(TELEPORT_LOCATIONS.MIDDLE_PARK)
|
||||
}),
|
||||
createMenuItem("Star Junction (Times Sq)", ITEM_TYPE.FUNCTION, {
|
||||
action: () => teleportTo(TELEPORT_LOCATIONS.STAR_JUNCTION)
|
||||
}),
|
||||
createMenuItem("Algonquin Safehouse", ITEM_TYPE.FUNCTION, {
|
||||
action: () => teleportTo(TELEPORT_LOCATIONS.ALGONQUIN_SAFEHOUSE)
|
||||
}),
|
||||
createMenuItem("Happiness Island", ITEM_TYPE.FUNCTION, {
|
||||
action: () => teleportTo(TELEPORT_LOCATIONS.HAPPINESS_ISLAND)
|
||||
}),
|
||||
createMenuItem("Statue of Happiness (Top)", ITEM_TYPE.FUNCTION, {
|
||||
action: () => teleportTo(TELEPORT_LOCATIONS.STATUE_OF_HAPPINESS)
|
||||
}),
|
||||
createMenuItem("Francis Intl Airport", ITEM_TYPE.FUNCTION, {
|
||||
action: () => teleportTo(TELEPORT_LOCATIONS.AIRPORT)
|
||||
}),
|
||||
|
||||
createMenuItem("~~ ALDERNEY ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("Alderney Safehouse", ITEM_TYPE.FUNCTION, {
|
||||
action: () => teleportTo(TELEPORT_LOCATIONS.ALDERNEY_SAFEHOUSE)
|
||||
}),
|
||||
createMenuItem("Westdyke", ITEM_TYPE.FUNCTION, {
|
||||
action: () => teleportTo(TELEPORT_LOCATIONS.WESTDYKE)
|
||||
}),
|
||||
createMenuItem("Acter Industrial", ITEM_TYPE.FUNCTION, {
|
||||
action: () => teleportTo(TELEPORT_LOCATIONS.ACTER_INDUSTRIAL)
|
||||
}),
|
||||
createMenuItem("Port Tudor", ITEM_TYPE.FUNCTION, {
|
||||
action: () => teleportTo(TELEPORT_LOCATIONS.PORT_TUDOR)
|
||||
}),
|
||||
|
||||
createMenuItem("~~ SERVICES ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("Hospital", ITEM_TYPE.FUNCTION, {
|
||||
action: () => teleportTo(TELEPORT_LOCATIONS.HOSPITAL)
|
||||
}),
|
||||
createMenuItem("Police Station", ITEM_TYPE.FUNCTION, {
|
||||
action: () => teleportTo(TELEPORT_LOCATIONS.POLICE_STATION)
|
||||
}),
|
||||
createMenuItem("Bowling Alley", ITEM_TYPE.FUNCTION, {
|
||||
action: () => teleportTo(TELEPORT_LOCATIONS.BOWLING_ALLEY)
|
||||
}),
|
||||
createMenuItem("Burger Shot", ITEM_TYPE.FUNCTION, {
|
||||
action: () => teleportTo(TELEPORT_LOCATIONS.BURGER_SHOT)
|
||||
}),
|
||||
|
||||
createMenuItem("~~ COORDINATES ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("Save Current Position", ITEM_TYPE.FUNCTION, { action: saveCurrentPosition }),
|
||||
createMenuItem("Teleport to Saved Position", ITEM_TYPE.FUNCTION, { action: teleportToSavedPosition })
|
||||
];
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// SAVED POSITIONS
|
||||
// ============================================================================
|
||||
|
||||
let savedPositions = [];
|
||||
let lastSavedPosition = null;
|
||||
|
||||
// ============================================================================
|
||||
// TELEPORT FUNCTIONS
|
||||
// ============================================================================
|
||||
|
||||
function teleportTo(location) {
|
||||
let playerId = natives.GET_PLAYER_ID();
|
||||
let playerPed = natives.GET_PLAYER_PED(playerId);
|
||||
|
||||
let inVehicle = natives.IS_CHAR_IN_ANY_CAR(playerPed);
|
||||
|
||||
if (inVehicle) {
|
||||
let vehicle = natives.GET_CAR_CHAR_IS_USING(playerPed);
|
||||
natives.SET_CAR_COORDINATES_NO_OFFSET(vehicle, location.x, location.y, location.z);
|
||||
natives.SET_CAR_ON_GROUND_PROPERLY(vehicle);
|
||||
} else {
|
||||
natives.SET_CHAR_COORDINATES_NO_OFFSET(playerPed, location.x, location.y, location.z);
|
||||
}
|
||||
|
||||
showNotification("~g~Teleported to: ~s~" + location.name);
|
||||
}
|
||||
|
||||
function teleportToWaypoint() {
|
||||
let playerId = natives.GET_PLAYER_ID();
|
||||
let playerPed = natives.GET_PLAYER_PED(playerId);
|
||||
|
||||
// Check if waypoint is set
|
||||
let blipInfo = natives.GET_FIRST_BLIP_INFO_ID(8); // 8 = waypoint blip
|
||||
if (!blipInfo || blipInfo === 0) {
|
||||
showNotification("~r~No waypoint set!");
|
||||
return;
|
||||
}
|
||||
|
||||
let blipCoords = natives.GET_BLIP_INFO_ID_COORD(blipInfo);
|
||||
if (!blipCoords) {
|
||||
showNotification("~r~Could not get waypoint coordinates!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get ground Z at waypoint
|
||||
let groundZ = natives.GET_GROUND_Z_FOR_3D_COORD(blipCoords[0], blipCoords[1], 1000.0);
|
||||
let targetZ = groundZ ? groundZ + 1.0 : blipCoords[2] + 1.0;
|
||||
|
||||
let inVehicle = natives.IS_CHAR_IN_ANY_CAR(playerPed);
|
||||
|
||||
if (inVehicle) {
|
||||
let vehicle = natives.GET_CAR_CHAR_IS_USING(playerPed);
|
||||
natives.SET_CAR_COORDINATES_NO_OFFSET(vehicle, blipCoords[0], blipCoords[1], targetZ);
|
||||
natives.SET_CAR_ON_GROUND_PROPERLY(vehicle);
|
||||
} else {
|
||||
natives.SET_CHAR_COORDINATES_NO_OFFSET(playerPed, blipCoords[0], blipCoords[1], targetZ);
|
||||
}
|
||||
|
||||
showNotification("~g~Teleported to waypoint!");
|
||||
}
|
||||
|
||||
function teleportForward() {
|
||||
let playerId = natives.GET_PLAYER_ID();
|
||||
let playerPed = natives.GET_PLAYER_PED(playerId);
|
||||
|
||||
let pos = natives.GET_CHAR_COORDINATES(playerPed);
|
||||
let heading = natives.GET_CHAR_HEADING(playerPed);
|
||||
|
||||
// Calculate position 10 units forward
|
||||
let radians = heading * Math.PI / 180;
|
||||
let newX = pos[0] - Math.sin(radians) * 10;
|
||||
let newY = pos[1] + Math.cos(radians) * 10;
|
||||
let newZ = pos[2];
|
||||
|
||||
// Get ground Z at new position
|
||||
let groundZ = natives.GET_GROUND_Z_FOR_3D_COORD(newX, newY, pos[2] + 100);
|
||||
if (groundZ) {
|
||||
newZ = groundZ + 1.0;
|
||||
}
|
||||
|
||||
let inVehicle = natives.IS_CHAR_IN_ANY_CAR(playerPed);
|
||||
|
||||
if (inVehicle) {
|
||||
let vehicle = natives.GET_CAR_CHAR_IS_USING(playerPed);
|
||||
natives.SET_CAR_COORDINATES_NO_OFFSET(vehicle, newX, newY, newZ);
|
||||
} else {
|
||||
natives.SET_CHAR_COORDINATES_NO_OFFSET(playerPed, newX, newY, newZ);
|
||||
}
|
||||
|
||||
showNotification("~g~Teleported forward!");
|
||||
}
|
||||
|
||||
function saveCurrentPosition() {
|
||||
let playerPed = natives.GET_PLAYER_PED(natives.GET_PLAYER_ID());
|
||||
let pos = natives.GET_CHAR_COORDINATES(playerPed);
|
||||
let heading = natives.GET_CHAR_HEADING(playerPed);
|
||||
|
||||
lastSavedPosition = {
|
||||
x: pos[0],
|
||||
y: pos[1],
|
||||
z: pos[2],
|
||||
heading: heading,
|
||||
name: "Saved Position " + (savedPositions.length + 1)
|
||||
};
|
||||
|
||||
savedPositions.push(lastSavedPosition);
|
||||
|
||||
showNotification("~g~Position saved! ~s~(" + pos[0].toFixed(2) + ", " + pos[1].toFixed(2) + ", " + pos[2].toFixed(2) + ")");
|
||||
}
|
||||
|
||||
function teleportToSavedPosition() {
|
||||
if (!lastSavedPosition) {
|
||||
showNotification("~r~No position saved!");
|
||||
return;
|
||||
}
|
||||
|
||||
let playerId = natives.GET_PLAYER_ID();
|
||||
let playerPed = natives.GET_PLAYER_PED(playerId);
|
||||
|
||||
let inVehicle = natives.IS_CHAR_IN_ANY_CAR(playerPed);
|
||||
|
||||
if (inVehicle) {
|
||||
let vehicle = natives.GET_CAR_CHAR_IS_USING(playerPed);
|
||||
natives.SET_CAR_COORDINATES_NO_OFFSET(vehicle, lastSavedPosition.x, lastSavedPosition.y, lastSavedPosition.z);
|
||||
natives.SET_CAR_HEADING(vehicle, lastSavedPosition.heading);
|
||||
natives.SET_CAR_ON_GROUND_PROPERLY(vehicle);
|
||||
} else {
|
||||
natives.SET_CHAR_COORDINATES_NO_OFFSET(playerPed, lastSavedPosition.x, lastSavedPosition.y, lastSavedPosition.z);
|
||||
natives.SET_CHAR_HEADING(playerPed, lastSavedPosition.heading);
|
||||
}
|
||||
|
||||
showNotification("~g~Teleported to saved position!");
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// EXPORTS
|
||||
// ============================================================================
|
||||
|
||||
this.getTeleportMenuItems = getTeleportMenuItems;
|
||||
this.teleportTo = teleportTo;
|
||||
this.teleportToWaypoint = teleportToWaypoint;
|
||||
this.TELEPORT_LOCATIONS = TELEPORT_LOCATIONS;
|
||||
604
Trident/vehicle.js
Normal file
604
Trident/vehicle.js
Normal file
@@ -0,0 +1,604 @@
|
||||
/**
|
||||
* MD TRIDENT - Vehicle Options Module
|
||||
* GTAConnected Port for GTA IV
|
||||
*/
|
||||
|
||||
// ============================================================================
|
||||
// VEHICLE MODEL HASHES (GTA IV)
|
||||
// ============================================================================
|
||||
|
||||
const VEHICLE_MODELS = {
|
||||
// Sports Cars
|
||||
BANSHEE: 0xC1E908D2,
|
||||
COMET: 0x067BC037,
|
||||
COQUETTE: 0x067BC037,
|
||||
FELTZER: 0x8F5B9FB5,
|
||||
INFERNUS: 0x18F25AC7,
|
||||
SULTAN: 0x39DA2754,
|
||||
SULTANRS: 0xEE6024BC,
|
||||
SUPERGT: 0x42F2ED16,
|
||||
TURISMO: 0x185484E1,
|
||||
SENTINEL: 0x50732C82,
|
||||
|
||||
// Muscle Cars
|
||||
BUCCANEER: 0xD756460C,
|
||||
DUKES: 0x2B26F456,
|
||||
FACTION: 0x81A9CDDF,
|
||||
MANANA: 0x81634188,
|
||||
PEYOTE: 0x6D19CCBC,
|
||||
RUINER: 0xF26CEFF9,
|
||||
SABRE: 0x9B909C94,
|
||||
SABREGT: 0x9B909C94,
|
||||
STALION: 0x72A4C31E,
|
||||
VIGERO: 0xCEC6B9B7,
|
||||
VIRGO: 0xE2504942,
|
||||
VOODOO: 0x1F3766E3,
|
||||
|
||||
// SUVs and Off-Road
|
||||
BOBCAT: 0x31F0B376,
|
||||
CAVALCADE: 0x779F23AA,
|
||||
HABANERO: 0x34B7390F,
|
||||
HUNTLEY: 0x1D06D681,
|
||||
LANDSTALKER: 0x4BA4E8DC,
|
||||
PATRIOT: 0xCFCFEB3B,
|
||||
RANCHER: 0x6210CBB0,
|
||||
REBLA: 0x4C489021,
|
||||
|
||||
// Sedans
|
||||
ADMIRAL: 0x32B29A4B,
|
||||
CHAVOS: 0xE8A8BDA8,
|
||||
COGNOSCENTI: 0x86FE0B60,
|
||||
EMPEROR: 0xD7278283,
|
||||
ESPERANTO: 0xFF8C6ED1,
|
||||
FEROCI: 0x1AD3D617,
|
||||
INGOT: 0xB3206692,
|
||||
INTRUDER: 0x34DD8AA1,
|
||||
LOKUS: 0xCB3C7191,
|
||||
ORACLE: 0x506434F6,
|
||||
PINNACLE: 0x874D2A8B,
|
||||
PMP600: 0x700E514C,
|
||||
PREMIER: 0x8FB66F9B,
|
||||
SCHAFTER: 0xB52B5113,
|
||||
VINCENT: 0x9D0450CA,
|
||||
WASHINGTON: 0x69F06B57,
|
||||
|
||||
// Emergency Vehicles
|
||||
AMBULANCE: 0x45D56ADA,
|
||||
FBI: 0x432EA949,
|
||||
FIRETRUK: 0x73920F8E,
|
||||
NOOSE: 0xB4F32720,
|
||||
POLICE: 0x79FBB0C5,
|
||||
POLICE2: 0x9F05F101,
|
||||
POLPATRIOT: 0xCFCFEB3B,
|
||||
|
||||
// Commercial
|
||||
BENSON: 0xB7B2BBE7,
|
||||
BOXVILLE: 0x898ECCEA,
|
||||
BURRITO: 0xAFBB2CA4,
|
||||
FLATBED: 0x50B0215A,
|
||||
MULE: 0x35ED670B,
|
||||
PACKER: 0x21EEE87D,
|
||||
PHANTOM: 0x809AA4CB,
|
||||
PONY: 0xF8DE29A8,
|
||||
SPEEDO: 0xCFB3870C,
|
||||
STOCKADE: 0x6827CF72,
|
||||
YANKEE: 0x3D236D91,
|
||||
|
||||
// Public Service
|
||||
BUS: 0xD577C962,
|
||||
CABBY: 0x3FC5D440,
|
||||
ROMERO: 0x2560B2FC,
|
||||
TAXI: 0xC703DB5F,
|
||||
STRETCH: 0x8B13F083,
|
||||
TRASH: 0x72435A19,
|
||||
|
||||
// Bikes
|
||||
FAGGIO: 0x9229E4EB,
|
||||
NRG900: 0x6F946279,
|
||||
PCJ: 0xC9CEAF06,
|
||||
SANCHEZ: 0x2EF89E46,
|
||||
ZOMBIEB: 0xDE05FB87,
|
||||
HELLFURY: 0x6598A42B,
|
||||
BOBBER: 0x67B52491,
|
||||
|
||||
// Boats
|
||||
DINGHY: 0x3D961290,
|
||||
JETMAX: 0x33581161,
|
||||
MARQUIS: 0xC1CE1183,
|
||||
PREDATOR: 0xE2E7D4AB,
|
||||
REEFER: 0x1D97DCAF,
|
||||
SQUALO: 0x17DF5EC2,
|
||||
TROPIC: 0x1149422F,
|
||||
TUGA: 0x82CAC433,
|
||||
|
||||
// Helicopters
|
||||
ANNIHILATOR: 0x31F0B376,
|
||||
MAVERICK: 0x9D0450CA,
|
||||
POLMAV: 0x1517D4D9,
|
||||
TOURMAV: 0x73232612
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// VEHICLE OPTIONS STATE
|
||||
// ============================================================================
|
||||
|
||||
let vehicleOptions = {
|
||||
godmode: false,
|
||||
speedBoost: false,
|
||||
autoFlip: false,
|
||||
autoFix: false,
|
||||
rainbow: false,
|
||||
invisible: false,
|
||||
engineAlwaysOn: false,
|
||||
nitro: false
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// VEHICLE MENU ITEMS
|
||||
// ============================================================================
|
||||
|
||||
function getVehicleMenuItems() {
|
||||
return [
|
||||
createMenuItem("~~ SPAWN VEHICLES ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("Quick Spawner (Favorites)", ITEM_TYPE.SUBMENU, { submenu: "vehicle_favorites" }),
|
||||
createMenuItem("Sports Cars", ITEM_TYPE.SUBMENU, { submenu: "vehicle_sports" }),
|
||||
createMenuItem("Muscle / Vintage", ITEM_TYPE.SUBMENU, { submenu: "vehicle_muscle" }),
|
||||
createMenuItem("SUVs / Off-Road", ITEM_TYPE.SUBMENU, { submenu: "vehicle_suv" }),
|
||||
createMenuItem("Sedans", ITEM_TYPE.SUBMENU, { submenu: "vehicle_sedan" }),
|
||||
createMenuItem("Emergency Vehicles", ITEM_TYPE.SUBMENU, { submenu: "vehicle_emergency" }),
|
||||
createMenuItem("Bikes", ITEM_TYPE.SUBMENU, { submenu: "vehicle_bikes" }),
|
||||
createMenuItem("Boats", ITEM_TYPE.SUBMENU, { submenu: "vehicle_boats" }),
|
||||
createMenuItem("Helicopters", ITEM_TYPE.SUBMENU, { submenu: "vehicle_helicopters" }),
|
||||
createMenuItem("Commercial", ITEM_TYPE.SUBMENU, { submenu: "vehicle_commercial" }),
|
||||
|
||||
createMenuItem("~~ VEHICLE OPTIONS ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("Vehicle God Mode", ITEM_TYPE.BOOL, {
|
||||
boolState: vehicleOptions.godmode,
|
||||
action: toggleVehicleGodMode
|
||||
}),
|
||||
createMenuItem("Speed Boost", ITEM_TYPE.BOOL, {
|
||||
boolState: vehicleOptions.speedBoost,
|
||||
action: toggleSpeedBoost
|
||||
}),
|
||||
createMenuItem("Auto Flip", ITEM_TYPE.BOOL, {
|
||||
boolState: vehicleOptions.autoFlip,
|
||||
action: toggleAutoFlip
|
||||
}),
|
||||
createMenuItem("Auto Repair", ITEM_TYPE.BOOL, {
|
||||
boolState: vehicleOptions.autoFix,
|
||||
action: toggleAutoFix
|
||||
}),
|
||||
createMenuItem("Rainbow Car", ITEM_TYPE.BOOL, {
|
||||
boolState: vehicleOptions.rainbow,
|
||||
action: toggleRainbow
|
||||
}),
|
||||
createMenuItem("Invisible Vehicle", ITEM_TYPE.BOOL, {
|
||||
boolState: vehicleOptions.invisible,
|
||||
action: toggleVehicleInvisible
|
||||
}),
|
||||
|
||||
createMenuItem("~~ VEHICLE ACTIONS ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("Repair Vehicle", ITEM_TYPE.FUNCTION, { action: repairVehicle }),
|
||||
createMenuItem("Flip Vehicle", ITEM_TYPE.FUNCTION, { action: flipVehicle }),
|
||||
createMenuItem("Clean Vehicle", ITEM_TYPE.FUNCTION, { action: cleanVehicle }),
|
||||
createMenuItem("Maximize Performance", ITEM_TYPE.FUNCTION, { action: maxPerformance }),
|
||||
createMenuItem("Delete Vehicle", ITEM_TYPE.FUNCTION, { action: deleteVehicle }),
|
||||
createMenuItem("Teleport to Nearest Vehicle", ITEM_TYPE.FUNCTION, { action: teleportToNearestVehicle })
|
||||
];
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// VEHICLE CATEGORY ITEMS
|
||||
// ============================================================================
|
||||
|
||||
function getFavoriteVehicleItems() {
|
||||
return [
|
||||
createMenuItem("Comet", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.COMET, action: spawnVehicleAction }),
|
||||
createMenuItem("Turismo", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.TURISMO, action: spawnVehicleAction }),
|
||||
createMenuItem("Infernus", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.INFERNUS, action: spawnVehicleAction }),
|
||||
createMenuItem("Super GT", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.SUPERGT, action: spawnVehicleAction }),
|
||||
createMenuItem("Sultan RS", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.SULTANRS, action: spawnVehicleAction }),
|
||||
createMenuItem("Oracle", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.ORACLE, action: spawnVehicleAction }),
|
||||
createMenuItem("Patriot", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.PATRIOT, action: spawnVehicleAction }),
|
||||
createMenuItem("FBI", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.FBI, action: spawnVehicleAction }),
|
||||
createMenuItem("Bus", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.BUS, action: spawnVehicleAction }),
|
||||
createMenuItem("NRG 900", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.NRG900, action: spawnVehicleAction }),
|
||||
createMenuItem("Maverick", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.MAVERICK, action: spawnVehicleAction }),
|
||||
createMenuItem("Annihilator", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.ANNIHILATOR, action: spawnVehicleAction })
|
||||
];
|
||||
}
|
||||
|
||||
function getSportsVehicleItems() {
|
||||
return [
|
||||
createMenuItem("Banshee", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.BANSHEE, action: spawnVehicleAction }),
|
||||
createMenuItem("Comet", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.COMET, action: spawnVehicleAction }),
|
||||
createMenuItem("Coquette", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.COQUETTE, action: spawnVehicleAction }),
|
||||
createMenuItem("Feltzer", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.FELTZER, action: spawnVehicleAction }),
|
||||
createMenuItem("Infernus", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.INFERNUS, action: spawnVehicleAction }),
|
||||
createMenuItem("Sultan", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.SULTAN, action: spawnVehicleAction }),
|
||||
createMenuItem("Sultan RS", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.SULTANRS, action: spawnVehicleAction }),
|
||||
createMenuItem("Super GT", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.SUPERGT, action: spawnVehicleAction }),
|
||||
createMenuItem("Turismo", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.TURISMO, action: spawnVehicleAction }),
|
||||
createMenuItem("Sentinel", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.SENTINEL, action: spawnVehicleAction })
|
||||
];
|
||||
}
|
||||
|
||||
function getMuscleVehicleItems() {
|
||||
return [
|
||||
createMenuItem("Buccaneer", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.BUCCANEER, action: spawnVehicleAction }),
|
||||
createMenuItem("Dukes", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.DUKES, action: spawnVehicleAction }),
|
||||
createMenuItem("Faction", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.FACTION, action: spawnVehicleAction }),
|
||||
createMenuItem("Manana", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.MANANA, action: spawnVehicleAction }),
|
||||
createMenuItem("Peyote", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.PEYOTE, action: spawnVehicleAction }),
|
||||
createMenuItem("Ruiner", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.RUINER, action: spawnVehicleAction }),
|
||||
createMenuItem("Sabre", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.SABRE, action: spawnVehicleAction }),
|
||||
createMenuItem("Stallion", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.STALION, action: spawnVehicleAction }),
|
||||
createMenuItem("Vigero", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.VIGERO, action: spawnVehicleAction }),
|
||||
createMenuItem("Virgo", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.VIRGO, action: spawnVehicleAction }),
|
||||
createMenuItem("Voodoo", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.VOODOO, action: spawnVehicleAction })
|
||||
];
|
||||
}
|
||||
|
||||
function getSUVVehicleItems() {
|
||||
return [
|
||||
createMenuItem("Bobcat", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.BOBCAT, action: spawnVehicleAction }),
|
||||
createMenuItem("Cavalcade", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.CAVALCADE, action: spawnVehicleAction }),
|
||||
createMenuItem("Habanero", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.HABANERO, action: spawnVehicleAction }),
|
||||
createMenuItem("Huntley", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.HUNTLEY, action: spawnVehicleAction }),
|
||||
createMenuItem("Landstalker", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.LANDSTALKER, action: spawnVehicleAction }),
|
||||
createMenuItem("Patriot", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.PATRIOT, action: spawnVehicleAction }),
|
||||
createMenuItem("Rancher", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.RANCHER, action: spawnVehicleAction }),
|
||||
createMenuItem("Rebla", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.REBLA, action: spawnVehicleAction })
|
||||
];
|
||||
}
|
||||
|
||||
function getSedanVehicleItems() {
|
||||
return [
|
||||
createMenuItem("Admiral", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.ADMIRAL, action: spawnVehicleAction }),
|
||||
createMenuItem("Chavos", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.CHAVOS, action: spawnVehicleAction }),
|
||||
createMenuItem("Cognoscenti", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.COGNOSCENTI, action: spawnVehicleAction }),
|
||||
createMenuItem("Emperor", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.EMPEROR, action: spawnVehicleAction }),
|
||||
createMenuItem("Esperanto", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.ESPERANTO, action: spawnVehicleAction }),
|
||||
createMenuItem("Feroci", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.FEROCI, action: spawnVehicleAction }),
|
||||
createMenuItem("Ingot", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.INGOT, action: spawnVehicleAction }),
|
||||
createMenuItem("Intruder", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.INTRUDER, action: spawnVehicleAction }),
|
||||
createMenuItem("Lokus", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.LOKUS, action: spawnVehicleAction }),
|
||||
createMenuItem("Oracle", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.ORACLE, action: spawnVehicleAction }),
|
||||
createMenuItem("Pinnacle", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.PINNACLE, action: spawnVehicleAction }),
|
||||
createMenuItem("Premier", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.PREMIER, action: spawnVehicleAction }),
|
||||
createMenuItem("Schafter", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.SCHAFTER, action: spawnVehicleAction }),
|
||||
createMenuItem("Washington", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.WASHINGTON, action: spawnVehicleAction })
|
||||
];
|
||||
}
|
||||
|
||||
function getEmergencyVehicleItems() {
|
||||
return [
|
||||
createMenuItem("Ambulance", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.AMBULANCE, action: spawnVehicleAction }),
|
||||
createMenuItem("FBI", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.FBI, action: spawnVehicleAction }),
|
||||
createMenuItem("Fire Truck", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.FIRETRUK, action: spawnVehicleAction }),
|
||||
createMenuItem("NOOSE", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.NOOSE, action: spawnVehicleAction }),
|
||||
createMenuItem("Police", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.POLICE, action: spawnVehicleAction }),
|
||||
createMenuItem("Police 2", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.POLICE2, action: spawnVehicleAction }),
|
||||
createMenuItem("Police Patriot", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.POLPATRIOT, action: spawnVehicleAction })
|
||||
];
|
||||
}
|
||||
|
||||
function getBikeVehicleItems() {
|
||||
return [
|
||||
createMenuItem("Faggio", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.FAGGIO, action: spawnVehicleAction }),
|
||||
createMenuItem("NRG 900", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.NRG900, action: spawnVehicleAction }),
|
||||
createMenuItem("PCJ", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.PCJ, action: spawnVehicleAction }),
|
||||
createMenuItem("Sanchez", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.SANCHEZ, action: spawnVehicleAction }),
|
||||
createMenuItem("Zombie B", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.ZOMBIEB, action: spawnVehicleAction }),
|
||||
createMenuItem("Hellfury", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.HELLFURY, action: spawnVehicleAction }),
|
||||
createMenuItem("Bobber", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.BOBBER, action: spawnVehicleAction })
|
||||
];
|
||||
}
|
||||
|
||||
function getBoatVehicleItems() {
|
||||
return [
|
||||
createMenuItem("Dinghy", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.DINGHY, action: spawnVehicleAction }),
|
||||
createMenuItem("Jetmax", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.JETMAX, action: spawnVehicleAction }),
|
||||
createMenuItem("Marquis", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.MARQUIS, action: spawnVehicleAction }),
|
||||
createMenuItem("Predator", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.PREDATOR, action: spawnVehicleAction }),
|
||||
createMenuItem("Reefer", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.REEFER, action: spawnVehicleAction }),
|
||||
createMenuItem("Squalo", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.SQUALO, action: spawnVehicleAction }),
|
||||
createMenuItem("Tropic", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.TROPIC, action: spawnVehicleAction }),
|
||||
createMenuItem("Tuga", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.TUGA, action: spawnVehicleAction })
|
||||
];
|
||||
}
|
||||
|
||||
function getHelicopterVehicleItems() {
|
||||
return [
|
||||
createMenuItem("Annihilator", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.ANNIHILATOR, action: spawnVehicleAction }),
|
||||
createMenuItem("Maverick", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.MAVERICK, action: spawnVehicleAction }),
|
||||
createMenuItem("Police Maverick", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.POLMAV, action: spawnVehicleAction }),
|
||||
createMenuItem("Tour Maverick", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.TOURMAV, action: spawnVehicleAction })
|
||||
];
|
||||
}
|
||||
|
||||
function getCommercialVehicleItems() {
|
||||
return [
|
||||
createMenuItem("Benson", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.BENSON, action: spawnVehicleAction }),
|
||||
createMenuItem("Boxville", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.BOXVILLE, action: spawnVehicleAction }),
|
||||
createMenuItem("Burrito", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.BURRITO, action: spawnVehicleAction }),
|
||||
createMenuItem("Flatbed", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.FLATBED, action: spawnVehicleAction }),
|
||||
createMenuItem("Mule", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.MULE, action: spawnVehicleAction }),
|
||||
createMenuItem("Packer", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.PACKER, action: spawnVehicleAction }),
|
||||
createMenuItem("Phantom", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.PHANTOM, action: spawnVehicleAction }),
|
||||
createMenuItem("Pony", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.PONY, action: spawnVehicleAction }),
|
||||
createMenuItem("Speedo", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.SPEEDO, action: spawnVehicleAction }),
|
||||
createMenuItem("Stockade", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.STOCKADE, action: spawnVehicleAction }),
|
||||
createMenuItem("Yankee", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.YANKEE, action: spawnVehicleAction }),
|
||||
createMenuItem("Bus", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.BUS, action: spawnVehicleAction }),
|
||||
createMenuItem("Taxi", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.TAXI, action: spawnVehicleAction }),
|
||||
createMenuItem("Stretch", ITEM_TYPE.VEHICLE, { vehicleModel: VEHICLE_MODELS.STRETCH, action: spawnVehicleAction })
|
||||
];
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// TOGGLE FUNCTIONS
|
||||
// ============================================================================
|
||||
|
||||
function toggleVehicleGodMode(state) {
|
||||
vehicleOptions.godmode = state;
|
||||
showNotification(state ? "~g~Vehicle God Mode ~s~ON" : "~r~Vehicle God Mode ~s~OFF");
|
||||
}
|
||||
|
||||
function toggleSpeedBoost(state) {
|
||||
vehicleOptions.speedBoost = state;
|
||||
showNotification(state ? "~g~Speed Boost ~s~ON (Press Shift)" : "~r~Speed Boost ~s~OFF");
|
||||
}
|
||||
|
||||
function toggleAutoFlip(state) {
|
||||
vehicleOptions.autoFlip = state;
|
||||
showNotification(state ? "~g~Auto Flip ~s~ON" : "~r~Auto Flip ~s~OFF");
|
||||
}
|
||||
|
||||
function toggleAutoFix(state) {
|
||||
vehicleOptions.autoFix = state;
|
||||
showNotification(state ? "~g~Auto Repair ~s~ON" : "~r~Auto Repair ~s~OFF");
|
||||
}
|
||||
|
||||
function toggleRainbow(state) {
|
||||
vehicleOptions.rainbow = state;
|
||||
showNotification(state ? "~g~Rainbow Car ~s~ON" : "~r~Rainbow Car ~s~OFF");
|
||||
}
|
||||
|
||||
function toggleVehicleInvisible(state) {
|
||||
vehicleOptions.invisible = state;
|
||||
let playerPed = natives.GET_PLAYER_PED(natives.GET_PLAYER_ID());
|
||||
if (natives.IS_CHAR_IN_ANY_CAR(playerPed)) {
|
||||
let vehicle = natives.GET_CAR_CHAR_IS_USING(playerPed);
|
||||
natives.SET_CAR_VISIBLE(vehicle, !state);
|
||||
}
|
||||
showNotification(state ? "~g~Invisible Vehicle ~s~ON" : "~r~Invisible Vehicle ~s~OFF");
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ACTION FUNCTIONS
|
||||
// ============================================================================
|
||||
|
||||
function spawnVehicleAction(modelHash) {
|
||||
spawnVehicleForPlayer(modelHash);
|
||||
}
|
||||
|
||||
function spawnVehicleForPlayer(modelHash) {
|
||||
let playerId = natives.GET_PLAYER_ID();
|
||||
let playerPed = natives.GET_PLAYER_PED(playerId);
|
||||
|
||||
let pos = natives.GET_CHAR_COORDINATES(playerPed);
|
||||
let heading = natives.GET_CHAR_HEADING(playerPed);
|
||||
|
||||
// Request model
|
||||
natives.REQUEST_MODEL(modelHash);
|
||||
|
||||
// Wait for model to load
|
||||
let attempts = 0;
|
||||
while (!natives.HAS_MODEL_LOADED(modelHash) && attempts < 100) {
|
||||
natives.WAIT(10);
|
||||
attempts++;
|
||||
}
|
||||
|
||||
if (!natives.HAS_MODEL_LOADED(modelHash)) {
|
||||
showNotification("~r~Failed to load vehicle model!");
|
||||
return null;
|
||||
}
|
||||
|
||||
// Calculate spawn position in front of player
|
||||
let radians = heading * Math.PI / 180;
|
||||
let spawnX = pos[0] - Math.sin(radians) * 5;
|
||||
let spawnY = pos[1] + Math.cos(radians) * 5;
|
||||
let spawnZ = pos[2];
|
||||
|
||||
// Create vehicle
|
||||
let vehicle = natives.CREATE_CAR(modelHash, spawnX, spawnY, spawnZ, true, true);
|
||||
|
||||
if (vehicle) {
|
||||
natives.SET_CAR_HEADING(vehicle, heading);
|
||||
natives.SET_CAR_ON_GROUND_PROPERLY(vehicle);
|
||||
|
||||
// Get vehicle display name
|
||||
let vehName = natives.GET_DISPLAY_NAME_FROM_VEHICLE_MODEL(modelHash);
|
||||
let displayName = natives.GET_STRING_FROM_TEXT_FILE(vehName) || "Vehicle";
|
||||
|
||||
showNotification("~g~Spawned: ~s~" + displayName);
|
||||
}
|
||||
|
||||
// Mark model as no longer needed
|
||||
natives.MARK_MODEL_AS_NO_LONGER_NEEDED(modelHash);
|
||||
|
||||
return vehicle;
|
||||
}
|
||||
|
||||
function repairVehicle() {
|
||||
let playerPed = natives.GET_PLAYER_PED(natives.GET_PLAYER_ID());
|
||||
if (!natives.IS_CHAR_IN_ANY_CAR(playerPed)) {
|
||||
showNotification("~r~You are not in a vehicle!");
|
||||
return;
|
||||
}
|
||||
|
||||
let vehicle = natives.GET_CAR_CHAR_IS_USING(playerPed);
|
||||
natives.FIX_CAR(vehicle);
|
||||
natives.SET_CAR_ENGINE_ON(vehicle, true, true);
|
||||
showNotification("~g~Vehicle repaired!");
|
||||
}
|
||||
|
||||
function flipVehicle() {
|
||||
let playerPed = natives.GET_PLAYER_PED(natives.GET_PLAYER_ID());
|
||||
if (!natives.IS_CHAR_IN_ANY_CAR(playerPed)) {
|
||||
showNotification("~r~You are not in a vehicle!");
|
||||
return;
|
||||
}
|
||||
|
||||
let vehicle = natives.GET_CAR_CHAR_IS_USING(playerPed);
|
||||
let heading = natives.GET_CAR_HEADING(vehicle);
|
||||
natives.SET_VEHICLE_QUATERNION(vehicle, 0, 0, 0, 0);
|
||||
natives.SET_CAR_HEADING(vehicle, heading);
|
||||
natives.SET_CAR_ON_GROUND_PROPERLY(vehicle);
|
||||
showNotification("~g~Vehicle flipped!");
|
||||
}
|
||||
|
||||
function cleanVehicle() {
|
||||
let playerPed = natives.GET_PLAYER_PED(natives.GET_PLAYER_ID());
|
||||
if (!natives.IS_CHAR_IN_ANY_CAR(playerPed)) {
|
||||
showNotification("~r~You are not in a vehicle!");
|
||||
return;
|
||||
}
|
||||
|
||||
let vehicle = natives.GET_CAR_CHAR_IS_USING(playerPed);
|
||||
natives.SET_VEHICLE_DIRT_LEVEL(vehicle, 0);
|
||||
showNotification("~g~Vehicle cleaned!");
|
||||
}
|
||||
|
||||
function maxPerformance() {
|
||||
let playerPed = natives.GET_PLAYER_PED(natives.GET_PLAYER_ID());
|
||||
if (!natives.IS_CHAR_IN_ANY_CAR(playerPed)) {
|
||||
showNotification("~r~You are not in a vehicle!");
|
||||
return;
|
||||
}
|
||||
|
||||
let vehicle = natives.GET_CAR_CHAR_IS_USING(playerPed);
|
||||
// Set max performance (if supported)
|
||||
natives.FIX_CAR(vehicle);
|
||||
natives.SET_CAR_ENGINE_ON(vehicle, true, true);
|
||||
showNotification("~g~Vehicle maxed out!");
|
||||
}
|
||||
|
||||
function deleteVehicle() {
|
||||
let playerPed = natives.GET_PLAYER_PED(natives.GET_PLAYER_ID());
|
||||
if (!natives.IS_CHAR_IN_ANY_CAR(playerPed)) {
|
||||
showNotification("~r~You are not in a vehicle!");
|
||||
return;
|
||||
}
|
||||
|
||||
let vehicle = natives.GET_CAR_CHAR_IS_USING(playerPed);
|
||||
|
||||
// Eject player first
|
||||
natives.TASK_LEAVE_CAR_IMMEDIATELY(playerPed, vehicle);
|
||||
natives.WAIT(500);
|
||||
|
||||
natives.DELETE_CAR(vehicle);
|
||||
showNotification("~g~Vehicle deleted!");
|
||||
}
|
||||
|
||||
function teleportToNearestVehicle() {
|
||||
let playerPed = natives.GET_PLAYER_PED(natives.GET_PLAYER_ID());
|
||||
let pos = natives.GET_CHAR_COORDINATES(playerPed);
|
||||
|
||||
let vehicle = natives.GET_CLOSEST_CAR(pos[0], pos[1], pos[2], 100.0, false, 70);
|
||||
|
||||
if (vehicle && natives.DOES_VEHICLE_EXIST(vehicle)) {
|
||||
natives.WARP_CHAR_INTO_CAR(playerPed, vehicle);
|
||||
showNotification("~g~Teleported to nearest vehicle!");
|
||||
} else {
|
||||
showNotification("~r~No vehicle found nearby!");
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// VEHICLE OPTIONS LOOP
|
||||
// ============================================================================
|
||||
|
||||
let rainbowColor = 0;
|
||||
|
||||
function vehicleOptionsLoop() {
|
||||
let playerId = natives.GET_PLAYER_ID();
|
||||
let playerPed = natives.GET_PLAYER_PED(playerId);
|
||||
|
||||
if (!natives.IS_CHAR_IN_ANY_CAR(playerPed)) return;
|
||||
|
||||
let vehicle = natives.GET_CAR_CHAR_IS_USING(playerPed);
|
||||
|
||||
// Vehicle God Mode
|
||||
if (vehicleOptions.godmode) {
|
||||
natives.SET_CAR_CAN_BE_DAMAGED(vehicle, false);
|
||||
natives.SET_CAR_CAN_BE_VISIBLY_DAMAGED(vehicle, false);
|
||||
let health = natives.GET_CAR_HEALTH(vehicle);
|
||||
if (health < 1000) {
|
||||
natives.SET_CAR_HEALTH(vehicle, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
// Speed Boost
|
||||
if (vehicleOptions.speedBoost) {
|
||||
if (natives.IS_GAME_KEYBOARD_KEY_PRESSED(0x10)) { // Shift
|
||||
natives.APPLY_FORCE_TO_CAR(vehicle, true, 0.0, 50.0, 0.0, 0.0, 0.0, 0.0, true, true, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Auto Flip
|
||||
if (vehicleOptions.autoFlip) {
|
||||
if (!natives.IS_CAR_UPRIGHT(vehicle)) {
|
||||
let heading = natives.GET_CAR_HEADING(vehicle);
|
||||
natives.SET_VEHICLE_QUATERNION(vehicle, 0, 0, 0, 0);
|
||||
natives.SET_CAR_HEADING(vehicle, heading);
|
||||
natives.SET_CAR_ON_GROUND_PROPERLY(vehicle);
|
||||
}
|
||||
}
|
||||
|
||||
// Auto Fix
|
||||
if (vehicleOptions.autoFix) {
|
||||
let health = natives.GET_CAR_HEALTH(vehicle);
|
||||
if (health < 800) {
|
||||
natives.FIX_CAR(vehicle);
|
||||
}
|
||||
}
|
||||
|
||||
// Rainbow Car
|
||||
if (vehicleOptions.rainbow) {
|
||||
rainbowColor = (rainbowColor + 1) % 134;
|
||||
natives.CHANGE_CAR_COLOUR(vehicle, rainbowColor, rainbowColor);
|
||||
}
|
||||
|
||||
// Invisible Vehicle (maintain state)
|
||||
if (vehicleOptions.invisible) {
|
||||
natives.SET_CAR_VISIBLE(vehicle, false);
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// EVENT HANDLERS
|
||||
// ============================================================================
|
||||
|
||||
addEventHandler("OnProcess", function(event) {
|
||||
vehicleOptionsLoop();
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
// EXPORTS
|
||||
// ============================================================================
|
||||
|
||||
this.vehicleOptions = vehicleOptions;
|
||||
this.getVehicleMenuItems = getVehicleMenuItems;
|
||||
this.getFavoriteVehicleItems = getFavoriteVehicleItems;
|
||||
this.getSportsVehicleItems = getSportsVehicleItems;
|
||||
this.getMuscleVehicleItems = getMuscleVehicleItems;
|
||||
this.getSUVVehicleItems = getSUVVehicleItems;
|
||||
this.getSedanVehicleItems = getSedanVehicleItems;
|
||||
this.getEmergencyVehicleItems = getEmergencyVehicleItems;
|
||||
this.getBikeVehicleItems = getBikeVehicleItems;
|
||||
this.getBoatVehicleItems = getBoatVehicleItems;
|
||||
this.getHelicopterVehicleItems = getHelicopterVehicleItems;
|
||||
this.getCommercialVehicleItems = getCommercialVehicleItems;
|
||||
this.spawnVehicleForPlayer = spawnVehicleForPlayer;
|
||||
286
Trident/weapon.js
Normal file
286
Trident/weapon.js
Normal file
@@ -0,0 +1,286 @@
|
||||
/**
|
||||
* MD TRIDENT - Weapon Options Module
|
||||
* GTAConnected Port for GTA IV
|
||||
*/
|
||||
|
||||
// ============================================================================
|
||||
// WEAPON HASHES (GTA IV)
|
||||
// ============================================================================
|
||||
|
||||
const WEAPONS = {
|
||||
// Melee
|
||||
UNARMED: 0,
|
||||
BASEBALLBAT: 1,
|
||||
POOLCUE: 2,
|
||||
KNIFE: 3,
|
||||
|
||||
// Handguns
|
||||
GLOCK: 4,
|
||||
DESERTEAGLE: 5,
|
||||
PISTOL44: 6,
|
||||
|
||||
// SMGs
|
||||
MICRO_UZI: 7,
|
||||
MP5: 8,
|
||||
SMG: 9,
|
||||
|
||||
// Shotguns
|
||||
SAWNOFF: 10,
|
||||
BARETTA: 11,
|
||||
COMBATSHOTGUN: 12,
|
||||
|
||||
// Rifles
|
||||
M4: 13,
|
||||
AK47: 14,
|
||||
|
||||
// Snipers
|
||||
SNIPER: 15,
|
||||
M40A1: 16,
|
||||
PSG1: 17,
|
||||
|
||||
// Heavy
|
||||
RPG: 18,
|
||||
|
||||
// Thrown
|
||||
GRENADE: 16,
|
||||
MOLOTOV: 17
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// WEAPON OPTIONS STATE
|
||||
// ============================================================================
|
||||
|
||||
let weaponOptions = {
|
||||
infiniteAmmo: false,
|
||||
rapidFire: false,
|
||||
explosiveAmmo: false,
|
||||
oneHitKill: false
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// WEAPON MENU ITEMS
|
||||
// ============================================================================
|
||||
|
||||
function getWeaponMenuItems() {
|
||||
return [
|
||||
createMenuItem("~~ WEAPON OPTIONS ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("Infinite Ammo", ITEM_TYPE.BOOL, {
|
||||
boolState: weaponOptions.infiniteAmmo,
|
||||
action: toggleInfiniteAmmo
|
||||
}),
|
||||
createMenuItem("Rapid Fire", ITEM_TYPE.BOOL, {
|
||||
boolState: weaponOptions.rapidFire,
|
||||
action: toggleRapidFire
|
||||
}),
|
||||
createMenuItem("Explosive Ammo", ITEM_TYPE.BOOL, {
|
||||
boolState: weaponOptions.explosiveAmmo,
|
||||
action: toggleExplosiveAmmo
|
||||
}),
|
||||
createMenuItem("One Hit Kill", ITEM_TYPE.BOOL, {
|
||||
boolState: weaponOptions.oneHitKill,
|
||||
action: toggleOneHitKill
|
||||
}),
|
||||
|
||||
createMenuItem("~~ GIVE WEAPONS ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("Give All Weapons", ITEM_TYPE.FUNCTION, { action: giveAllWeaponsAction }),
|
||||
createMenuItem("Give Handguns", ITEM_TYPE.FUNCTION, { action: giveHandguns }),
|
||||
createMenuItem("Give SMGs", ITEM_TYPE.FUNCTION, { action: giveSMGs }),
|
||||
createMenuItem("Give Shotguns", ITEM_TYPE.FUNCTION, { action: giveShotguns }),
|
||||
createMenuItem("Give Rifles", ITEM_TYPE.FUNCTION, { action: giveRifles }),
|
||||
createMenuItem("Give Snipers", ITEM_TYPE.FUNCTION, { action: giveSnipers }),
|
||||
createMenuItem("Give Heavy Weapons", ITEM_TYPE.FUNCTION, { action: giveHeavy }),
|
||||
createMenuItem("Give Thrown Weapons", ITEM_TYPE.FUNCTION, { action: giveThrown }),
|
||||
createMenuItem("Give Melee Weapons", ITEM_TYPE.FUNCTION, { action: giveMelee }),
|
||||
|
||||
createMenuItem("~~ AMMO ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("Max Ammo All Weapons", ITEM_TYPE.FUNCTION, { action: maxAmmoAllWeapons }),
|
||||
createMenuItem("Remove All Weapons", ITEM_TYPE.FUNCTION, { action: removeAllWeaponsAction }),
|
||||
|
||||
createMenuItem("~~ INDIVIDUAL WEAPONS ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("Spawn: Baseball Bat", ITEM_TYPE.FUNCTION, { action: () => giveWeapon(WEAPONS.BASEBALLBAT) }),
|
||||
createMenuItem("Spawn: Knife", ITEM_TYPE.FUNCTION, { action: () => giveWeapon(WEAPONS.KNIFE) }),
|
||||
createMenuItem("Spawn: Glock", ITEM_TYPE.FUNCTION, { action: () => giveWeapon(WEAPONS.GLOCK) }),
|
||||
createMenuItem("Spawn: Desert Eagle", ITEM_TYPE.FUNCTION, { action: () => giveWeapon(WEAPONS.DESERTEAGLE) }),
|
||||
createMenuItem("Spawn: Micro Uzi", ITEM_TYPE.FUNCTION, { action: () => giveWeapon(WEAPONS.MICRO_UZI) }),
|
||||
createMenuItem("Spawn: MP5", ITEM_TYPE.FUNCTION, { action: () => giveWeapon(WEAPONS.MP5) }),
|
||||
createMenuItem("Spawn: Sawn-off", ITEM_TYPE.FUNCTION, { action: () => giveWeapon(WEAPONS.SAWNOFF) }),
|
||||
createMenuItem("Spawn: Combat Shotgun", ITEM_TYPE.FUNCTION, { action: () => giveWeapon(WEAPONS.COMBATSHOTGUN) }),
|
||||
createMenuItem("Spawn: M4", ITEM_TYPE.FUNCTION, { action: () => giveWeapon(WEAPONS.M4) }),
|
||||
createMenuItem("Spawn: AK-47", ITEM_TYPE.FUNCTION, { action: () => giveWeapon(WEAPONS.AK47) }),
|
||||
createMenuItem("Spawn: Sniper Rifle", ITEM_TYPE.FUNCTION, { action: () => giveWeapon(WEAPONS.SNIPER) }),
|
||||
createMenuItem("Spawn: RPG", ITEM_TYPE.FUNCTION, { action: () => giveWeapon(WEAPONS.RPG) }),
|
||||
createMenuItem("Spawn: Grenades", ITEM_TYPE.FUNCTION, { action: () => giveWeapon(WEAPONS.GRENADE) }),
|
||||
createMenuItem("Spawn: Molotovs", ITEM_TYPE.FUNCTION, { action: () => giveWeapon(WEAPONS.MOLOTOV) })
|
||||
];
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// TOGGLE FUNCTIONS
|
||||
// ============================================================================
|
||||
|
||||
function toggleInfiniteAmmo(state) {
|
||||
weaponOptions.infiniteAmmo = state;
|
||||
showNotification(state ? "~g~Infinite Ammo ~s~ON" : "~r~Infinite Ammo ~s~OFF");
|
||||
}
|
||||
|
||||
function toggleRapidFire(state) {
|
||||
weaponOptions.rapidFire = state;
|
||||
showNotification(state ? "~g~Rapid Fire ~s~ON" : "~r~Rapid Fire ~s~OFF");
|
||||
}
|
||||
|
||||
function toggleExplosiveAmmo(state) {
|
||||
weaponOptions.explosiveAmmo = state;
|
||||
showNotification(state ? "~g~Explosive Ammo ~s~ON" : "~r~Explosive Ammo ~s~OFF");
|
||||
}
|
||||
|
||||
function toggleOneHitKill(state) {
|
||||
weaponOptions.oneHitKill = state;
|
||||
showNotification(state ? "~g~One Hit Kill ~s~ON" : "~r~One Hit Kill ~s~OFF");
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// WEAPON FUNCTIONS
|
||||
// ============================================================================
|
||||
|
||||
function giveWeapon(weaponId, ammo = 9999) {
|
||||
let playerPed = natives.GET_PLAYER_PED(natives.GET_PLAYER_ID());
|
||||
natives.GIVE_WEAPON_TO_CHAR(playerPed, weaponId, ammo, false);
|
||||
showNotification("~g~Weapon given!");
|
||||
}
|
||||
|
||||
function giveAllWeaponsAction() {
|
||||
let playerPed = natives.GET_PLAYER_PED(natives.GET_PLAYER_ID());
|
||||
let episode = natives.GET_CURRENT_EPISODE();
|
||||
natives.GIVE_EPISODIC_WEAPONS_TO_CHAR(playerPed, episode);
|
||||
showNotification("~g~All weapons given!");
|
||||
}
|
||||
|
||||
function giveHandguns() {
|
||||
let playerPed = natives.GET_PLAYER_PED(natives.GET_PLAYER_ID());
|
||||
natives.GIVE_WEAPON_TO_CHAR(playerPed, WEAPONS.GLOCK, 9999, false);
|
||||
natives.GIVE_WEAPON_TO_CHAR(playerPed, WEAPONS.DESERTEAGLE, 9999, false);
|
||||
natives.GIVE_WEAPON_TO_CHAR(playerPed, WEAPONS.PISTOL44, 9999, false);
|
||||
showNotification("~g~Handguns given!");
|
||||
}
|
||||
|
||||
function giveSMGs() {
|
||||
let playerPed = natives.GET_PLAYER_PED(natives.GET_PLAYER_ID());
|
||||
natives.GIVE_WEAPON_TO_CHAR(playerPed, WEAPONS.MICRO_UZI, 9999, false);
|
||||
natives.GIVE_WEAPON_TO_CHAR(playerPed, WEAPONS.MP5, 9999, false);
|
||||
natives.GIVE_WEAPON_TO_CHAR(playerPed, WEAPONS.SMG, 9999, false);
|
||||
showNotification("~g~SMGs given!");
|
||||
}
|
||||
|
||||
function giveShotguns() {
|
||||
let playerPed = natives.GET_PLAYER_PED(natives.GET_PLAYER_ID());
|
||||
natives.GIVE_WEAPON_TO_CHAR(playerPed, WEAPONS.SAWNOFF, 9999, false);
|
||||
natives.GIVE_WEAPON_TO_CHAR(playerPed, WEAPONS.BARETTA, 9999, false);
|
||||
natives.GIVE_WEAPON_TO_CHAR(playerPed, WEAPONS.COMBATSHOTGUN, 9999, false);
|
||||
showNotification("~g~Shotguns given!");
|
||||
}
|
||||
|
||||
function giveRifles() {
|
||||
let playerPed = natives.GET_PLAYER_PED(natives.GET_PLAYER_ID());
|
||||
natives.GIVE_WEAPON_TO_CHAR(playerPed, WEAPONS.M4, 9999, false);
|
||||
natives.GIVE_WEAPON_TO_CHAR(playerPed, WEAPONS.AK47, 9999, false);
|
||||
showNotification("~g~Rifles given!");
|
||||
}
|
||||
|
||||
function giveSnipers() {
|
||||
let playerPed = natives.GET_PLAYER_PED(natives.GET_PLAYER_ID());
|
||||
natives.GIVE_WEAPON_TO_CHAR(playerPed, WEAPONS.SNIPER, 9999, false);
|
||||
natives.GIVE_WEAPON_TO_CHAR(playerPed, WEAPONS.M40A1, 9999, false);
|
||||
natives.GIVE_WEAPON_TO_CHAR(playerPed, WEAPONS.PSG1, 9999, false);
|
||||
showNotification("~g~Sniper rifles given!");
|
||||
}
|
||||
|
||||
function giveHeavy() {
|
||||
let playerPed = natives.GET_PLAYER_PED(natives.GET_PLAYER_ID());
|
||||
natives.GIVE_WEAPON_TO_CHAR(playerPed, WEAPONS.RPG, 9999, false);
|
||||
showNotification("~g~Heavy weapons given!");
|
||||
}
|
||||
|
||||
function giveThrown() {
|
||||
let playerPed = natives.GET_PLAYER_PED(natives.GET_PLAYER_ID());
|
||||
natives.GIVE_WEAPON_TO_CHAR(playerPed, WEAPONS.GRENADE, 25, false);
|
||||
natives.GIVE_WEAPON_TO_CHAR(playerPed, WEAPONS.MOLOTOV, 25, false);
|
||||
showNotification("~g~Thrown weapons given!");
|
||||
}
|
||||
|
||||
function giveMelee() {
|
||||
let playerPed = natives.GET_PLAYER_PED(natives.GET_PLAYER_ID());
|
||||
natives.GIVE_WEAPON_TO_CHAR(playerPed, WEAPONS.BASEBALLBAT, 1, false);
|
||||
natives.GIVE_WEAPON_TO_CHAR(playerPed, WEAPONS.POOLCUE, 1, false);
|
||||
natives.GIVE_WEAPON_TO_CHAR(playerPed, WEAPONS.KNIFE, 1, false);
|
||||
showNotification("~g~Melee weapons given!");
|
||||
}
|
||||
|
||||
function maxAmmoAllWeapons() {
|
||||
let playerPed = natives.GET_PLAYER_PED(natives.GET_PLAYER_ID());
|
||||
|
||||
// Add ammo to all weapon types
|
||||
for (let weaponId = 1; weaponId <= 18; weaponId++) {
|
||||
if (natives.HAS_CHAR_GOT_WEAPON(playerPed, weaponId)) {
|
||||
natives.ADD_AMMO_TO_CHAR(playerPed, weaponId, 9999);
|
||||
}
|
||||
}
|
||||
|
||||
showNotification("~g~Max ammo added to all weapons!");
|
||||
}
|
||||
|
||||
function removeAllWeaponsAction() {
|
||||
let playerPed = natives.GET_PLAYER_PED(natives.GET_PLAYER_ID());
|
||||
natives.REMOVE_ALL_CHAR_WEAPONS(playerPed);
|
||||
showNotification("~r~All weapons removed!");
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// WEAPON OPTIONS LOOP
|
||||
// ============================================================================
|
||||
|
||||
function weaponOptionsLoop() {
|
||||
let playerId = natives.GET_PLAYER_ID();
|
||||
let playerPed = natives.GET_PLAYER_PED(playerId);
|
||||
|
||||
if (!natives.DOES_CHAR_EXIST(playerPed)) return;
|
||||
|
||||
// Infinite Ammo
|
||||
if (weaponOptions.infiniteAmmo && natives.IS_CHAR_SHOOTING(playerPed)) {
|
||||
let weapon = natives.GET_CURRENT_CHAR_WEAPON(playerPed);
|
||||
if (weapon !== WEAPONS.GRENADE && weapon !== WEAPONS.MOLOTOV) {
|
||||
let maxAmmo = natives.GET_MAX_AMMO_IN_CLIP(playerPed, weapon);
|
||||
if (maxAmmo) {
|
||||
natives.SET_AMMO_IN_CLIP(playerPed, weapon, maxAmmo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Explosive Ammo
|
||||
if (weaponOptions.explosiveAmmo && natives.IS_CHAR_SHOOTING(playerPed)) {
|
||||
let weapon = natives.GET_CURRENT_CHAR_WEAPON(playerPed);
|
||||
if (weapon !== WEAPONS.GRENADE && weapon !== WEAPONS.MOLOTOV && weapon !== WEAPONS.RPG) {
|
||||
// Get aimed position and create explosion
|
||||
let aimPos = natives.GET_PED_BONE_COORDS(playerPed, 57, 0, 0, 50);
|
||||
if (aimPos) {
|
||||
natives.ADD_EXPLOSION(aimPos[0], aimPos[1], aimPos[2], 2, 1.0, true, false, 0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// EVENT HANDLERS
|
||||
// ============================================================================
|
||||
|
||||
addEventHandler("OnProcess", function(event) {
|
||||
weaponOptionsLoop();
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
// EXPORTS
|
||||
// ============================================================================
|
||||
|
||||
this.weaponOptions = weaponOptions;
|
||||
this.getWeaponMenuItems = getWeaponMenuItems;
|
||||
this.giveAllWeaponsAction = giveAllWeaponsAction;
|
||||
this.removeAllWeaponsAction = removeAllWeaponsAction;
|
||||
488
Trident/world.js
Normal file
488
Trident/world.js
Normal file
@@ -0,0 +1,488 @@
|
||||
/**
|
||||
* MD TRIDENT - World Options Module (Weather & Time)
|
||||
* GTAConnected Port for GTA IV
|
||||
*/
|
||||
|
||||
// ============================================================================
|
||||
// WEATHER TYPES (GTA IV)
|
||||
// ============================================================================
|
||||
|
||||
const WEATHER_TYPES = {
|
||||
EXTRA_SUNNY: 0,
|
||||
SUNNY: 1,
|
||||
SUNNY_WINDY: 2,
|
||||
CLOUDY: 3,
|
||||
RAINING: 4,
|
||||
DRIZZLE: 5,
|
||||
FOGGY: 6,
|
||||
THUNDERSTORM: 7,
|
||||
EXTRA_SUNNY_2: 8,
|
||||
SUNNY_WINDY_2: 9
|
||||
};
|
||||
|
||||
const WEATHER_NAMES = [
|
||||
"Extra Sunny",
|
||||
"Sunny",
|
||||
"Sunny Windy",
|
||||
"Cloudy",
|
||||
"Raining",
|
||||
"Drizzle",
|
||||
"Foggy",
|
||||
"Thunderstorm",
|
||||
"Extra Sunny 2",
|
||||
"Sunny Windy 2"
|
||||
];
|
||||
|
||||
// ============================================================================
|
||||
// WORLD OPTIONS STATE
|
||||
// ============================================================================
|
||||
|
||||
let worldOptions = {
|
||||
timeFrozen: false,
|
||||
weatherLocked: false,
|
||||
currentWeather: 1,
|
||||
currentHour: 12,
|
||||
currentMinute: 0
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// WEATHER MENU ITEMS
|
||||
// ============================================================================
|
||||
|
||||
function getWeatherMenuItems() {
|
||||
return [
|
||||
createMenuItem("~~ TIME CONTROL ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("Set Hour", ITEM_TYPE.VALUE_NUM, {
|
||||
value: worldOptions.currentHour,
|
||||
minValue: 0,
|
||||
maxValue: 23,
|
||||
action: setHour
|
||||
}),
|
||||
createMenuItem("Set Minute", ITEM_TYPE.VALUE_NUM, {
|
||||
value: worldOptions.currentMinute,
|
||||
minValue: 0,
|
||||
maxValue: 59,
|
||||
action: setMinute
|
||||
}),
|
||||
createMenuItem("Freeze Time", ITEM_TYPE.BOOL, {
|
||||
boolState: worldOptions.timeFrozen,
|
||||
action: toggleFreezeTime
|
||||
}),
|
||||
|
||||
createMenuItem("~~ QUICK TIME ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("Morning (06:00)", ITEM_TYPE.FUNCTION, { action: () => setTimeQuick(6, 0) }),
|
||||
createMenuItem("Noon (12:00)", ITEM_TYPE.FUNCTION, { action: () => setTimeQuick(12, 0) }),
|
||||
createMenuItem("Evening (18:00)", ITEM_TYPE.FUNCTION, { action: () => setTimeQuick(18, 0) }),
|
||||
createMenuItem("Midnight (00:00)", ITEM_TYPE.FUNCTION, { action: () => setTimeQuick(0, 0) }),
|
||||
createMenuItem("Night (22:00)", ITEM_TYPE.FUNCTION, { action: () => setTimeQuick(22, 0) }),
|
||||
|
||||
createMenuItem("~~ WEATHER CONTROL ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("Select Weather", ITEM_TYPE.VALUE_STRING, {
|
||||
value: worldOptions.currentWeather,
|
||||
stringValues: WEATHER_NAMES,
|
||||
action: setWeather
|
||||
}),
|
||||
createMenuItem("Lock Weather", ITEM_TYPE.BOOL, {
|
||||
boolState: worldOptions.weatherLocked,
|
||||
action: toggleLockWeather
|
||||
}),
|
||||
|
||||
createMenuItem("~~ QUICK WEATHER ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("Extra Sunny", ITEM_TYPE.FUNCTION, { action: () => setWeatherQuick(WEATHER_TYPES.EXTRA_SUNNY) }),
|
||||
createMenuItem("Sunny", ITEM_TYPE.FUNCTION, { action: () => setWeatherQuick(WEATHER_TYPES.SUNNY) }),
|
||||
createMenuItem("Cloudy", ITEM_TYPE.FUNCTION, { action: () => setWeatherQuick(WEATHER_TYPES.CLOUDY) }),
|
||||
createMenuItem("Raining", ITEM_TYPE.FUNCTION, { action: () => setWeatherQuick(WEATHER_TYPES.RAINING) }),
|
||||
createMenuItem("Thunderstorm", ITEM_TYPE.FUNCTION, { action: () => setWeatherQuick(WEATHER_TYPES.THUNDERSTORM) }),
|
||||
createMenuItem("Foggy", ITEM_TYPE.FUNCTION, { action: () => setWeatherQuick(WEATHER_TYPES.FOGGY) }),
|
||||
createMenuItem("Drizzle", ITEM_TYPE.FUNCTION, { action: () => setWeatherQuick(WEATHER_TYPES.DRIZZLE) }),
|
||||
|
||||
createMenuItem("~~ WORLD OPTIONS ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("Random Weather", ITEM_TYPE.FUNCTION, { action: randomWeather }),
|
||||
createMenuItem("Release Weather Lock", ITEM_TYPE.FUNCTION, { action: releaseWeather }),
|
||||
createMenuItem("Clear Area of Peds", ITEM_TYPE.FUNCTION, { action: clearAreaPeds }),
|
||||
createMenuItem("Clear Area of Vehicles", ITEM_TYPE.FUNCTION, { action: clearAreaVehicles })
|
||||
];
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// TIME FUNCTIONS
|
||||
// ============================================================================
|
||||
|
||||
function setHour(hour) {
|
||||
worldOptions.currentHour = hour;
|
||||
natives.SET_TIME_OF_DAY(hour, worldOptions.currentMinute);
|
||||
showNotification("~b~Time set to: ~s~" + hour.toString().padStart(2, '0') + ":" + worldOptions.currentMinute.toString().padStart(2, '0'));
|
||||
}
|
||||
|
||||
function setMinute(minute) {
|
||||
worldOptions.currentMinute = minute;
|
||||
natives.SET_TIME_OF_DAY(worldOptions.currentHour, minute);
|
||||
showNotification("~b~Time set to: ~s~" + worldOptions.currentHour.toString().padStart(2, '0') + ":" + minute.toString().padStart(2, '0'));
|
||||
}
|
||||
|
||||
function setTimeQuick(hour, minute) {
|
||||
worldOptions.currentHour = hour;
|
||||
worldOptions.currentMinute = minute;
|
||||
natives.SET_TIME_OF_DAY(hour, minute);
|
||||
showNotification("~b~Time set to: ~s~" + hour.toString().padStart(2, '0') + ":" + minute.toString().padStart(2, '0'));
|
||||
}
|
||||
|
||||
function toggleFreezeTime(state) {
|
||||
worldOptions.timeFrozen = state;
|
||||
// In GTA IV, we control time by repeatedly setting it in the loop
|
||||
showNotification(state ? "~g~Time Frozen ~s~ON" : "~r~Time Frozen ~s~OFF");
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// WEATHER FUNCTIONS
|
||||
// ============================================================================
|
||||
|
||||
function setWeather(weatherIndex) {
|
||||
worldOptions.currentWeather = weatherIndex;
|
||||
natives.FORCE_WEATHER_NOW(weatherIndex);
|
||||
showNotification("~b~Weather set to: ~s~" + WEATHER_NAMES[weatherIndex]);
|
||||
}
|
||||
|
||||
function setWeatherQuick(weatherType) {
|
||||
worldOptions.currentWeather = weatherType;
|
||||
natives.FORCE_WEATHER_NOW(weatherType);
|
||||
worldOptions.weatherLocked = true;
|
||||
showNotification("~b~Weather set to: ~s~" + WEATHER_NAMES[weatherType]);
|
||||
}
|
||||
|
||||
function toggleLockWeather(state) {
|
||||
worldOptions.weatherLocked = state;
|
||||
if (state) {
|
||||
worldOptions.currentWeather = natives.GET_CURRENT_WEATHER() || 1;
|
||||
}
|
||||
showNotification(state ? "~g~Weather Locked ~s~ON" : "~r~Weather Locked ~s~OFF");
|
||||
}
|
||||
|
||||
function releaseWeather() {
|
||||
worldOptions.weatherLocked = false;
|
||||
natives.RELEASE_WEATHER();
|
||||
showNotification("~g~Weather released!");
|
||||
}
|
||||
|
||||
function randomWeather() {
|
||||
let randomType = Math.floor(Math.random() * 8);
|
||||
setWeatherQuick(randomType);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// WORLD CLEANUP FUNCTIONS
|
||||
// ============================================================================
|
||||
|
||||
function clearAreaPeds() {
|
||||
let playerPed = natives.GET_PLAYER_PED(natives.GET_PLAYER_ID());
|
||||
let pos = natives.GET_CHAR_COORDINATES(playerPed);
|
||||
|
||||
natives.CLEAR_AREA_OF_CHARS(pos[0], pos[1], pos[2], 100.0);
|
||||
showNotification("~g~Area cleared of peds!");
|
||||
}
|
||||
|
||||
function clearAreaVehicles() {
|
||||
let playerPed = natives.GET_PLAYER_PED(natives.GET_PLAYER_ID());
|
||||
let pos = natives.GET_CHAR_COORDINATES(playerPed);
|
||||
|
||||
natives.CLEAR_AREA_OF_CARS(pos[0], pos[1], pos[2], 100.0);
|
||||
showNotification("~g~Area cleared of vehicles!");
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// WORLD OPTIONS LOOP
|
||||
// ============================================================================
|
||||
|
||||
function worldOptionsLoop() {
|
||||
// Freeze Time
|
||||
if (worldOptions.timeFrozen) {
|
||||
natives.SET_TIME_OF_DAY(worldOptions.currentHour, worldOptions.currentMinute);
|
||||
}
|
||||
|
||||
// Lock Weather
|
||||
if (worldOptions.weatherLocked) {
|
||||
natives.FORCE_WEATHER_NOW(worldOptions.currentWeather);
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ADDITIONAL MENU ITEMS
|
||||
// ============================================================================
|
||||
|
||||
function getModelMenuItems() {
|
||||
return [
|
||||
createMenuItem("~~ PLAYER MODELS ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("Change to Niko", ITEM_TYPE.FUNCTION, { action: changeToNiko }),
|
||||
createMenuItem("Change to Random Ped", ITEM_TYPE.FUNCTION, { action: changeToRandomPed }),
|
||||
createMenuItem("Reset Model", ITEM_TYPE.FUNCTION, { action: resetModel }),
|
||||
|
||||
createMenuItem("~~ PRESET MODELS ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("Police Officer", ITEM_TYPE.FUNCTION, { action: () => changeToModel("M_Y_COP") }),
|
||||
createMenuItem("NOOSE Officer", ITEM_TYPE.FUNCTION, { action: () => changeToModel("M_Y_SWAT") }),
|
||||
createMenuItem("Paramedic", ITEM_TYPE.FUNCTION, { action: () => changeToModel("M_M_PARAMEDIC") }),
|
||||
createMenuItem("Fireman", ITEM_TYPE.FUNCTION, { action: () => changeToModel("M_Y_FIREMAN") }),
|
||||
createMenuItem("Business Man", ITEM_TYPE.FUNCTION, { action: () => changeToModel("M_M_BUSINESSMAN") }),
|
||||
createMenuItem("Homeless", ITEM_TYPE.FUNCTION, { action: () => changeToModel("M_O_HOMELESS") }),
|
||||
createMenuItem("Biker", ITEM_TYPE.FUNCTION, { action: () => changeToModel("M_Y_GBIK01") }),
|
||||
createMenuItem("Mafia", ITEM_TYPE.FUNCTION, { action: () => changeToModel("M_M_PRICH_01") })
|
||||
];
|
||||
}
|
||||
|
||||
function getAnimationMenuItems() {
|
||||
return [
|
||||
createMenuItem("~~ ANIMATIONS ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("Play: Wave", ITEM_TYPE.FUNCTION, { action: () => playAnimation("amb@wave") }),
|
||||
createMenuItem("Play: Cheer", ITEM_TYPE.FUNCTION, { action: () => playAnimation("amb@cheering") }),
|
||||
createMenuItem("Play: Dance", ITEM_TYPE.FUNCTION, { action: () => playAnimation("amb@dancing_fem") }),
|
||||
createMenuItem("Play: Sit Down", ITEM_TYPE.FUNCTION, { action: () => playAnimation("amb@sitting") }),
|
||||
createMenuItem("Play: Smoking", ITEM_TYPE.FUNCTION, { action: () => playAnimation("amb@smoking") }),
|
||||
createMenuItem("Play: Push Ups", ITEM_TYPE.FUNCTION, { action: () => playAnimation("amb@pushups") }),
|
||||
createMenuItem("Clear Animation", ITEM_TYPE.FUNCTION, { action: clearAnimation })
|
||||
];
|
||||
}
|
||||
|
||||
function getObjectMenuItems() {
|
||||
return [
|
||||
createMenuItem("~~ OBJECT SPAWNER ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("Spawn: Barrel", ITEM_TYPE.FUNCTION, { action: () => spawnObject("prop_barrel_01") }),
|
||||
createMenuItem("Spawn: Cone", ITEM_TYPE.FUNCTION, { action: () => spawnObject("prop_cone") }),
|
||||
createMenuItem("Spawn: Ramp", ITEM_TYPE.FUNCTION, { action: () => spawnObject("prop_ramp") }),
|
||||
createMenuItem("Spawn: Fence", ITEM_TYPE.FUNCTION, { action: () => spawnObject("prop_fence") }),
|
||||
|
||||
createMenuItem("~~ OBJECT MANAGEMENT ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("Delete Nearest Object", ITEM_TYPE.FUNCTION, { action: deleteNearestObject }),
|
||||
createMenuItem("Delete All Spawned Objects", ITEM_TYPE.FUNCTION, { action: deleteAllSpawnedObjects })
|
||||
];
|
||||
}
|
||||
|
||||
function getSettingsMenuItems() {
|
||||
return [
|
||||
createMenuItem("~~ MENU SETTINGS ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("Menu Position X", ITEM_TYPE.VALUE_NUM, {
|
||||
value: Math.floor(MENU_CONFIG.posX * 100),
|
||||
minValue: 0,
|
||||
maxValue: 100,
|
||||
action: (val) => { MENU_CONFIG.posX = val / 100; }
|
||||
}),
|
||||
createMenuItem("Menu Position Y", ITEM_TYPE.VALUE_NUM, {
|
||||
value: Math.floor(MENU_CONFIG.posY * 100),
|
||||
minValue: 0,
|
||||
maxValue: 100,
|
||||
action: (val) => { MENU_CONFIG.posY = val / 100; }
|
||||
}),
|
||||
createMenuItem("Reset Menu Position", ITEM_TYPE.FUNCTION, { action: resetMenuPosition }),
|
||||
|
||||
createMenuItem("~~ GAME SETTINGS ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("Toggle HUD", ITEM_TYPE.FUNCTION, { action: toggleHUD }),
|
||||
createMenuItem("Toggle Radar", ITEM_TYPE.FUNCTION, { action: toggleRadar })
|
||||
];
|
||||
}
|
||||
|
||||
function getCreditsMenuItems() {
|
||||
return [
|
||||
createMenuItem("~~ MD TRIDENT ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("Version: v13 GTAConnected Port", ITEM_TYPE.ERROR),
|
||||
createMenuItem("~~ ORIGINAL AUTHORS ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("DEVILSDESIGN", ITEM_TYPE.ERROR),
|
||||
createMenuItem("IIV_NATHAN_VII", ITEM_TYPE.ERROR),
|
||||
createMenuItem("SHOCKixiXixiWAVE", ITEM_TYPE.ERROR),
|
||||
createMenuItem("~~ PORTED FOR ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("GTAConnected GTA IV Server", ITEM_TYPE.ERROR),
|
||||
createMenuItem("~~ THANK YOU ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("Thanks for using MD TRIDENT!", ITEM_TYPE.ERROR)
|
||||
];
|
||||
}
|
||||
|
||||
function getNetworkMenuItems() {
|
||||
// Get list of players for network options
|
||||
let items = [
|
||||
createMenuItem("~~ NETWORK OPTIONS ~~", ITEM_TYPE.JUMPOVER),
|
||||
createMenuItem("Player List", ITEM_TYPE.SUBMENU, { submenu: "player_list" }),
|
||||
createMenuItem("Spectate Player", ITEM_TYPE.FUNCTION, { action: spectatePlayer }),
|
||||
createMenuItem("Stop Spectating", ITEM_TYPE.FUNCTION, { action: stopSpectating })
|
||||
];
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// HELPER FUNCTIONS
|
||||
// ============================================================================
|
||||
|
||||
function changeToModel(modelName) {
|
||||
let playerId = natives.GET_PLAYER_ID();
|
||||
let modelHash = natives.GET_HASH_KEY(modelName);
|
||||
|
||||
natives.REQUEST_MODEL(modelHash);
|
||||
|
||||
let attempts = 0;
|
||||
while (!natives.HAS_MODEL_LOADED(modelHash) && attempts < 100) {
|
||||
natives.WAIT(10);
|
||||
attempts++;
|
||||
}
|
||||
|
||||
if (natives.HAS_MODEL_LOADED(modelHash)) {
|
||||
natives.CHANGE_PLAYER_MODEL(playerId, modelHash);
|
||||
natives.MARK_MODEL_AS_NO_LONGER_NEEDED(modelHash);
|
||||
showNotification("~g~Changed model to: ~s~" + modelName);
|
||||
} else {
|
||||
showNotification("~r~Failed to load model!");
|
||||
}
|
||||
}
|
||||
|
||||
function changeToNiko() {
|
||||
changeToModel("PLAYER");
|
||||
}
|
||||
|
||||
function changeToRandomPed() {
|
||||
let playerPed = natives.GET_PLAYER_PED(natives.GET_PLAYER_ID());
|
||||
natives.SET_CHAR_RANDOM_COMPONENT_VARIATION(playerPed);
|
||||
showNotification("~g~Random variation applied!");
|
||||
}
|
||||
|
||||
function resetModel() {
|
||||
let playerId = natives.GET_PLAYER_ID();
|
||||
let defaultModel = natives.GET_PLAYERSETTINGS_MODEL_CHOICE();
|
||||
natives.CHANGE_PLAYER_MODEL(playerId, defaultModel);
|
||||
showNotification("~g~Model reset!");
|
||||
}
|
||||
|
||||
function playAnimation(animName) {
|
||||
let playerPed = natives.GET_PLAYER_PED(natives.GET_PLAYER_ID());
|
||||
natives.REQUEST_ANIMS(animName);
|
||||
|
||||
let attempts = 0;
|
||||
while (!natives.HAVE_ANIMS_LOADED(animName) && attempts < 100) {
|
||||
natives.WAIT(10);
|
||||
attempts++;
|
||||
}
|
||||
|
||||
if (natives.HAVE_ANIMS_LOADED(animName)) {
|
||||
natives.TASK_PLAY_ANIM(playerPed, animName, animName, 4.0, false, false, false, false, -1);
|
||||
showNotification("~g~Playing animation!");
|
||||
} else {
|
||||
showNotification("~r~Failed to load animation!");
|
||||
}
|
||||
}
|
||||
|
||||
function clearAnimation() {
|
||||
let playerPed = natives.GET_PLAYER_PED(natives.GET_PLAYER_ID());
|
||||
natives.CLEAR_CHAR_TASKS(playerPed);
|
||||
showNotification("~g~Animation cleared!");
|
||||
}
|
||||
|
||||
let spawnedObjects = [];
|
||||
|
||||
function spawnObject(objectName) {
|
||||
let playerPed = natives.GET_PLAYER_PED(natives.GET_PLAYER_ID());
|
||||
let pos = natives.GET_OFFSET_FROM_CHAR_IN_WORLD_COORDS(playerPed, 0, 3, 0);
|
||||
|
||||
let modelHash = natives.GET_HASH_KEY(objectName);
|
||||
natives.REQUEST_MODEL(modelHash);
|
||||
|
||||
let attempts = 0;
|
||||
while (!natives.HAS_MODEL_LOADED(modelHash) && attempts < 100) {
|
||||
natives.WAIT(10);
|
||||
attempts++;
|
||||
}
|
||||
|
||||
if (natives.HAS_MODEL_LOADED(modelHash)) {
|
||||
let obj = natives.CREATE_OBJECT(modelHash, pos[0], pos[1], pos[2], true, true);
|
||||
if (obj) {
|
||||
spawnedObjects.push(obj);
|
||||
natives.PLACE_OBJECT_ON_GROUND_PROPERLY(obj);
|
||||
showNotification("~g~Object spawned!");
|
||||
}
|
||||
natives.MARK_MODEL_AS_NO_LONGER_NEEDED(modelHash);
|
||||
} else {
|
||||
showNotification("~r~Failed to load object!");
|
||||
}
|
||||
}
|
||||
|
||||
function deleteNearestObject() {
|
||||
let playerPed = natives.GET_PLAYER_PED(natives.GET_PLAYER_ID());
|
||||
let pos = natives.GET_CHAR_COORDINATES(playerPed);
|
||||
|
||||
let obj = natives.GET_CLOSEST_OBJECT_OF_TYPE(pos[0], pos[1], pos[2], 10.0, 0, false);
|
||||
if (obj && natives.DOES_OBJECT_EXIST(obj)) {
|
||||
natives.DELETE_OBJECT(obj);
|
||||
showNotification("~g~Object deleted!");
|
||||
} else {
|
||||
showNotification("~r~No object found nearby!");
|
||||
}
|
||||
}
|
||||
|
||||
function deleteAllSpawnedObjects() {
|
||||
for (let obj of spawnedObjects) {
|
||||
if (natives.DOES_OBJECT_EXIST(obj)) {
|
||||
natives.DELETE_OBJECT(obj);
|
||||
}
|
||||
}
|
||||
spawnedObjects = [];
|
||||
showNotification("~g~All spawned objects deleted!");
|
||||
}
|
||||
|
||||
function resetMenuPosition() {
|
||||
MENU_CONFIG.posX = 0.695;
|
||||
MENU_CONFIG.posY = 0.155;
|
||||
showNotification("~g~Menu position reset!");
|
||||
}
|
||||
|
||||
let hudVisible = true;
|
||||
function toggleHUD() {
|
||||
hudVisible = !hudVisible;
|
||||
natives.DISPLAY_HUD(hudVisible);
|
||||
showNotification(hudVisible ? "~g~HUD Visible" : "~r~HUD Hidden");
|
||||
}
|
||||
|
||||
let radarVisible = true;
|
||||
function toggleRadar() {
|
||||
radarVisible = !radarVisible;
|
||||
natives.DISPLAY_RADAR(radarVisible);
|
||||
showNotification(radarVisible ? "~g~Radar Visible" : "~r~Radar Hidden");
|
||||
}
|
||||
|
||||
let spectating = false;
|
||||
let spectateTarget = null;
|
||||
|
||||
function spectatePlayer() {
|
||||
// TODO: Implement player list selection for spectating
|
||||
showNotification("~y~Select a player to spectate from Player List");
|
||||
}
|
||||
|
||||
function stopSpectating() {
|
||||
if (spectating) {
|
||||
let playerId = natives.GET_PLAYER_ID();
|
||||
let playerPed = natives.GET_PLAYER_PED(playerId);
|
||||
natives.SET_CAMERA_CONTROLS_DISABLED_WITH_PLAYER_CONTROLS(false);
|
||||
natives.SET_PLAYER_CONTROL(playerId, true);
|
||||
spectating = false;
|
||||
spectateTarget = null;
|
||||
showNotification("~g~Stopped spectating!");
|
||||
} else {
|
||||
showNotification("~r~Not currently spectating!");
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// EVENT HANDLERS
|
||||
// ============================================================================
|
||||
|
||||
addEventHandler("OnProcess", function(event) {
|
||||
worldOptionsLoop();
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
// EXPORTS
|
||||
// ============================================================================
|
||||
|
||||
this.worldOptions = worldOptions;
|
||||
this.getWeatherMenuItems = getWeatherMenuItems;
|
||||
this.getModelMenuItems = getModelMenuItems;
|
||||
this.getAnimationMenuItems = getAnimationMenuItems;
|
||||
this.getObjectMenuItems = getObjectMenuItems;
|
||||
this.getSettingsMenuItems = getSettingsMenuItems;
|
||||
this.getCreditsMenuItems = getCreditsMenuItems;
|
||||
this.getNetworkMenuItems = getNetworkMenuItems;
|
||||
this.setWeather = setWeather;
|
||||
this.setTimeQuick = setTimeQuick;
|
||||
Reference in New Issue
Block a user