445 lines
		
	
	
		
			No EOL
		
	
	
		
			13 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			445 lines
		
	
	
		
			No EOL
		
	
	
		
			13 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| async function objectDialog(type) {
 | |
| 	return new Promise(async function(resolve, reject) {
 | |
| 		switch(type) {
 | |
| 			case "item": {
 | |
| 				resolve( await itemsDialog() );
 | |
| 	
 | |
| 				break;
 | |
| 			}
 | |
| 	
 | |
| 			case "account": {
 | |
| 				resolve( await accountsDialog() );
 | |
| 
 | |
| 				break;
 | |
| 			}
 | |
| 	
 | |
| 			case "weapon": {
 | |
| 				resolve( await weaponsDialog() );
 | |
| 
 | |
| 				break;
 | |
| 			}
 | |
| 		}
 | |
| 	});
 | |
| }
 | |
| 
 | |
| function getDefaultMarkerCustomization() {
 | |
| 	return {
 | |
| 		type: 1,
 | |
| 		scale: {
 | |
| 			x: 1.5,
 | |
| 			y: 1.5,
 | |
| 			z: 0.5
 | |
| 		},
 | |
| 		color: {
 | |
| 			red: 150,
 | |
| 			green: 100,
 | |
| 			blue: 0,
 | |
| 			opacity: 200
 | |
| 		},
 | |
| 		rotation: {
 | |
| 			x: 0.0,
 | |
| 			y: 0.0,
 | |
| 			z: 0.0
 | |
| 		},
 | |
| 		followCamera: false,
 | |
| 		bounce: false,
 | |
| 		rotate: false
 | |
| 	}
 | |
| }
 | |
| 
 | |
| async function markerDialog(currentMarkerData) {
 | |
| 	return new Promise((resolve, reject) => {
 | |
| 		let markerModal = $("#marker-customization-dialog-modal");
 | |
| 
 | |
| 		if(!currentMarkerData) {
 | |
| 			currentMarkerData = getDefaultMarkerCustomization()
 | |
| 		}
 | |
| 
 | |
| 		$("#marker-type").val(currentMarkerData.type);
 | |
| 		$("#marker-size-x").val(currentMarkerData.scale.x);
 | |
| 		$("#marker-size-y").val(currentMarkerData.scale.y);
 | |
| 		$("#marker-size-z").val(currentMarkerData.scale.z);
 | |
| 		$("#marker-color-red").val(currentMarkerData.color.red);
 | |
| 		$("#marker-color-green").val(currentMarkerData.color.green);
 | |
| 		$("#marker-color-blue").val(currentMarkerData.color.blue);
 | |
| 		$("#marker-color-opacity").val(currentMarkerData.color.opacity);
 | |
| 		$("#marker-rotation-x").val(currentMarkerData.rotation.x);
 | |
| 		$("#marker-rotation-y").val(currentMarkerData.rotation.y);
 | |
| 		$("#marker-rotation-z").val(currentMarkerData.rotation.z);
 | |
| 		$("#marker-follow-camera").prop("checked", currentMarkerData.followCamera);
 | |
| 		$("#marker-bounce").prop("checked", currentMarkerData.bounce);
 | |
| 		$("#marker-rotate").prop("checked", currentMarkerData.rotate);
 | |
| 
 | |
| 		$("#marker-customization-form").unbind().submit(function(event) {
 | |
| 			if(isThereAnyErrorInForm(event)) return;
 | |
| 
 | |
| 			let markerData = {
 | |
| 				type: parseInt( $("#marker-type").val() ),
 | |
| 				scale: {
 | |
| 					x: parseFloat( $("#marker-size-x").val() ),
 | |
| 					y: parseFloat( $("#marker-size-y").val() ),
 | |
| 					z: parseFloat( $("#marker-size-z").val() )
 | |
| 				},
 | |
| 				color: {
 | |
| 					red: parseInt( $("#marker-color-red").val() ),
 | |
| 					green: parseInt( $("#marker-color-green").val() ),
 | |
| 					blue: parseInt( $("#marker-color-blue").val() ),
 | |
| 					opacity: parseInt( $("#marker-color-opacity").val() )
 | |
| 				},
 | |
| 				rotation: {
 | |
| 					x: parseFloat( $("#marker-rotation-x").val() ),
 | |
| 					y: parseFloat( $("#marker-rotation-y").val() ),
 | |
| 					z: parseFloat( $("#marker-rotation-z").val() )
 | |
| 				},
 | |
| 				followCamera: $("#marker-follow-camera").prop("checked"),
 | |
| 				bounce: $("#marker-bounce").prop("checked"),
 | |
| 				rotate: $("#marker-rotate").prop("checked")
 | |
| 			}
 | |
| 
 | |
| 			markerModal.modal("hide");
 | |
| 
 | |
| 			resolve(markerData);
 | |
| 		})
 | |
| 
 | |
| 		markerModal.modal("show");
 | |
| 	});
 | |
| }
 | |
