forked from Simnation/Main
1539 lines
No EOL
43 KiB
JavaScript
1539 lines
No EOL
43 KiB
JavaScript
const resName = GetParentResourceName();
|
|
|
|
// Utils
|
|
|
|
function showNotification(message, duration=false) {
|
|
var notification = $("#notification");
|
|
|
|
if(duration) {
|
|
notification.toast({
|
|
autohide: true,
|
|
delay: duration
|
|
})
|
|
} else {
|
|
notification.toast({
|
|
autohide: false,
|
|
})
|
|
}
|
|
|
|
$("#notification-message").text(message)
|
|
|
|
notification.toast("show")
|
|
}
|
|
|
|
async function buildingsDialog() {
|
|
let inputBuildingModal = $("#input-building-dialog-modal")
|
|
inputBuildingModal.modal("show");
|
|
|
|
$("#input-building-search").val("");
|
|
|
|
const buildings = await $.post(`https://${resName}/getAllBuildings`);
|
|
let buildingsListDiv = $("#buildings-list");
|
|
|
|
buildingsListDiv.empty();
|
|
|
|
return new Promise(resolve => {
|
|
for(const[_, buildingData] of Object.entries(buildings)) {
|
|
let buildingDiv = $(`
|
|
<li class="list-group-item list-group-item-action clickable">${buildingData.id} - ${buildingData.label}</li>
|
|
`);
|
|
|
|
buildingDiv.click(function() {
|
|
inputBuildingModal.modal("hide");
|
|
resolve(buildingData.id);
|
|
});
|
|
|
|
buildingsListDiv.append(buildingDiv);
|
|
}
|
|
})
|
|
}
|
|
$("#input-building-search").on("keyup", function() {
|
|
let text = $(this).val().toLowerCase();
|
|
|
|
$("#buildings-list li").filter(function() {
|
|
$(this).toggle($(this).text().toLowerCase().indexOf(text) > -1)
|
|
});
|
|
})
|
|
|
|
async function playersListDialog(cb) {
|
|
// Get players list
|
|
let playersList = await $.get(`https://${resName}/getPlayersList`);
|
|
|
|
let modal = $("#players-dialog-modal");
|
|
|
|
$("#input-players-search").val("");
|
|
|
|
let playerListDiv = $("#players-list")
|
|
|
|
playerListDiv.empty();
|
|
|
|
for(const playerData of playersList) {
|
|
let playerDiv = $(`
|
|
<li class="list-group-item list-group-item-action clickable"}>${playerData.playerName}</li>
|
|
`);
|
|
|
|
playerDiv.click(function() {
|
|
modal.modal("hide");
|
|
cb(playerData.identifier);
|
|
});
|
|
|
|
playerListDiv.append(playerDiv);
|
|
}
|
|
|
|
modal.modal("show");
|
|
}
|
|
$("#input-players-search").on("keyup", function() {
|
|
let text = $(this).val().toLowerCase();
|
|
|
|
$("#players-list li").filter(function() {
|
|
$(this).toggle($(this).text().toLowerCase().indexOf(text) > -1)
|
|
});
|
|
})
|
|
|
|
/* DOORS */
|
|
function changeLockIconButton(row, newState) {
|
|
const lockedIcon = `<i class="bi bi-lock"></i>`;
|
|
const unlockedIcon = `<i class="bi bi-unlock"></i>`;
|
|
|
|
const btnDiv = $(row).find(".toggle-lock-btn");
|
|
|
|
if(newState) {
|
|
btnDiv.html(lockedIcon);
|
|
btnDiv.removeClass("btn-success");
|
|
btnDiv.addClass("btn-danger");
|
|
} else {
|
|
btnDiv.html(unlockedIcon);
|
|
btnDiv.removeClass("btn-danger");
|
|
btnDiv.addClass("btn-success");
|
|
}
|
|
}
|
|
|
|
let doorsDatatable = $("#doors-container").DataTable( {
|
|
"lengthMenu": [10, 15, 20],
|
|
"columnDefs": [
|
|
{
|
|
"targets": -1, // Ultima colonna
|
|
"data": null,
|
|
"className": "col-1",
|
|
"defaultContent": `
|
|
<div class="d-inline-flex gap-3">
|
|
<button class='btn btn-danger py-0 px-2 toggle-lock-btn'><i class=\"bi bi-lock\"></i></button>
|
|
<button class='btn py-0 px-2 teleport-to-door-btn' style="background-color: #706fd3" data-bs-toggle="tooltip" data-bs-placement="top" title="TP"><i class=\"bi-geo-fill\"></i></button>
|
|
</div>
|
|
`
|
|
}
|
|
],
|
|
"createdRow": async function ( row, data, index ) {
|
|
const doorsData = data[data.length - 1];
|
|
|
|
$(row).addClass("clickable");
|
|
|
|
$(row).click(function() {
|
|
editDoor(doorsData.id);
|
|
});
|
|
|
|
$(row).find(".toggle-lock-btn").click(async function(event) {
|
|
event.stopPropagation();
|
|
|
|
const newState = await $.post(`https://${resName}/toggleLock`, JSON.stringify({doorsId: doorsData.id}));
|
|
if(newState < 0) return;
|
|
|
|
changeLockIconButton(row, newState);
|
|
});
|
|
|
|
$(row).find(".teleport-to-door-btn").click(async function(event) {
|
|
event.stopPropagation();
|
|
|
|
$.post(`https://${resName}/teleportToDoor`, JSON.stringify({doorsId: doorsData.id}));
|
|
|
|
$(this).tooltip("hide");
|
|
}).tooltip();
|
|
|
|
const currentLockState = await $.post(`https://${resName}/getLockState`, JSON.stringify({doorsId: doorsData.id}));
|
|
if(currentLockState < 0) return;
|
|
|
|
changeLockIconButton(row, currentLockState);
|
|
},
|
|
} );
|
|
|
|
let doors = {};
|
|
|
|
function loadDoors() {
|
|
$.post(`https://${resName}/getAllDoors`, {}, async function(rawDoors) {
|
|
// Manually create the table to avoid incompatibilities due table indexing
|
|
|
|
doors = {};
|
|
|
|
for(const[k, doorsData] of Object.entries(rawDoors)) {
|
|
doors[doorsData.id] = doorsData;
|
|
}
|
|
|
|
doorsDatatable.clear();
|
|
|
|
for(const[doorsId, doorsData] of Object.entries(doors)) {
|
|
doorsDatatable.row.add([
|
|
doorsData.distance,
|
|
doorsId,
|
|
doorsData.label,
|
|
doorsData.doors ? Object.entries(doorsData.doors).length : 0,
|
|
doorsData.parentBuilding ? buildings[doorsData.parentBuilding].label : getLocalizedText("menu:none"),
|
|
doorsData // Will be the last element of the data parameter in the createdRow callback
|
|
])
|
|
}
|
|
|
|
doorsDatatable.draw()
|
|
})
|
|
}
|
|
|
|
function setDoorsModalType(type) {
|
|
$("#door-modal").data("type", type);
|
|
|
|
switch(type) {
|
|
case "building": {
|
|
$("#used-doors-div").hide();
|
|
$("#maximum-distance-div").hide().find("input").prop("required", false);
|
|
$("#icon-coordinates-div").hide().find("input").prop("required", false);
|
|
$("#use-building-rules-div").hide();
|
|
$("#sliding-door-div").hide();
|
|
$("#display-door-icon-div").hide();
|
|
$("#can-be-lockpicked-div").hide();
|
|
$("#vault-door-div").hide();
|
|
$("#sound-data-div").hide();
|
|
|
|
showBuildingOptions();
|
|
|
|
break;
|
|
}
|
|
|
|
case "door": {
|
|
$("#used-doors-div").show();
|
|
$("#maximum-distance-div").show().find("input").prop("required", true);
|
|
$("#icon-coordinates-div").show().find("input").prop("required", true);
|
|
$("#use-building-rules-div").show();
|
|
$("#sliding-door-div").show();
|
|
$("#display-door-icon-div").show();
|
|
$("#can-be-lockpicked-div").show();
|
|
$("#vault-door-div").show();
|
|
$("#sound-data-div").show();
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
function setupDefaultModalValues() {
|
|
let doorModal = $("#door-modal");
|
|
|
|
doorModal.find(".form-control").val("");
|
|
|
|
$("#door-label").val( getLocalizedText("menu:default") );
|
|
|
|
$(`input[name="doors-default-state"][value="0"]`).prop("checked", true);
|
|
|
|
$("#used-doors-table").empty();
|
|
$("#maximum-distance").val(4.0);
|
|
|
|
$("#requires-job").prop("checked", false).change();
|
|
$("#requires-item").prop("checked", false).change();
|
|
$("#required-item-remove-on-use").prop("checked", false);
|
|
$("#requires-code").prop("checked", false).change();
|
|
$("#auto-closure-switch").prop("checked", false).change();
|
|
$("#can-be-lockpicked").prop("checked", true).change();
|
|
$("#alert-police-on-lockpick").prop("checked", false).change();
|
|
$("#is-sliding-door").prop("checked", true).change();
|
|
$("#display-door-icon").prop("checked", true).change();
|
|
|
|
$("#requires-identifier").prop("checked", false).change();
|
|
$("#allowed-identifiers").empty();
|
|
|
|
$("#is-vault-door").prop("checked", false).change();
|
|
}
|
|
|
|
$("#register-bulk-doors-btn").click(async function() {
|
|
let doorModal = $("#door-modal");
|
|
|
|
$("html").hide();
|
|
|
|
setDoorsModalType("door");
|
|
|
|
// Converts from edit modal to create modal
|
|
doorModal.data("action", "create");
|
|
|
|
$("#delete-door-btn").hide();
|
|
$("#save-door-btn").text( getLocalizedText("menu:create") );
|
|
|
|
// Resets fields (only for the first door in bulk list)
|
|
setupDefaultModalValues();
|
|
|
|
// Gets the bulk doors list
|
|
let mergedDoors = await $.get(`https://${resName}/getMergedDoors`);
|
|
|
|
if(!mergedDoors || mergedDoors.length == 0) {
|
|
$("html").show();
|
|
return;
|
|
}
|
|
|
|
let finalDoorsObjectUsed = {};
|
|
|
|
for(let i=0; i < mergedDoors.length; i++) {
|
|
$("html").hide();
|
|
|
|
let data = await $.post(`https://${resName}/bulkRegisterDoorsGroup`, JSON.stringify({
|
|
doorsGroup: mergedDoors[i],
|
|
finalDoorsObjectUsed: finalDoorsObjectUsed
|
|
}));
|
|
|
|
$("html").show();
|
|
if(!data.doorsData) continue;
|
|
|
|
doorModal.modal("show");
|
|
|
|
// merge the final doors object used
|
|
finalDoorsObjectUsed = Object.assign(finalDoorsObjectUsed, data.finalDoorsObjectUsed);
|
|
let doorsData = data.doorsData;
|
|
|
|
setUsedDoors(doorsData.doors);
|
|
$("#icon-coords-x").val(doorsData.iconCoords.x).change();
|
|
$("#icon-coords-y").val(doorsData.iconCoords.y).change();
|
|
$("#icon-coords-z").val(doorsData.iconCoords.z).change();
|
|
|
|
// Wait till the modal is closed
|
|
await new Promise(resolve => {
|
|
doorModal.one("hidden.bs.modal", function() {
|
|
resolve();
|
|
})
|
|
})
|
|
}
|
|
})
|
|
|
|
$("#new-door-btn").click(function() {
|
|
let doorModal = $("#door-modal");
|
|
|
|
setDoorsModalType("door");
|
|
|
|
// Converts from create modal to edit modal
|
|
doorModal.data("action", "create");
|
|
|
|
$("#delete-door-btn").hide();
|
|
$("#save-door-btn").text( getLocalizedText("menu:create") );
|
|
|
|
// Resets fields
|
|
setupDefaultModalValues();
|
|
|
|
setParentBuilding(null);
|
|
|
|
doorModal.modal("show");
|
|
})
|
|
|
|
function setUsedDoors(doors = {}) {
|
|
let usedDoorsTable = $("#used-doors-table");
|
|
|
|
usedDoorsTable.empty();
|
|
|
|
for(const[doorObject, doorData] of Object.entries(doors)) {
|
|
let x = (doorData.coords.x).toFixed(2);
|
|
let y = (doorData.coords.y).toFixed(2);
|
|
let z = (doorData.coords.z).toFixed(2);
|
|
|
|
let newRow = $(`
|
|
<tr class="used-door">
|
|
<td class="x-coord">${x}</td>
|
|
<td class="y-coord">${y}</td>
|
|
<td class="z-coord">${z}</td>
|
|
<td class="model">${doorData.model}</td>
|
|
</tr>
|
|
`)
|
|
|
|
newRow.data("doorObject", doorObject);
|
|
|
|
usedDoorsTable.append(newRow);
|
|
}
|
|
}
|
|
|
|
$("#select-doors-btn").click(function() {
|
|
closeMenu();
|
|
let doorModal = $("#door-modal");
|
|
doorModal.modal("hide");
|
|
|
|
let action = doorModal.data("action");
|
|
if(action === "edit") {
|
|
var doorsId = doorModal.data("doorsId");
|
|
}
|
|
|
|
$.post(`https://${resName}/selectDoors`, JSON.stringify({doorsId: doorsId}), function(doors) {
|
|
if(doors) {
|
|
setUsedDoors(doors);
|
|
}
|
|
|
|
$("#doors_creator").show();
|
|
doorModal.modal("show");
|
|
})
|
|
})
|
|
|
|
$("#choose-icon-coords-btn").click(function() {
|
|
closeMenu();
|
|
let doorModal = $("#door-modal");
|
|
doorModal.modal("hide");
|
|
|
|
$.post(`https://${resName}/chooseIconCoords`, JSON.stringify({usedDoors: getUsedDoors()}), function(coords) {
|
|
if(coords) {
|
|
$("#icon-coords-x").val(coords.x).change();
|
|
$("#icon-coords-y").val(coords.y).change();
|
|
$("#icon-coords-z").val(coords.z).change();
|
|
}
|
|
|
|
$("#doors_creator").show();
|
|
doorModal.modal("show");
|
|
})
|
|
})
|
|
|
|
function getUsedDoors() {
|
|
let doorsTable = $("#used-doors-table");
|
|
let usedDoors = {};
|
|
|
|
let isThereAtLeastOneDoor = false;
|
|
|
|
doorsTable.find(".used-door").each(function() {
|
|
isThereAtLeastOneDoor = true;
|
|
|
|
let doorObject = $(this).data("doorObject");
|
|
|
|
let model = parseInt( $(this).find(".model").text() );
|
|
|
|
let x = parseFloat( $(this).find(".x-coord").text() );
|
|
let y = parseFloat( $(this).find(".y-coord").text() );
|
|
let z = parseFloat( $(this).find(".z-coord").text() );
|
|
|
|
usedDoors[doorObject] = {
|
|
coords: {
|
|
x: x,
|
|
y: y,
|
|
z: z
|
|
},
|
|
|
|
model: model
|
|
}
|
|
});
|
|
|
|
return isThereAtLeastOneDoor && usedDoors || null;
|
|
}
|
|
|
|
$("#choose-maximum-distance-btn").click(function() {
|
|
let doors = getUsedDoors();
|
|
if(!doors) return swal("ERROR", getLocalizedText("menu:no_doors_selected"), "error");;
|
|
|
|
closeMenu();
|
|
let doorModal = $("#door-modal");
|
|
doorModal.modal("hide");
|
|
|
|
let currentDistance = parseFloat( $("#maximum-distance").val() );
|
|
$.post(`https://${resName}/chooseMaximumDistance`, JSON.stringify({doors: doors, distance: currentDistance}), function(maxDistance) {
|
|
if(maxDistance) {
|
|
$("#maximum-distance").val(maxDistance);
|
|
}
|
|
|
|
$("#doors_creator").show();
|
|
doorModal.modal("show");
|
|
})
|
|
})
|
|
|
|
async function getGangLabel(gangName) {
|
|
return new Promise((resolve, reject) => {
|
|
$.post(`https://${resName}/getGangLabel`, JSON.stringify({gangName: gangName}), function(gangLabel) {
|
|
resolve(gangLabel);
|
|
})
|
|
})
|
|
}
|
|
|
|
async function setRequiredJob(requiresJob, allowedJobs) {
|
|
$("#requires-job").prop("checked", requiresJob).change();
|
|
|
|
let allowedJobsDiv = $("#allowed-jobs");
|
|
|
|
allowedJobsDiv.val("");
|
|
|
|
if(allowedJobs) {
|
|
allowedJobsDiv.data("allowedJobs", allowedJobs);
|
|
|
|
let text = "";
|
|
|
|
let isTheFirst = true;
|
|
|
|
for(const[jobName, _] of Object.entries(allowedJobs)) {
|
|
if(isTheFirst) {
|
|
text = await getJobLabel(jobName);
|
|
|
|
isTheFirst = false;
|
|
} else {
|
|
text += `, ${await getJobLabel(jobName)}`;
|
|
}
|
|
}
|
|
|
|
allowedJobsDiv.val(text);
|
|
} else {
|
|
allowedJobsDiv.data("allowedJobs", null);
|
|
}
|
|
}
|
|
|
|
async function setRequiredGang(requiresGang, allowedGangs) {
|
|
$("#requires-gang").prop("checked", requiresGang).change();
|
|
|
|
let allowedGangsDiv = $("#allowed-gangs");
|
|
|
|
allowedGangsDiv.val("");
|
|
|
|
if(allowedGangs) {
|
|
allowedGangsDiv.data("allowedGangs", allowedGangs);
|
|
|
|
let text = "";
|
|
|
|
let isTheFirst = true;
|
|
|
|
for(const[gangName, _] of Object.entries(allowedGangs)) {
|
|
if(isTheFirst) {
|
|
text = await getGangLabel(gangName);
|
|
|
|
isTheFirst = false;
|
|
} else {
|
|
text += `, ${await getGangLabel(gangName)}`;
|
|
}
|
|
}
|
|
|
|
allowedGangsDiv.val(text);
|
|
} else {
|
|
allowedGangsDiv.data("allowedGangs", null);
|
|
}
|
|
}
|
|
|
|
async function setRequiredItem(requiresItem, requiredItem) {
|
|
$("#requires-item").prop("checked", requiresItem).change();
|
|
|
|
let requiredItemDiv = $("#required-item");
|
|
|
|
requiredItemDiv.val(requiredItem);
|
|
}
|
|
|
|
$("#requires-code").change(function() {
|
|
let isEnabled = $(this).prop("checked");
|
|
|
|
$("#required-code").prop("disabled", !isEnabled).prop("required", isEnabled);;
|
|
})
|
|
|
|
function setRequiredCode(requiredCode) {
|
|
$("#requires-code").prop("checked", requiredCode != undefined).change();
|
|
|
|
$("#required-code").val(requiredCode);
|
|
}
|
|
|
|
function hideBuildingOptions() {
|
|
$("#requires-job-div").hide();
|
|
$("#requires-item-div").hide();
|
|
$("#requires-code-div").hide();
|
|
$("#auto-closure-div").hide();
|
|
$("#default-doors-state-div").hide();
|
|
$("#requires-identifier-div").hide();
|
|
}
|
|
|
|
function showBuildingOptions() {
|
|
$("#requires-job-div").show();
|
|
$("#requires-item-div").show();
|
|
$("#requires-code-div").show();
|
|
$("#auto-closure-div").show();
|
|
$("#default-doors-state-div").show();
|
|
$("#requires-identifier-div").show();
|
|
}
|
|
|
|
function setParentBuilding(buildingId) {
|
|
if(buildingId != undefined) {
|
|
$("#use-building-rules").prop("checked", true).change();
|
|
$("#parent-building").data("buildingId", buildingId).val(buildings[buildingId].label);
|
|
} else {
|
|
$("#use-building-rules").prop("checked", false).change();
|
|
$("#parent-building").data("buildingId", null).val("");
|
|
}
|
|
}
|
|
|
|
async function editDoor(doorsId) {
|
|
setDoorsModalType("door");
|
|
|
|
let doorModal = $("#door-modal");
|
|
|
|
doorModal.find("input .form-control").val("");
|
|
|
|
doorModal.data("doorsId", doorsId);
|
|
|
|
// Converts from create modal to edit modal
|
|
doorModal.data("action", "edit");
|
|
|
|
$("#delete-door-btn").show();
|
|
$("#save-door-btn").text( getLocalizedText("menu:save") );
|
|
|
|
let doorsData = doors[doorsId];
|
|
|
|
$("#door-label").val(doorsData.label);
|
|
|
|
setUsedDoors(doorsData.doors);
|
|
|
|
$(`input[name="doors-default-state"][value="${doorsData.defaultState}"]`).prop("checked", true);
|
|
|
|
$("#maximum-distance").val(doorsData.maxDistance);
|
|
|
|
setRequiredJob(doorsData.allowedJobs ? true : false, doorsData.allowedJobs);
|
|
|
|
if(await getFramework() == "QB-core") {
|
|
setRequiredGang(doorsData.allowedGangs ? true : false, doorsData.allowedGangs);
|
|
}
|
|
|
|
setRequiredItem(doorsData.requiredItem ? true : false, doorsData.requiredItem);
|
|
$("#required-item-remove-on-use").prop("checked", doorsData.requiredItem && doorsData.requiredItemRemoveOnUse);
|
|
|
|
setRequiredCode(doorsData.requiredCode);
|
|
|
|
setAutoClosure(doorsData.autoClosureSeconds);
|
|
|
|
setParentBuilding(doorsData.parentBuilding);
|
|
|
|
$("#requires-job-and-item").prop("checked", doorsData.requiresJobAndItem);
|
|
|
|
$("#is-sliding-door").prop("checked", doorsData.isSliding);
|
|
$("#display-door-icon").prop("checked", doorsData.displayIcon);
|
|
$("#can-be-lockpicked").prop("checked", doorsData.canBeLockpicked);
|
|
$("#alert-police-on-lockpick").prop("checked", doorsData.alertPoliceOnLockpick);
|
|
|
|
// Requires identifier
|
|
$("#requires-identifier").prop("checked", doorsData.requiresIdentifier).change();
|
|
|
|
// Add identifiers
|
|
$("#allowed-identifiers").empty();
|
|
if(doorsData.allowedIdentifiers) {
|
|
for(const [identifier, _] of Object.entries(doorsData.allowedIdentifiers)) {
|
|
addIdentifierToList(identifier);
|
|
}
|
|
}
|
|
|
|
setVaultData(doorsData.vault);
|
|
setSoundsData(doorsData.soundsData);
|
|
|
|
$("#icon-coords-x").val(doorsData.iconCoords.x).change();
|
|
$("#icon-coords-y").val(doorsData.iconCoords.y).change();
|
|
$("#icon-coords-z").val(doorsData.iconCoords.z).change();
|
|
|
|
doorModal.modal("show");
|
|
}
|
|
|
|
function submitDoor() {
|
|
let doorModal = $("#door-modal");
|
|
|
|
let action = doorModal.data("action");
|
|
|
|
let doorData = {
|
|
label: $("#door-label").val(),
|
|
defaultState: parseInt( $("input[name='doors-default-state']:checked").val() ),
|
|
maxDistance: parseFloat( $("#maximum-distance").val() ),
|
|
|
|
iconCoords: {
|
|
x: parseFloat( $("#icon-coords-x").val() ),
|
|
y: parseFloat( $("#icon-coords-y").val() ),
|
|
z: parseFloat( $("#icon-coords-z").val() )
|
|
},
|
|
|
|
doors: getUsedDoors(),
|
|
|
|
allowedJobs: $("#requires-job").prop("checked") ? $("#allowed-jobs").data("allowedJobs") : null,
|
|
allowedGangs: $("#requires-gang").prop("checked") ? $("#allowed-gangs").data("allowedGangs") : null,
|
|
requiredItem: $("#requires-item").prop("checked") ? $("#required-item").val() : null,
|
|
requiredItemRemoveOnUse: $("#required-item-remove-on-use").prop("checked"),
|
|
|
|
requiresJobAndItem: $("#requires-job-and-item").prop("checked"),
|
|
|
|
requiredCode: $("#requires-code").prop("checked") ? $("#required-code").val() : null,
|
|
|
|
autoClosureSeconds: $("#auto-closure-switch").prop("checked") ? parseInt( $("#auto-closure").val() ) : null,
|
|
|
|
parentBuilding: $("#use-building-rules").prop("checked") ? $("#parent-building").data("buildingId") : null,
|
|
|
|
isSliding: $("#is-sliding-door").prop("checked"),
|
|
displayIcon: $("#display-door-icon").prop("checked"),
|
|
|
|
requiresIdentifier: $("#requires-identifier").prop("checked"),
|
|
allowedIdentifiers: getAllowedIdentifiers(),
|
|
|
|
vault: getVaultData(),
|
|
|
|
canBeLockpicked: $("#can-be-lockpicked").prop("checked"),
|
|
alertPoliceOnLockpick: $("#alert-police-on-lockpick").prop("checked"),
|
|
|
|
soundsData: getSoundsData()
|
|
}
|
|
|
|
switch(action) {
|
|
case "create": {
|
|
$.post(`https://${resName}/createDoor`, JSON.stringify(doorData), function(isSuccessful) {
|
|
if(isSuccessful) {
|
|
loadDoors();
|
|
doorModal.modal("hide");
|
|
}
|
|
});
|
|
|
|
break;
|
|
}
|
|
|
|
case "edit": {
|
|
let doorsId = doorModal.data("doorsId");
|
|
|
|
$.post(`https://${resName}/updateDoor`, JSON.stringify({doorsId: doorsId, doorData: doorData}), function(isSuccessful) {
|
|
if(isSuccessful) {
|
|
loadDoors();
|
|
doorModal.modal("hide");
|
|
}
|
|
});
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
function submitBuilding() {
|
|
let buildingModal = $("#door-modal");
|
|
|
|
let action = buildingModal.data("action");
|
|
|
|
let buildingData = {
|
|
label: $("#door-label").val(),
|
|
defaultState: parseInt( $("input[name='doors-default-state']:checked").val() ),
|
|
|
|
allowedJobs: $("#requires-job").prop("checked") ? $("#allowed-jobs").data("allowedJobs") : null,
|
|
allowedGangs: $("#requires-gang").prop("checked") ? $("#allowed-gangs").data("allowedGangs") : null,
|
|
requiredItem: $("#requires-item").prop("checked") ? $("#required-item").val() : null,
|
|
requiredItemRemoveOnUse: $("#required-item-remove-on-use").prop("checked"),
|
|
|
|
requiresJobAndItem: $("#requires-job-and-item").prop("checked"),
|
|
|
|
requiredCode: $("#requires-code").prop("checked") ? $("#required-code").val() : null,
|
|
|
|
autoClosureSeconds: $("#auto-closure-switch").prop("checked") ? parseInt( $("#auto-closure").val() ) : null,
|
|
|
|
requiresIdentifier: $("#requires-identifier").prop("checked"),
|
|
allowedIdentifiers: getAllowedIdentifiers()
|
|
|
|
}
|
|
|
|
switch(action) {
|
|
case "create": {
|
|
$.post(`https://${resName}/createBuilding`, JSON.stringify(buildingData), function(isSuccessful) {
|
|
if(isSuccessful) {
|
|
loadBuildings();
|
|
buildingModal.modal("hide");
|
|
}
|
|
});
|
|
|
|
break;
|
|
}
|
|
|
|
case "edit": {
|
|
let buildingId = buildingModal.data("buildingId");
|
|
|
|
$.post(`https://${resName}/updateBuilding`, JSON.stringify({buildingId: buildingId, buildingData: buildingData}), function(isSuccessful) {
|
|
if(isSuccessful) {
|
|
loadBuildings();
|
|
buildingModal.modal("hide");
|
|
}
|
|
});
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
$("#door-form").submit(function(event) {
|
|
if(isThereAnyErrorInForm(event)) return;
|
|
|
|
let type = $("#door-modal").data("type");
|
|
|
|
if(type == "door") {
|
|
submitDoor();
|
|
} else if(type == "building") {
|
|
submitBuilding();
|
|
}
|
|
})
|
|
|
|
$("#delete-door-btn").click(function() {
|
|
let doorModal = $("#door-modal");
|
|
|
|
let type = doorModal.data("type");
|
|
|
|
switch(type) {
|
|
case "door": {
|
|
let doorsId = doorModal.data("doorsId");
|
|
|
|
$.post(`https://${resName}/deleteDoor`, JSON.stringify({doorsId: doorsId}), function(isSuccessful) {
|
|
if(isSuccessful) {
|
|
loadDoors();
|
|
doorModal.modal("hide");
|
|
}
|
|
});
|
|
|
|
break;
|
|
}
|
|
|
|
case "building": {
|
|
let buildingId = doorModal.data("buildingId");
|
|
|
|
$.post(`https://${resName}/deleteBuilding`, JSON.stringify({buildingId: buildingId}), function(isSuccessful) {
|
|
if(isSuccessful) {
|
|
loadBuildings();
|
|
doorModal.modal("hide");
|
|
}
|
|
});
|
|
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
|
|
/* DOORS - Jobs */
|
|
$("#requires-job").change(function() {
|
|
let isEnabled = $(this).prop("checked");
|
|
|
|
$("#choose-jobs-btn").prop("disabled", !isEnabled);
|
|
});
|
|
|
|
$("#choose-jobs-btn").click(async function() {
|
|
const oldJobs = $("#allowed-jobs").data("allowedJobs");
|
|
|
|
let allowedJobs = await jobsDialog(oldJobs);
|
|
|
|
setRequiredJob(allowedJobs ? true : false, allowedJobs);
|
|
});
|
|
|
|
/* DOORS - Gangs QBCore */
|
|
$("#requires-gang").change(function() {
|
|
let isEnabled = $(this).prop("checked");
|
|
|
|
$("#choose-gangs-btn").prop("disabled", !isEnabled);
|
|
});
|
|
|
|
$("#choose-gangs-btn").click(async function() {
|
|
const oldGangs = $("#allowed-gangs").data("allowedGangs");
|
|
|
|
let allowedGangs = await gangsDialog(oldGangs);
|
|
|
|
setRequiredGang(allowedGangs ? true : false, allowedGangs);
|
|
});
|
|
|
|
/* DOORS - Item */
|
|
$("#requires-item").change(function() {
|
|
let isEnabled = $(this).prop("checked");
|
|
|
|
$("#choose-item-btn").prop("disabled", !isEnabled);
|
|
$("#required-item").prop("disabled", !isEnabled);
|
|
$("#required-item").prop("required", isEnabled);
|
|
$("#required-item-remove-on-use").prop("checked", false).prop("disabled", !isEnabled);
|
|
});
|
|
|
|
$("#choose-item-btn").click(async function() {
|
|
const itemName = await itemsDialog();
|
|
if(!itemName) return;
|
|
|
|
$("#required-item").val(itemName);
|
|
});
|
|
|
|
/* DOORS - Item & Job */
|
|
function requiresBothJobAndItem() {
|
|
let requiresItem = $("#requires-item").prop("checked");
|
|
let requiresJob = $("#requires-job").prop("checked");
|
|
|
|
let requiresBoth = requiresItem && requiresJob;
|
|
|
|
$("#requires-job-and-item-div").toggle(requiresBoth);
|
|
|
|
if(!requiresBoth) {
|
|
$("#requires-job-and-item").prop("checked", false);
|
|
}
|
|
}
|
|
$("#requires-item, #requires-job").change(requiresBothJobAndItem);
|
|
|
|
/* DOORS - Auto closure */
|
|
$("#auto-closure-switch").change(function() {
|
|
let isEnabled = $(this).prop("checked");
|
|
|
|
$("#auto-closure").prop("disabled", !isEnabled);
|
|
})
|
|
|
|
function setAutoClosure(seconds) {
|
|
$("#auto-closure-switch").prop("checked", seconds ? true : false).change();
|
|
$("#auto-closure").val(seconds ? seconds : null);
|
|
}
|
|
|
|
/* BUILDINGS */
|
|
let buildingsDatatable = $("#buildings-container").DataTable( {
|
|
"lengthMenu": [10, 15, 20],
|
|
"columnDefs": [
|
|
{
|
|
"targets": -1, // Ultima colonna
|
|
"data": null,
|
|
"className": "col-1",
|
|
"defaultContent": `
|
|
<div class="d-inline-flex gap-3">
|
|
<div class="btn-group" role="group">
|
|
<button class='btn btn-success py-0 px-2 unlock-building-btn'><i class=\"bi bi-unlock\"></i></button>
|
|
<button class='btn btn-danger py-0 px-2 lock-building-btn'><i class=\"bi bi-lock\"></i></button>
|
|
</div>
|
|
</div>
|
|
`
|
|
}
|
|
],
|
|
"createdRow": async function ( row, data, index ) {
|
|
const buildingData = data[data.length - 1];
|
|
|
|
$(row).addClass("clickable");
|
|
|
|
$(row).click(function() {
|
|
editBuilding(buildingData.id);
|
|
})
|
|
|
|
$(row).find(".unlock-building-btn").click(function(event) {
|
|
event.stopPropagation();
|
|
|
|
$.post(`https://${resName}/setBuildingLockState`, JSON.stringify({buildingId: buildingData.id, newState: 0}));
|
|
});
|
|
|
|
$(row).find(".lock-building-btn").click(function(event) {
|
|
event.stopPropagation();
|
|
|
|
$.post(`https://${resName}/setBuildingLockState`, JSON.stringify({buildingId: buildingData.id, newState: 1}));
|
|
});
|
|
},
|
|
} );
|
|
|
|
let buildings = {};
|
|
|
|
function loadBuildings() {
|
|
$.post(`https://${resName}/getAllBuildings`, {}, async function(rawBuildings) {
|
|
// Manually create the table to avoid incompatibilities due table indexing
|
|
|
|
buildings = {};
|
|
|
|
for(const[k, buildingData] of Object.entries(rawBuildings)) {
|
|
buildings[buildingData.id] = buildingData;
|
|
}
|
|
|
|
buildingsDatatable.clear();
|
|
|
|
for(const[buildingId, buildingData] of Object.entries(buildings)) {
|
|
buildingsDatatable.row.add([
|
|
buildingId,
|
|
buildingData.label,
|
|
buildingData.defaultState === 0 ? getLocalizedText("menu:unlocked") : getLocalizedText("menu:locked"),
|
|
buildingData
|
|
])
|
|
}
|
|
|
|
buildingsDatatable.draw()
|
|
})
|
|
}
|
|
|
|
$("#new-building-btn").click(function() {
|
|
let buildingModal = $("#door-modal");
|
|
|
|
setDoorsModalType("building");
|
|
setupDefaultModalValues();
|
|
|
|
buildingModal.data("action", "create");
|
|
|
|
buildingModal.modal("show");
|
|
});
|
|
|
|
function editBuilding(buildingId) {
|
|
let buildingData = buildings[buildingId];
|
|
|
|
setDoorsModalType("building");
|
|
|
|
let buildingModal = $("#door-modal");
|
|
|
|
buildingModal.data("action", "edit");
|
|
|
|
buildingModal.find("input .form-control").val("");
|
|
buildingModal.data("buildingId", buildingId);
|
|
|
|
// Converts from create modal to edit modal
|
|
buildingModal.data("action", "edit");
|
|
|
|
$("#delete-door-btn").show();
|
|
$("#save-door-btn").text( getLocalizedText("menu:save") );
|
|
|
|
$("#door-label").val(buildingData.label);
|
|
|
|
$(`input[name="doors-default-state"][value="${buildingData.defaultState}"]`).prop("checked", true);
|
|
|
|
setRequiredJob(buildingData.allowedJobs ? true : false, buildingData.allowedJobs);
|
|
setRequiredGang(buildingData.allowedGangs ? true : false, buildingData.allowedGangs);
|
|
|
|
setRequiredItem(buildingData.requiredItem ? true : false, buildingData.requiredItem);
|
|
$("#required-item-remove-on-use").prop("checked", buildingData.requiredItem && buildingData.requiredItemRemoveOnUse);
|
|
|
|
setRequiredCode(buildingData.requiredCode);
|
|
|
|
setAutoClosure(buildingData.autoClosureSeconds);
|
|
|
|
$("#requires-job-and-item").prop("checked", buildingData.requiresJobAndItem);
|
|
|
|
// Requires identifier
|
|
$("#requires-identifier").prop("checked", buildingData.requiresIdentifier).change();
|
|
|
|
// Add identifiers
|
|
$("#allowed-identifiers").empty();
|
|
if(buildingData.allowedIdentifiers) {
|
|
for(const [identifier, _] of Object.entries(buildingData.allowedIdentifiers)) {
|
|
addIdentifierToList(identifier);
|
|
}
|
|
}
|
|
|
|
buildingModal.modal("show");
|
|
}
|
|
|
|
$("#use-building-rules").change(function() {
|
|
let isEnabled = $(this).prop("checked");
|
|
|
|
$("#choose-building-btn").prop("disabled", !isEnabled);
|
|
|
|
if(isEnabled) {
|
|
hideBuildingOptions();
|
|
} else {
|
|
showBuildingOptions();
|
|
}
|
|
})
|
|
|
|
$("#choose-building-btn").click(async function() {
|
|
const buildingId = await buildingsDialog();
|
|
if(!buildingId) return;
|
|
|
|
setParentBuilding(buildingId);
|
|
});
|
|
|
|
/* SETTINGS */
|
|
$("#settings_enableDoorlockAnimation").change(function() {
|
|
let isEnabled = $(this).prop("checked");
|
|
|
|
$("#doorlock-animation-div").find("input").prop("disabled", !isEnabled).prop("required", isEnabled);
|
|
})
|
|
|
|
function setDoorlockAnimation(doorLockAnimation) {
|
|
$("#settings_enableDoorlockAnimation").prop("checked", doorLockAnimation.isEnabled).change();
|
|
|
|
$("#settings_doorlockAnimationDictionary").val(doorLockAnimation.dict);
|
|
$("#settings_doorlockAnimationName").val(doorLockAnimation.name);
|
|
$("#settings_doorlockAnimationDuration").val(doorLockAnimation.duration);
|
|
}
|
|
|
|
function getDoorlockAnimation() {
|
|
if( $("#settings_enableDoorlockAnimation").prop("checked") ) {
|
|
let doorLockAnimation = {
|
|
dict: $("#settings_doorlockAnimationDictionary").val(),
|
|
name: $("#settings_doorlockAnimationName").val(),
|
|
duration: parseInt( $("#settings_doorlockAnimationDuration").val() ),
|
|
isEnabled: true
|
|
}
|
|
|
|
return doorLockAnimation;
|
|
} else {
|
|
let doorLockAnimation = {
|
|
isEnabled: false
|
|
}
|
|
|
|
return doorLockAnimation;
|
|
}
|
|
}
|
|
|
|
$("#import-from-qb-doorlock-btn").click(async function() {
|
|
if(!await confirmWarning(getLocalizedText("menu:backup_reccomended"))) return;
|
|
|
|
const response = await $.post(`https://${resName}/importFromQbDoorlock`, JSON.stringify({}));
|
|
|
|
if(response === true) {
|
|
loadDoors();
|
|
}
|
|
|
|
showServerResponse(response);
|
|
});
|
|
|
|
$("#import-from-ox-doorlock-btn").click(async function() {
|
|
if(!await confirmWarning(getLocalizedText("menu:backup_reccomended"))) return;
|
|
|
|
const response = await $.post(`https://${resName}/importFromOxDoorlock`, JSON.stringify({}));
|
|
|
|
if(response === true) {
|
|
loadDoors();
|
|
}
|
|
|
|
showServerResponse(response);
|
|
});
|
|
|
|
function loadSettings(fullConfig) {
|
|
setTomSelectValue("#settings_locale", fullConfig.locale);
|
|
|
|
$("#settings_acePermission").val(fullConfig.acePermission);
|
|
$("#settings_saveDoorStateAfterRestart").prop("checked", fullConfig.saveDoorStateAfterRestart);
|
|
|
|
$("#settings_doorlockIconSize").val(fullConfig.doorLockIconSize);
|
|
|
|
$("#settings_lockpickName").val(fullConfig.lockpickName);
|
|
$("#settings_lockpickMinimumQuantity").val(fullConfig.lockpickMinimumQuantity);
|
|
$("#settings_lockpickLoseOnUse").prop("checked", fullConfig.lockpickLoseOnUse);
|
|
$("#settings_lockpickMinimumPolice").val(fullConfig.lockpickMinimumPolice);
|
|
|
|
// Door icon
|
|
$("#settings_use3dTextInsteadOfIcon").prop("checked", fullConfig.use3dTextInsteadOfIcon);
|
|
$("#settings_exclusiveDoorIcon").prop("checked", fullConfig.exclusiveDoorIcon);
|
|
|
|
setDoorlockAnimation(fullConfig.doorLockAnimation);
|
|
|
|
// Targeting
|
|
setTomSelectValue("settings-targeting-script", fullConfig.targetingScript);
|
|
|
|
// Keys
|
|
$("#settings-confirm-key").val(fullConfig.confirmKey);
|
|
$("#settings-key-to-toggle-door-status").val(fullConfig.keyToToggleDoorStatus);
|
|
}
|
|
|
|
$("#settings").submit(async function(event) {
|
|
if(isThereAnyErrorInForm(event)) return;
|
|
|
|
let clientSettings = {
|
|
doorLockAnimation: getDoorlockAnimation(),
|
|
doorLockIconSize: parseFloat( $("#settings_doorlockIconSize").val() ),
|
|
use3dTextInsteadOfIcon: $("#settings_use3dTextInsteadOfIcon").prop("checked"),
|
|
targetingScript:$("#settings-targeting-script").val(),
|
|
confirmKey: parseInt( $("#settings-confirm-key").val() ),
|
|
keyToToggleDoorStatus: parseInt( $("#settings-key-to-toggle-door-status").val() ),
|
|
exclusiveDoorIcon: $("#settings_exclusiveDoorIcon").prop("checked"),
|
|
}
|
|
|
|
let sharedSettings = {
|
|
locale: $("#settings_locale").val(),
|
|
lockpickName: $("#settings_lockpickName").val(),
|
|
}
|
|
|
|
let serverSettings = {
|
|
acePermission: $("#settings_acePermission").val(),
|
|
saveDoorStateAfterRestart: $("#settings_saveDoorStateAfterRestart").prop("checked"),
|
|
|
|
lockpickMinimumQuantity: parseInt( $("#settings_lockpickMinimumQuantity").val() ),
|
|
lockpickLoseOnUse: $("#settings_lockpickLoseOnUse").prop("checked"),
|
|
lockpickMinimumPolice: parseInt( $("#settings_lockpickMinimumPolice").val() )
|
|
}
|
|
|
|
const response = await $.post(`https://${resName}/saveSettings`, JSON.stringify({ clientSettings, serverSettings, sharedSettings}));
|
|
showServerResponse(response);
|
|
|
|
refreshTranslations(sharedSettings.locale);
|
|
});
|
|
|
|
// Doors Identifiers
|
|
$("#requires-identifier").change(function() {
|
|
let isEnabled = $(this).prop("checked");
|
|
|
|
$("#identifiers-div").find("input, button").prop("disabled", !isEnabled);
|
|
});
|
|
|
|
$("#is-vault-door").change(function() {
|
|
let isEnabled = $(this).prop("checked");
|
|
|
|
$("#vault-door-options").toggle(isEnabled);
|
|
|
|
$("#vault-speed").prop("required", isEnabled);
|
|
|
|
if(isEnabled) {
|
|
$(`input[name="vault-type"][value="heading"]`).prop("checked", true).change();
|
|
} else {
|
|
$("#vault-opened-angle").prop("required", false);
|
|
$("#vault-closed-angle").prop("required", false);
|
|
}
|
|
})
|
|
|
|
$(`input[name="vault-type"]`).change(function() {
|
|
let type = $(this).val();
|
|
|
|
if(type == "ratio") {
|
|
$("#vault-opened-angle").attr('placeholder', "Usually 1.0 or -1.0").prop("required", false);
|
|
$("#vault-closed-angle").attr('placeholder', "Usually 0.0").prop("required", false);
|
|
$("#vault-get-opened-heading").hide();
|
|
$("#vault-get-closed-heading").hide();
|
|
} else {
|
|
$("#vault-opened-angle").attr('placeholder', "0-360").prop("required", true);
|
|
$("#vault-closed-angle").attr('placeholder', "0-360").prop("required", true);
|
|
$("#vault-get-opened-heading").show();
|
|
$("#vault-get-closed-heading").show();
|
|
}
|
|
});
|
|
|
|
async function getHeadingOfFirstDoorObject() {
|
|
return new Promise((resolve, reject) => {
|
|
closeMenu();
|
|
let doorModal = $("#door-modal");
|
|
doorModal.modal("hide");
|
|
|
|
const doorObject = $("#used-doors-table").find(".used-door").first().data("doorObject");
|
|
|
|
$.post(`https://${resName}/getHeading`, JSON.stringify({doorObject: doorObject}), function(heading) {
|
|
$("#doors_creator").show();
|
|
doorModal.modal("show");
|
|
|
|
resolve( Math.floor(heading) );
|
|
});
|
|
})
|
|
}
|
|
|
|
$("#vault-get-opened-heading").click(async function() {
|
|
const heading = await getHeadingOfFirstDoorObject();
|
|
$("#vault-opened-angle").val(heading);
|
|
})
|
|
|
|
$("#vault-get-closed-heading").click(async function() {
|
|
const heading = await getHeadingOfFirstDoorObject();
|
|
$("#vault-closed-angle").val(heading);
|
|
})
|
|
|
|
function addIdentifierToList(identifier) {
|
|
let allowedIdentifiers = $("#allowed-identifiers");
|
|
|
|
let identifierDiv = $(`
|
|
<li class="list-group-item mt-1" data-identifier="${identifier}">${identifier} <span class="btn-close float-end clickable"></span></li>
|
|
`)
|
|
|
|
identifierDiv.find(".btn-close").click(function() {
|
|
$(this).parent().remove();
|
|
});
|
|
|
|
allowedIdentifiers.append(identifierDiv);
|
|
}
|
|
|
|
$("#add-identifier-btn").click(function() {
|
|
let identifierDiv = $("#identifier-to-add")
|
|
let identifier = identifierDiv.val();
|
|
|
|
if(identifier) {
|
|
addIdentifierToList(identifier);
|
|
identifierDiv.val("");
|
|
}
|
|
})
|
|
|
|
$("#choose-player-btn").click(function() {
|
|
playersListDialog(identifier => {
|
|
$("#identifier-to-add").val(identifier);
|
|
});
|
|
})
|
|
|
|
function getAllowedIdentifiers() {
|
|
let identifiers = {};
|
|
|
|
$("#allowed-identifiers").find("li").each(function() {
|
|
identifiers[$(this).data("identifier")] = true;
|
|
});
|
|
|
|
return identifiers;
|
|
}
|
|
|
|
function getVaultData() {
|
|
if(!$("#is-vault-door").prop("checked"))
|
|
return null;
|
|
|
|
let vaultData = {
|
|
speed: parseFloat( $("#vault-speed").val() ),
|
|
doorHeavy: $("#vault-make-door-extremely-heavy").prop("checked"),
|
|
invertedDirection: $("#vault-inverted-direction").prop("checked"),
|
|
openedAngle: parseFloat( $("#vault-opened-angle").val() ),
|
|
closedAngle: parseFloat( $("#vault-closed-angle").val() ),
|
|
type: $('input[name="vault-type"]:checked').val()
|
|
}
|
|
|
|
return vaultData
|
|
}
|
|
|
|
function setVaultData(vaultData) {
|
|
if(vaultData) {
|
|
$("#is-vault-door").prop("checked", true).change();
|
|
$("#vault-speed").val(vaultData.speed);
|
|
$("#vault-make-door-extremely-heavy").prop("checked", vaultData.doorHeavy);
|
|
$("#vault-inverted-direction").prop("checked", vaultData.invertedDirection);
|
|
$("#vault-opened-angle").val(vaultData.openedAngle);
|
|
$("#vault-closed-angle").val(vaultData.closedAngle);
|
|
$(`input[name="vault-type"][value=${vaultData.type || "ratio"}]`).prop("checked", true).change();
|
|
} else {
|
|
$("#is-vault-door").prop("checked", false).change();
|
|
}
|
|
}
|
|
|
|
function getSoundsData() {
|
|
let unlockSound = $("#unlock-sound").val();
|
|
let lockSound = $("#lock-sound").val();
|
|
|
|
return {
|
|
unlockSound: unlockSound == "none" ? null : unlockSound,
|
|
lockSound: lockSound == "none" ? null : lockSound
|
|
}
|
|
}
|
|
|
|
function setSoundsData(data) {
|
|
if(!data) {
|
|
setTomSelectValue("#unlock-sound", "none");
|
|
setTomSelectValue("#lock-sound", "none");
|
|
|
|
return;
|
|
};
|
|
|
|
setTomSelectValue("#unlock-sound", data.unlockSound);
|
|
setTomSelectValue("#lock-sound", data.lockSound);
|
|
}
|
|
|
|
function reloadAllData() {
|
|
resetNexus();
|
|
loadBuildings();
|
|
loadDoors();
|
|
}
|
|
|
|
// Open/Close menu
|
|
async function openMenu(version, fullConfig) {
|
|
$("#doors-creator-version").text(version);
|
|
$("#doors_creator").show();
|
|
|
|
reloadAllData();
|
|
|
|
loadSettings(fullConfig);
|
|
|
|
if(await getFramework() == "QB-core") {
|
|
$("#requires-gang-div").show()
|
|
}
|
|
}
|
|
|
|
function closeMenu() {
|
|
// Resets current active tab
|
|
$("#doors_creator").find(".nav-link, .tab-pane").each(function() {
|
|
if($(this).data("isDefault") == "1") {
|
|
$(this).addClass(["active", "show"])
|
|
} else {
|
|
$(this).removeClass(["active", "show"])
|
|
}
|
|
})
|
|
|
|
$("#doors_creator").hide();
|
|
|
|
$.post(`https://${resName}/close`, {})
|
|
}
|
|
$("#close-main-btn").click(closeMenu);
|
|
|
|
$("#input-div").submit(function(event) {
|
|
if(isThereAnyErrorInForm(event)) return;
|
|
|
|
let input = $("#code-input").val();
|
|
|
|
$.post(`https://${resName}/receiveInput`, JSON.stringify({input: input}));
|
|
|
|
$("#code-input").val("");
|
|
})
|
|
|
|
$("#code-input-cancel-btn").click(function() {
|
|
$.post(`https://${resName}/cancelInput`, JSON.stringify({}));
|
|
})
|
|
|
|
// [[ NEXUS ]]
|
|
const voteInstanceRater = raterJs({
|
|
starSize: 35,
|
|
element: document.querySelector("#vote-instance-rater"),
|
|
rateCallback: async function rateCallback(rating, done) {
|
|
const instanceId = $("#nexus-modal").data("instance").id;
|
|
const success = await $.post(`https://${resName}/nexus/rateInstance`, JSON.stringify({rating, instanceId}));
|
|
if(success) voteInstanceRater.setRating(rating);
|
|
|
|
done();
|
|
}
|
|
});
|
|
|
|
const averageInstanceVotes = raterJs({
|
|
starSize: 20,
|
|
readOnly: true,
|
|
element: document.querySelector("#nexus-modal-instance-average-rating"),
|
|
});
|
|
|
|
$("#nexus-import-instance-btn").click(async function() {
|
|
const instance = $("#nexus-modal").data("instance");
|
|
const id = instance.id;
|
|
|
|
const response = await $.post(`https://${resName}/nexus/importInstance`, JSON.stringify({id}));
|
|
$("#nexus-modal").modal("hide");
|
|
|
|
if(response === true) reloadAllData();
|
|
|
|
showServerResponse(response);
|
|
});
|
|
|
|
let nexusDataTable = $("#nexus-table").DataTable({
|
|
"lengthMenu": [5, 10, 15, 20],
|
|
"pageLength": 5,
|
|
"order": [[4, 'desc'], [5, 'desc']],
|
|
"createdRow": function(row, data, index) {
|
|
$(row).addClass("clickable");
|
|
$(row).click(function() {
|
|
const instance = $(this).data("instance");
|
|
showInstance(instance);
|
|
$("#nexus-modal").modal("show");
|
|
});
|
|
},
|
|
"columnDefs": [
|
|
{ "defaultContent": "???", "targets": "_all" },
|
|
{
|
|
"targets": 2,
|
|
render: function(data, type, row) {
|
|
if(!data) return 9999;
|
|
if(type === "display" || type === "filter") return data + "m";
|
|
return parseFloat(data);
|
|
}
|
|
}
|
|
]
|
|
});
|
|
|
|
function showInstance(instance) {
|
|
$("#nexus-modal").data("instance", instance);
|
|
|
|
$("#nexus-modal-instance-listing-label").text(instance.label);
|
|
$("#nexus-modal-instance-description").text(instance.description || getLocalizedText("menu:nexus:no_description"));
|
|
$("#nexus-modal-instance-author").text(instance.author);
|
|
$("#nexus-instance-building-name").text(instance.content.building.label);
|
|
|
|
// Content names and labels
|
|
|
|
$("#nexus-modal-instance-content").empty();
|
|
instance.content.doors.forEach(content => {
|
|
$("#nexus-modal-instance-content").append(`
|
|
<li class="list-group-item">${content.label || content.name}</li>
|
|
`);
|
|
});
|
|
|
|
// Votes
|
|
if(instance?.votes?.total > 0) {
|
|
averageInstanceVotes.setRating(instance?.votes.averageRating);
|
|
} else {
|
|
averageInstanceVotes.setRating(0);
|
|
}
|
|
|
|
$("#nexus-modal-instance-total-votes").text(instance.votes?.total || 0);
|
|
|
|
// This server vote
|
|
voteInstanceRater.setRating(0);
|
|
}
|
|
|
|
$("#upload-to-nexus-btn").click(async function() {
|
|
const buildingId = await buildingsDialog();
|
|
if(!buildingId) return;
|
|
|
|
$("#nexus-modal-upload").data("buildingId", buildingId);
|
|
|
|
$("#nexus-upload-label").val("");
|
|
$("#nexus-upload-description").val("");
|
|
|
|
$("#nexus-upload-accept-tos").prop("checked", false);
|
|
|
|
$("#nexus-modal-upload").modal("show");
|
|
});
|
|
|
|
$("#nexus-upload-form").submit(async function(event) {
|
|
if(isThereAnyErrorInForm(event)) return;
|
|
|
|
const dataToUpload = {
|
|
buildingId: $("#nexus-modal-upload").data("buildingId"),
|
|
label: $("#nexus-upload-label").val(),
|
|
description: $("#nexus-upload-description").val(),
|
|
}
|
|
|
|
const result = await $.post(`https://${resName}/nexus/uploadData`, JSON.stringify(dataToUpload));
|
|
|
|
if(result == true) {
|
|
swal("Success", getLocalizedText("menu:nexus:upload_success"), "success");
|
|
resetNexus();
|
|
} else {
|
|
swal("Error", result, "error");
|
|
}
|
|
|
|
$("#nexus-modal-upload").modal("hide");
|
|
});
|
|
|
|
async function getInstancesDoorsDistance(instances) {
|
|
return await $.post(`https://${resName}/nexus/getInstancesDoorsDistance`, JSON.stringify({instances}));
|
|
}
|
|
|
|
$("#enter-in-nexus-btn").click(async function() {
|
|
$("#nexus-login").find(".spinner-border").show();
|
|
$("#enter-in-nexus-label").text("...");
|
|
|
|
const sharedData = await $.get(`https://${resName}/nexus/getSharedData`);
|
|
if(!sharedData) {
|
|
swal("Error", getLocalizedText("menu:nexus:not_available"), "error");
|
|
resetNexus();
|
|
return;
|
|
}
|
|
|
|
nexusDataTable.clear()
|
|
|
|
const distances = await getInstancesDoorsDistance(sharedData);
|
|
|
|
Object.values(sharedData).forEach(instance => {
|
|
const roundedAverageRating = instance?.votes?.averageRating ? Math.round(instance.votes.averageRating) : 0;
|
|
const ratingStars = instance?.votes?.total ? "⭐".repeat(roundedAverageRating) : getLocalizedText("menu:nexus:not_rated");
|
|
const limitedDescription = instance.description?.length > 30 ? instance.description.substring(0, 30) + "..." : instance.description;
|
|
const doorsCount = instance.content.doors.length;
|
|
const distance = distances[instance.id];
|
|
|
|
const rawRow = nexusDataTable.row.add( [instance.label, limitedDescription, distance, doorsCount, ratingStars, instance.votes?.total || 0, instance.author] );
|
|
|
|
const rowDiv = $(rawRow.node());
|
|
$(rowDiv).data("instance", instance);
|
|
})
|
|
|
|
nexusDataTable.draw();
|
|
|
|
$("#nexus-login").hide();
|
|
$("#nexus-container").show();
|
|
})
|
|
|
|
function resetNexus() {
|
|
$("#nexus-login").show();
|
|
$("#nexus-login").find(".spinner-border").hide();
|
|
$("#enter-in-nexus-label").text("Enter in Nexus");
|
|
|
|
$("#nexus-container").hide();
|
|
}
|
|
|
|
|
|
// Messages received by client
|
|
window.addEventListener('message', (event) => {
|
|
let data = event.data;
|
|
let action = data.action;
|
|
|
|
switch (action) {
|
|
case 'openMenu':
|
|
openMenu(data.version, data.fullConfig);
|
|
break;
|
|
case 'notification':
|
|
showNotification(data.message, data.duration);
|
|
break;
|
|
case 'getInput':
|
|
$("#input-div").show();
|
|
$("#code-input").focus().val("");
|
|
break;
|
|
case 'hideInput':
|
|
$("#input-div").hide();
|
|
break;
|
|
case "sound":
|
|
const sound = document.createElement("audio");
|
|
sound.src = `../audio/${data.soundId}`;
|
|
sound.volume = data.calculatedVolume;
|
|
sound.play();
|
|
break;
|
|
}
|
|
})
|
|
|
|
// Closes menu when clicking ESC
|
|
$(document).on('keyup', function(e) {
|
|
if (e.key != "Escape") return;
|
|
closeMenu();
|
|
}); |