forked from Simnation/Main
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({})); |