| 
 | |
| function getDefaultBlipCustomization() {
 | |
| 	return {
 | |
| 		isEnabled: true,
 | |
| 		sprite: 1,
 | |
| 		label: "Default",
 | |
| 		scale: "0.5",
 | |
| 		color: 1,
 | |
| 		display: 5,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| async function blipDialog(currentBlipData) {
 | |
| 	return new Promise((resolve, reject) => {
 | |
| 		let blipModal = $("#blip-customization-dialog-modal");
 | |
| 
 | |
| 		if(!currentBlipData) {
 | |
| 			currentBlipData = getDefaultBlipCustomization()
 | |
| 		}
 | |
| 
 | |
| 		$("#blip-enabled").prop("checked", currentBlipData.isEnabled).change();
 | |
| 		$("#blip-sprite").val(currentBlipData.sprite);
 | |
| 		$("#blip-name").val(currentBlipData.label);
 | |
| 		$("#blip-color").val(currentBlipData.color);
 | |
| 		$("#blip-display").val(currentBlipData.display);
 | |
| 		$("#blip-scale").val(currentBlipData.scale);
 | |
| 
 | |
| 		$("#blip-customization-form").unbind().submit(function(event) {
 | |
| 			if(isThereAnyErrorInForm(event)) return;
 | |
| 
 | |
| 			let blipData = {
 | |
| 				isEnabled: $("#blip-enabled").prop("checked"),
 | |
| 				sprite: parseInt( $("#blip-sprite").val() ),
 | |
| 				label: $("#blip-name").val(),
 | |
| 				scale: parseFloat( $("#blip-scale").val() ),
 | |
| 				color: parseInt( $("#blip-color").val() ),
 | |
| 				display: parseInt( $("#blip-display").val() ),
 | |
| 			}
 | |
| 
 | |
| 			blipModal.modal("hide");
 | |
| 
 | |
| 			resolve(blipData);
 | |
| 		})
 | |
| 
 | |
| 		blipModal.modal("show");
 | |
| 	});
 | |
| }
 | |
| 
 | |
| $("#blip-enabled").change(function() {
 | |
| 	let isEnabled = $(this).prop("checked");
 | |
| 
 | |
| 	$("#blip-customization-form").find("input, select").not( $(this) )
 | |
| 		.prop("disabled", !isEnabled)
 | |
| 		.prop("required", isEnabled);
 | |
| })
 | |
| 
 | |
| async function heistsDialog() {
 | |
| 	return new Promise((resolve, reject) => {
 | |
| 		let inputHeistsModal = $("#input-heists-dialog-modal")
 | |
| 		inputHeistsModal.modal("show");
 | |
| 	
 | |
| 		$("#input-heist-search").val("");
 | |
| 		
 | |
| 		$.post(`https://${resName}/getAllHeists`, JSON.stringify({}), function (heists) {
 | |
| 			let inputHeistsList = $("#heists-list");
 | |
| 	
 | |
| 			inputHeistsList.empty();
 | |
| 	
 | |
| 			for(const[_, heistData] of Object.entries(heists)) {
 | |
| 				let heistDiv = $(`
 | |
| 					<li class="list-group-item list-group-item-action" value=${heistData.id}>${heistData.label}</li>
 | |
| 				`);
 | |
| 	
 | |
| 				heistDiv.click(function() {
 | |
| 					inputHeistsModal.modal("hide");
 | |
| 					resolve(heistData.id);
 | |
| 				});
 | |
| 	
 | |
| 				inputHeistsList.append(heistDiv);
 | |
| 			}
 | |
| 		});
 | |
| 	})
 | |
| }
 | |
| 
 | |
| $("#input-heist-search").on("keyup", function() {
 | |
| 	let text = $(this).val().toLowerCase();
 | |
| 
 | |
| 	$("#heists-list li").filter(function() {
 | |
|       $(this).toggle($(this).text().toLowerCase().indexOf(text) > -1)
 | |
|     });
 | |
| })
 | |
| 
 | |
| async function doorsDialog(alreadySelectedDoors = {}) {
 | |
| 	return new Promise((resolve, reject) => {
 | |
| 		let inputDoorsModal = $("#input-doors-dialog-modal")
 | |
| 		inputDoorsModal.modal("show");
 | |
| 	
 | |
| 		$("#input-door-search").val("");
 | |
| 		
 | |
| 		$.post(`https://${resName}/getAllDoors`, JSON.stringify({}), function (doors) {
 | |
| 			let inputDoorsList = $("#doors-list");
 | |
| 	
 | |
| 			inputDoorsList.empty();
 | |
| 	
 | |
| 			for(const[buildingId, data] of Object.entries(doors)) {	
 | |
| 				let buildingDiv = $(`
 | |
| 					<div class="form-check fs-3 mb-2">
 | |
| 						<p class="fw-bold mb-0">${data.label}</p>
 | |
| 						
 | |
| 						<div class="doors-list">
 | |
| 
 | |
| 						</div>
 | |
| 					</div>
 | |
| 				`);
 | |
| 
 | |
| 				for(let [doorsId, doorsData] of Object.entries(data.doors)) {
 | |
| 					let doorDiv = $(`
 | |
| 						<div class="door-div mx-auto">
 | |
| 							<input class="form-check-input" type="checkbox" data-doors-id=${doorsData.id}>
 | |
| 							<label class="form-check-label">
 | |
| 								${doorsData.id} - ${doorsData.label}
 | |
| 							</label>
 | |
| 						</div>
 | |
| 					`);
 | |
| 
 | |
| 					buildingDiv.find(".doors-list").append(doorDiv);
 | |
| 				}
 | |
| 				
 | |
| 				inputDoorsList.append(buildingDiv);
 | |
| 			}
 | |
| 
 | |
| 			for(let [doorsId, _] of Object.entries(alreadySelectedDoors) ) {
 | |
| 				$(`input[data-doors-id=${doorsId}]`).prop("checked", true);
 | |
| 			}
 | |
| 
 | |
| 			// Unbinds the button and rebinds it to callback the selected doors
 | |
| 			$("#input-doors-confirm-btn").unbind().click(function() {
 | |
| 				let selectedDoors = {};
 | |
| 		
 | |
| 				inputDoorsList.find("input:checked").each(function() {	
 | |
| 					let doorsId = parseInt( $(this).data("doorsId") )
 | |
| 						
 | |
| 					selectedDoors[doorsId] = true;
 | |
| 				});
 | |
| 	
 | |
| 				inputDoorsModal.modal("hide");
 | |
| 	
 | |
| 				resolve(selectedDoors);
 | |
| 			})
 | |
| 		});
 | |
| 	})
 | |
| }
 | |
| 
 | |
| $("#input-door-search").on("keyup", function() {
 | |
| 	let text = $(this).val().toLowerCase();
 | |
| 
 | |
| 	$("#doors-list .form-check").filter(function() {
 | |
|       $(this).toggle($(this).text().toLowerCase().indexOf(text) > -1)
 | |
|     });
 | |
| })
 | |
| 
 | |
| function createAlarmDiv(alarm = {}) {
 | |
| 	let alarmDiv = $(`
 | |
| 		<div class="mb-3 mt-1 alarm">
 | |
| 			<div class="row g-2 row-cols-auto align-items-center justify-content-center">
 | |
| 				<button type="button" class="btn btn-danger delete-alarm-btn me-3" ><i class="bi bi-trash-fill"></i></button>	
 | |
| 
 | |
| 				<div class="form-floating text-body col-2">
 | |
| 					<input type="number" step="0.01" class="form-control coords-x" placeholder="X" required value="${alarm.coords?.x || ""}">
 | |
| 					<label>${ getLocalizedText("menu:x") }</label>
 | |
| 				</div>
 | |
| 
 | |
| 				<div class="form-floating text-body col-2">
 | |
| 					<input type="number" step="0.01" class="form-control coords-y" placeholder="Y" required value="${alarm.coords?.y || ""}">
 | |
| 					<label>${ getLocalizedText("menu:y") }</label>
 | |
| 				</div>
 | |
| 
 | |
| 				<div class="form-floating text-body col-2">
 | |
| 					<input type="number" step="0.01" class="form-control coords-z" placeholder="Z" required value="${alarm.coords?.z || ""}">
 | |
| 					<label>${ getLocalizedText("menu:z") }</label>
 | |
| 				</div>
 | |
| 
 | |
| 				<button type="button" class="btn btn-secondary col-auto choose-coords-and-heading-btn" data-bs-toggle="tooltip" data-bs-placement="top" title="${ getLocalizedText("menu:place_object") }"><i class="bi bi-arrow-down-square"></i></button>				
 | |
| 			</div>
 | |
| 
 | |
| 			<div class="d-flex gap-3 align-items-center justify-content-center mt-2">
 | |
| 				<div class="form-floating text-body ms-2">
 | |
| 					<input type="number" min=1 class="form-control duration" placeholder="Duration" required value="${alarm.duration || 30}">
 | |
| 					<label>${ getLocalizedText("menu:duration") }</label>
 | |
| 				</div>
 | |
| 
 | |
| 				<select class="form-select alarm-type ms-2" style="width: auto">
 | |
| 					<option value="police_and_alarm_bell">${ getLocalizedText("menu:police_and_alarm_bell") }</option>
 | |
| 					<option value="police_only">${ getLocalizedText("menu:police_only") }</option>
 | |
| 					<option value="alarm_bell_only">${ getLocalizedText("menu:alarm_bell_only") }</option>
 | |
| 				</select>
 | |
| 
 | |
| 				<select class="form-select alarm-trigger-method" style="width: auto">
 | |
| 					<option value="start">${ getLocalizedText("menu:start_on_interaction") }</option>
 | |
| 					<option value="end">${ getLocalizedText("menu:start_on_step_completion") }</option>
 | |
| 				</select>
 | |
| 			</div>
 | |
| 
 | |
| 			<hr>
 | |
| 
 | |
| 		</div>
 | |
| 	`);
 | |
| 
 | |
| 	alarmDiv.find(".delete-alarm-btn").click(function() {
 | |
| 		alarmDiv.remove();
 | |
| 	});
 | |
| 
 | |
| 	alarmDiv.find(".choose-coords-and-heading-btn").click(async function() {
 | |
| 		let data = await placeObjectAndReturnCoords();
 | |
| 
 | |
| 		if(data) {
 | |
| 			alarmDiv.find(".coords-x").val(data.coords.x);
 | |
| 			alarmDiv.find(".coords-y").val(data.coords.y);
 | |
| 			alarmDiv.find(".coords-z").val(data.coords.z);
 | |
| 		}
 | |
| 	}).tooltip();
 | |
| 
 | |
| 	alarmDiv.find(".alarm-type").val(alarm.type || "police_and_alarm_bell");
 | |
| 	alarmDiv.find(".alarm-trigger-method").val(alarm.triggerMethod || "start");
 | |
| 
 | |
| 	$("#alarms-list").append(alarmDiv);
 | |
| }
 | |
| 
 | |
| async function alarmsDialog(alarms = []) {
 | |
| 	return new Promise((resolve, reject) => {
 | |
| 		let inputAlarmsModal = $("#input-alarms-dialog-modal");
 | |
| 
 | |
| 		$("#alarms-list").empty();
 | |
| 
 | |
| 		inputAlarmsModal.modal("show");
 | |
| 
 | |
| 		alarms.forEach(alarm => {
 | |
| 			createAlarmDiv(alarm);
 | |
| 		});
 | |
| 
 | |
| 		$("#input-alarms-form").unbind().submit(function(event) {
 | |
| 			if(isThereAnyErrorInForm(event)) return;
 | |
| 		
 | |
| 			let alarms = [];
 | |
| 			
 | |
| 			$("#alarms-list").find(".alarm").each(function() {
 | |
| 				let alarm = {
 | |
| 					coords: {
 | |
| 						x: parseFloat( $(this).find(".coords-x").val() ),
 | |
| 						y: parseFloat( $(this).find(".coords-y").val() ),
 | |
| 						z: parseFloat( $(this).find(".coords-z").val() )
 | |
| 					},
 | |
| 					duration: parseInt( $(this).find(".duration").val() ),
 | |
| 					type: $(this).find(".alarm-type").val(),
 | |
| 					triggerMethod: $(this).find(".alarm-trigger-method").val()
 | |
| 				}
 | |
| 
 | |
| 				alarms.push(alarm);
 | |
| 			});
 | |
| 
 | |
| 			inputAlarmsModal.modal("hide");
 | |
| 			resolve(alarms);
 | |
| 		})
 | |
| 	})
 | |
| }
 | |
| 
 | |
| $("#input-alarms-new-alarm-btn").click(function() {
 | |
| 	createAlarmDiv();
 | |
| })
 | |
| 
 | |
| async function cargoRobberiesDialog() {
 | |
| 	return new Promise((resolve, reject) => {
 | |
| 		let inputHeistsModal = $("#input-cargo-robberies-dialog-modal")
 | |
| 		inputHeistsModal.modal("show");
 | |
| 	
 | |
| 		$("#input-cargo-robbery-search").val("");
 | |
| 		
 | |
| 		$.post(`https://${resName}/getAllCargoRobberies`, JSON.stringify({}), function (cargoRobberies) {
 | |
| 			let inputHeistsList = $("#cargo-robberies-list");
 | |
| 	
 | |
| 			inputHeistsList.empty();
 | |
| 	
 | |
| 			for(const[_, robberyData] of Object.entries(cargoRobberies)) {
 | |
| 				let robberyDiv = $(`
 | |
| 					<li class="list-group-item list-group-item-action clickable" value=${robberyData.id}>${robberyData.label}</li>
 | |
| 				`);
 | |
| 	
 | |
| 				robberyDiv.click(function() {
 | |
| 					inputHeistsModal.modal("hide");
 | |
| 					resolve(robberyData.id);
 | |
| 				});
 | |
| 	
 | |
| 				inputHeistsList.append(robberyDiv);
 | |
| 			}
 | |
| 		});
 | |
| 	})
 | |
| }
 | |
| 
 | |
| $("#input-cargo-robbery-search").on("keyup", function() {
 | |
| 	let text = $(this).val().toLowerCase();
 | |
| 
 | |
| 	$("#cargo-robberies-list li").filter(function() {
 | |
|       $(this).toggle($(this).text().toLowerCase().indexOf(text) > -1)
 | |
|     });
 | |
| })
 | |
| 
 | |
| function toggleCursor(enabled) {
 | |
| 	if (enabled) {
 | |
| 		$.post(`https://${resName}/enableCursor`, JSON.stringify({}));
 | |
| 	} else {
 | |
| 		$.post(`https://${resName}/disableCursor`, JSON.stringify({}));
 | |
| 	}
 | |
| }
 | |
| 
 | |
| function loadDialog(dialogName) {
 | |
| 	var script = document.createElement('script');
 | |
| 
 | |
| 	console.log(`../utils/dialogs/${dialogName}/${dialogName}.js`)
 | |
| 	script.setAttribute('src',`../utils/dialogs/${dialogName}/${dialogName}.js`);
 | |
| 
 | |
| 	document.head.appendChild(script);
 | |
| }
 | |
| 
 | |
| // Messages received by client
 | |
| window.addEventListener('message', (event) => {
 | |
| 	let data = event.data;
 | |
| 	let action = data.action;
 | |
| 
 | |
| 	switch(action) {
 | |
| 		case "loadDialog": {
 | |
| 			var script = document.createElement('script');
 | |
| 			script.setAttribute('src',`../utils/dialogs/${data.dialogName}/${data.dialogName}.js`);
 | |
| 			document.head.appendChild(script);
 | |
| 			break;
 | |
| 		}
 | |
| 	}
 | |
| })
 | |
| 
 | |
| $.post(`https://${resName}/nuiReady`, JSON.stringify({})); | 
