1
0
Fork 0
forked from Simnation/Main
Main/resources/[creator]/dealerships_creator/html/index.js

1208 lines
39 KiB
JavaScript
Raw Normal View History

2025-06-07 08:51:21 +02:00
const resName = GetParentResourceName();
let hasDoorsCreator = null; // editing this is useless, don't do it
// Open/Close menu
function openMenu(version, fullConfig) {
$("#dealerships-creator-version").text(version);
loadDealerships();
loadVehicles();
loadClasses();
loadSettings(fullConfig);
$("#dealerships-creator").show()
}
function closeMenu() {
// Resets current active tab
$("#dealerships-creator").find(".nav-link, .tab-pane").each(function() {
if($(this).data("isDefault") == "1") {
$(this).addClass(["active", "show"])
} else {
$(this).removeClass(["active", "show"])
}
})
$("#dealerships-creator").hide();
$.post(`https://${resName}/close`)
}
$("#close-main-btn").click(closeMenu);
// 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 "hasDoorsCreator": {
hasDoorsCreator = data.hasDoorsCreator;
break;
}
}
})
/*
*/
/* Discord logs */
function toggleDiscordLogsInSettings(enable) {
$("#settings-mainDiscordWebhook").prop("disabled", !enable);
$("#settings-mainDiscordWebhook").prop("required", enable);
$("#settings-specific-webooks-div").find(`.form-control`).prop("disabled", !enable);
}
$("#settings-areDiscordLogsActive").change(function() {
let enabled = $(this).prop("checked");
toggleDiscordLogsInSettings(enabled);
})
function getSeparatedDiscordWebhooks() {
let webhooks = {};
$("#settings-specific-webooks-div").find(".form-control").each(function(index, element) {
let webhook = $(element).val();
if(!webhook) return;
let logType = $(element).data("logType");
webhooks[logType] = webhook;
});
return webhooks;
}
/* Discord logs END */
function loadSettings(fullConfig) {
// Generic
$("#settings-locale").val(fullConfig.locale);
$("#settings-ace-permission").val(fullConfig.acePermission);
$("#settings-can-always-carry").prop("checked", fullConfig.canAlwaysCarryItem);
// Help notification
setTomSelectValue("#settings-help-notification-script", fullConfig.helpNotification)
// Discord logs
$("#settings-areDiscordLogsActive").prop("checked", fullConfig.areDiscordLogsActive);
$("#settings-mainDiscordWebhook").val(fullConfig.mainDiscordWebhook);
toggleDiscordLogsInSettings(fullConfig.areDiscordLogsActive);
for(const[logType, webhook] of Object.entries(fullConfig.specificWebhooks)) {
$("#settings-specific-webooks-div").find(`[data-log-type="${logType}"]`).val(webhook);
}
// Discord logs - END
// Player dealership
$("#settings-minutes-to-receive-vehicle-after-order").val(fullConfig.minutesToReceiveVehicleAfterOrder);
$("#settings-persistent-displayed-vehicles").prop("checked", fullConfig.persistentDisplayedVehicles);
}
$("#settings").submit(async function(event) {
if(isThereAnyErrorInForm(event)) return;
let clientSettings = {
helpNotification: $("#settings-help-notification-script").val(),
}
let sharedSettings = {
locale: $("#settings-locale").val(),
}
let serverSettings = {
// Generic
acePermission: $("#settings-ace-permission").val(),
canAlwaysCarryItem: $("#settings-can-always-carry").prop("checked"),
// Discord logs
areDiscordLogsActive: $("#settings-areDiscordLogsActive").prop("checked"),
mainDiscordWebhook: $("#settings-mainDiscordWebhook").val(),
specificWebhooks: getSeparatedDiscordWebhooks(),
// Player dealership
minutesToReceiveVehicleAfterOrder: parseInt( $("#settings-minutes-to-receive-vehicle-after-order").val() ),
persistentDisplayedVehicles: $("#settings-persistent-displayed-vehicles").prop("checked"),
}
const response = await $.post(`https://${resName}/saveSettings`, JSON.stringify({
clientSettings: clientSettings,
serverSettings: serverSettings,
sharedSettings: sharedSettings
}));
showServerResponse(response);
refreshTranslations(sharedSettings.locale);
});
/*
*/
let dealershipsDatatable = $("#dealerships-container").DataTable( {
"lengthMenu": [10, 15, 20],
"createdRow": function ( row, data, index ) {
$(row).addClass("clickable");
$(row).click(function() {
let id = parseInt( data[0] );
editDealership(id);
})
},
});
let dealerships = {};
async function loadDealerships() {
const rawDealerships = await $.post(`https://${resName}/getAllDealerships`);
// Manually create the table to avoid incompatibilities due table indexing
dealerships = {};
for(const[k, dealershipData] of Object.entries(rawDealerships)) {
dealerships[dealershipData.id] = dealershipData;
}
dealershipsDatatable.clear();
for(const[id, dealershipData] of Object.entries(dealerships)) {
dealershipsDatatable.row.add([
id,
dealershipData.label
]);
}
dealershipsDatatable.draw();
}
function setDefaultDataOfDealership() {
let dealershipModal = $("#dealership-modal");
// Generic
$(`input[name=dealership-type][value="auto"]`).prop("checked", true).change();
$("#dealership-label").val("Default");
dealershipModal.data("markerData", getDefaultMarkerCustomization());
dealershipModal.data("blipData", getDefaultBlipCustomization());
dealershipModal.data("vehiclesData", null);
$("#dealership-account-name").val("");
$("#dealership-account-name").val("bank");
// Coordinates
$("#auto-dealership-coords-list").empty();
// Spawn points
$("#dealership-spawn-points-list").empty();
// Showroom
$("#dealership-showroom-coords-x").val("");
$("#dealership-showroom-coords-y").val("");
$("#dealership-showroom-coords-z").val("");
$("#dealership-showroom-heading").val("");
// Restrictions
dealershipModal.data("jobsData", null);
setRequiredLicenseForDealership(null);
// Options
$("#dealership-pay-with-society-money").prop("checked", false).change();
$("#dealership-always-open").prop("checked", true).change();
$("#dealership-minutes-before-prices-update").val(0);
$("#dealership-is-resell-active").prop("checked", false).change();
$("#dealership-resell-percentage").val("");
dealershipModal.data("resellPointMarkerData", getDefaultResellCustomization());
setSelectedSocietiesForDealership(false);
// Resell points
$("#dealership-resell-points-list").empty();
// Test drive data
$("#dealership-is-test-drive-active").prop("checked", false).change();
$("#dealership-test-drive-duration").val("");
$("#dealership-test-drive-change-routing-bucket").prop("checked", false);
$("#dealership-test-drive-coords-x").val("");
$("#dealership-test-drive-coords-y").val("");
$("#dealership-test-drive-coords-z").val("");
// Player dealership
$("#player-dealership-price").val("");
$("#player-dealership-resell-percentage").val("");
$("#player-dealership-coords-x").val("");
$("#player-dealership-coords-y").val("");
$("#player-dealership-coords-z").val("");
$("#dealership-enter-showroom-coords-x").val("");
$("#dealership-enter-showroom-coords-y").val("");
$("#dealership-enter-showroom-coords-z").val("");
// Display points
$("#player-dealership-display-points-list").empty();
}
$("#new-dealership-btn").click(function() {
let dealershipModal = $("#dealership-modal");
// Converts from edit modal to create modal
dealershipModal.data("action", "create");
$("#delete-dealership-btn").hide();
$("#save-dealership-btn").text( getLocalizedText("menu:create") );
setDefaultDataOfDealership();
dealershipModal.modal("show");
})
$("#dealership-customize-blip-btn").click(async function() {
let dealershipModal = $("#dealership-modal");
let oldBlipData = dealershipModal.data("blipData");
let blipData = await blipDialog(oldBlipData)
dealershipModal.data("blipData", blipData);
});
$("#dealership-customize-marker-btn").click(async function() {
let dealershipModal = $("#dealership-modal");
let oldMarkerData = dealershipModal.data("markerData");
let markerData = await markerDialog(oldMarkerData)
dealershipModal.data("markerData", markerData);
});
$("#dealership-choose-vehicles-btn").click(async function() {
let dealershipModal = $("#dealership-modal");
let oldVehicles = dealershipModal.data("vehiclesData");
let vehicles = await vehiclesDialog(oldVehicles, true);
dealershipModal.data("vehiclesData", vehicles);
});
$("#dealership-choose-account-btn").click(async function() {
const accountName = await accountsDialog();
$("#dealership-account-name").val(accountName);
});
$("#dealership-choose-jobs-btn").click(async function() {
let dealershipModal = $("#dealership-modal");
let oldJobs = dealershipModal.data("jobsData");
let jobs = await jobsDialog(oldJobs);
dealershipModal.data("jobsData", jobs);
})
function setRequiredLicenseForDealership(licenseType) {
const btn = $("#dealership-choose-required-license-btn");
if(licenseType) {
btn.text(getLocalizedText("menu:license_required") + licenseType);
} else {
btn.text(getLocalizedText("menu:no_license_required"));
}
btn.data("licenseType", licenseType ? licenseType : null);
}
$("#dealership-choose-required-license-btn").click(async function() {
const requiredLicenseType = await licensesDialog();
setRequiredLicenseForDealership(requiredLicenseType);
});
$("#dealership-societies-to-send-money-to-btn").click(async function() {
let dealershipModal = $("#dealership-modal");
let oldSocieties = dealershipModal.data("societiesData");
let societies = await societiesDialog(oldSocieties);
setSelectedSocietiesForDealership(societies);
})
async function setSelectedPayingSociety(jobName) {
let dealershipModal = $("#dealership-modal");
dealershipModal.data("payingSociety", jobName);
const label = jobName ? await getJobLabel(jobName) : getLocalizedText("menu:none");
$("#dealership-paying-society").val(label);
}
$("#dealership-pay-with-society-money").change(function() {
let enabled = $(this).prop("checked");
$("#dealership-choose-paying-society-btn").prop("disabled", !enabled);
$("#dealership-account-name-div").toggle(!enabled);
const loanInput = $("#dealership-loan-is-active");
loanInput.prop("disabled", enabled)
if(enabled) {
loanInput.prop("checked", false).change();
}
if(!enabled) {
setSelectedPayingSociety(null);
}
})
$("#dealership-choose-paying-society-btn").click(async function() {
let jobName = await singleJobDialog();
setSelectedPayingSociety(jobName);
})
async function setSelectedSocietiesForDealership(societies) {
let dealershipModal = $("#dealership-modal");
dealershipModal.data("societiesData", societies);
if(!societies) {
$("#dealership-societies-to-send-money-to").val( getLocalizedText("menu:none") );
return;
}
let jobNames = "";
let isTheFirst = true;
for(const [societyName, percentage] of Object.entries(societies)) {
if(!isTheFirst) {
jobNames += ", ";
} else {
isTheFirst = false;
}
jobNames += await getJobLabel(societyName) + " (" + percentage + "%)";
}
$("#dealership-societies-to-send-money-to").val(jobNames);
}
$("#dealership-loan-is-active").change(function() {
const enabled = $(this).prop("checked");
$("#dealership-loan-percentage").prop("disabled", !enabled).prop("required", enabled);
$("#dealership-loan-interval").prop("disabled", !enabled).prop("required", enabled);
});
$("#dealership-is-resell-active").change(function() {
const enabled = $(this).prop("checked");
$("#dealership-resell-percentage").prop("disabled", !enabled).prop("required", enabled);
$("#dealership-resell-point-customize-marker-btn").prop("disabled", !enabled);
$("#dealership-resell-div").toggle(enabled);
});
$("#dealership-resell-point-customize-marker-btn").click(async function() {
let dealershipModal = $("#dealership-modal");
let oldMarkerData = dealershipModal.data("resellPointMarkerData");
let markerData = await markerDialog(oldMarkerData)
dealershipModal.data("resellPointMarkerData", markerData);
});
$("#dealership-is-test-drive-active").change(function() {
const enabled = $(this).prop("checked");
$("#dealership-test-drive-duration").prop("disabled", !enabled).prop("required", enabled)
$("#dealership-test-drive-change-routing-bucket").prop("disabled", !enabled)
$("#dealership-test-drive-coords-x").prop("disabled", !enabled).prop("required", enabled)
$("#dealership-test-drive-coords-y").prop("disabled", !enabled).prop("required", enabled)
$("#dealership-test-drive-coords-z").prop("disabled", !enabled).prop("required", enabled)
$("#dealership-test-drive-heading").prop("disabled", !enabled).prop("required", enabled)
$("#dealership-test-drive-current-coords-btn").prop("disabled", !enabled)
})
$("#dealership-test-drive-current-coords-btn").click(async function() {
let data = await chooseCoords();
if(!data) return;
$("#dealership-test-drive-coords-x").val(data.coords.x);
$("#dealership-test-drive-coords-y").val(data.coords.y);
$("#dealership-test-drive-coords-z").val(data.coords.z);
$("#dealership-test-drive-heading").val(data.heading);
});
function addPointToPointsList(listDiv, wantsHeading, wantsRadius, pointData) {
let div = $(`
<div class="d-flex gap-1 align-items-center justify-content-center my-2 coords-div">
<button type="button" class="btn-close delete-coords-btn me-2"></button>
<div class="form-floating text-body col">
<input type="number" step="0.01" class="form-control form-control-sm coords-x" placeholder="X" required>
<label>${getLocalizedText("menu:x")}</label>
</div>
<div class="form-floating text-body col">
<input type="number" step="0.01" class="form-control form-control-sm coords-y" placeholder="Y" required>
<label>${getLocalizedText("menu:y")}</label>
</div>
<div class="form-floating text-body col">
<input type="number" step="0.01" class="form-control form-control-sm coords-z" placeholder="Z" required>
<label>${getLocalizedText("menu:z")}</label>
</div>
<div class="form-floating text-body col heading-div">
<input type="number" step="0.01" class="form-control form-control-sm heading" placeholder="Heading" required>
<label>${getLocalizedText("menu:heading")}</label>
</div>
<div class="form-floating text-body col radius-div">
<input type="number" class="form-control form-control-sm radius" value="5" placeholder="Radius" required>
<label>${getLocalizedText("menu:radius")}</label>
</div>
<button type="button" class="btn btn-secondary col-auto current-coords-btn" data-bs-toggle="tooltip" data-bs-placement="top" title="${getLocalizedText("menu:choose_coords")}"><i class="bi bi-arrow-down-square"></i></button>
</div>
`)
if(!wantsHeading) {
div.find(".heading-div").remove();
}
if(!wantsRadius) {
div.find(".radius-div").remove();
}
div.find(".current-coords-btn").click(async function() {
let data = await chooseCoords();
if(!data) return;
div.find(".coords-x").val(data.coords.x);
div.find(".coords-y").val(data.coords.y);
div.find(".coords-z").val(data.coords.z);
div.find(".heading").val(data.heading);
}).tooltip();
div.find(".delete-coords-btn").click(function() {
div.remove();
});
if(pointData) {
let coords = null;
if(wantsHeading || wantsRadius) {
coords = pointData.coords;
div.find(".heading").val(pointData.heading);
div.find(".radius").val(pointData.radius);
} else {
coords = pointData;
}
div.find(".coords-x").val(coords.x);
div.find(".coords-y").val(coords.y);
div.find(".coords-z").val(coords.z);
}
listDiv.append(div);
}
function setPointToPointsList(listDiv, wantsHeading, wantsRadius, pointsList) {
listDiv.empty();
if(!pointsList) return;
for(const pointData of pointsList) {
addPointToPointsList(listDiv, wantsHeading, wantsRadius, pointData);
}
}
function getPointFromPointsList(listDiv) {
let pointsList = [];
listDiv.find(".coords-div").each(function() {
const coords = {
x: parseFloat( $(this).find(".coords-x").val() ),
y: parseFloat( $(this).find(".coords-y").val() ),
z: parseFloat( $(this).find(".coords-z").val() ),
}
const headingInput = $(this).find(".heading");
const radiusInput = $(this).find(".radius");
if(headingInput.prop("required")) {
const heading = parseFloat( headingInput.val() );
const radius = parseFloat( radiusInput.val() );
pointsList.push({
coords,
heading,
radius
});
} else {
pointsList.push(coords);
}
});
return pointsList;
}
$("#dealership-add-coordinates-btn").click(function() {
const div = $("#auto-dealership-coords-list");
addPointToPointsList(div);
});
$("#player-dealership-current-coords-btn").click(async function() {
let data = await chooseCoords();
if(!data) return;
$("#player-dealership-coords-x").val(data.coords.x);
$("#player-dealership-coords-y").val(data.coords.y);
$("#player-dealership-coords-z").val(data.coords.z);
});
$("#dealership-add-spawnpoint-btn").click(async function() {
const div = $("#dealership-spawn-points-list");
addPointToPointsList(div, true, true);
});
$("#dealership-add-resell-point-btn").click(async function() {
const div = $("#dealership-resell-points-list");
addPointToPointsList(div, false, false);
});
$("#dealership-add-display-point-btn").click(async function() {
const div = $("#player-dealership-display-points-list");
addPointToPointsList(div, true, true);
});
$("#dealership-enter-showroom-current-coords-btn").click(async function() {
let data = await chooseCoords();
if(!data) return;
$("#dealership-enter-showroom-coords-x").val(data.coords.x);
$("#dealership-enter-showroom-coords-y").val(data.coords.y);
$("#dealership-enter-showroom-coords-z").val(data.coords.z);
});
$("#dealership-showroom-current-coords-btn").click(async function() {
let data = await chooseCoords();
if(!data) return;
$("#dealership-showroom-coords-x").val(data.coords.x);
$("#dealership-showroom-coords-y").val(data.coords.y);
$("#dealership-showroom-coords-z").val(data.coords.z);
$("#dealership-showroom-heading").val(data.heading);
});
function toggleAutoDealershipFields(hasToShow) {
$("#dealership-account-name-div").toggle(hasToShow);
$("#dealership-account-name").prop("required", hasToShow);
$("#auto-dealership-coords-div").toggle(hasToShow);
$("#auto-dealership-coords-list").find("input").prop("required", hasToShow);
$("#dealership-restrictions-div").toggle(hasToShow);
$("#dealership-paying-society-div").toggle(hasToShow);
$("#dealership-resell-points-div").toggle(hasToShow);
$("#dealership-is-resell-active").prop("checked");
// options to disable to avoid issues when switching to player dealership
if(!hasToShow) {
$("#dealership-pay-with-society-money").prop("checked", false).change();
$("#dealership-is-resell-active").prop("checked", false).change();
$("#dealership-resell-points-list").empty();
}
}
function togglePlayerOwnedDealershipField(hasToShow) {
$("#player-dealership-coords-div").toggle(hasToShow);
$("#player-dealership-coords-div").find("input").prop("required", hasToShow);
$("#player-dealership-purchase-div").toggle(hasToShow);
$("#player-dealership-purchase-div").find("input").prop("required", hasToShow);
$("#player-dealership-display-div").toggle(hasToShow);
$("#player-dealership-display-div").find("input").prop("required", hasToShow);
$("#player-dealership-enter-showroom-div").toggle(hasToShow);
$("#player-dealership-enter-showroom-div").find("input").prop("required", hasToShow);
}
$("input[name=dealership-type]").change(function() {
const type = $(this).val();
toggleAutoDealershipFields(type == "auto");
togglePlayerOwnedDealershipField(type == "player");
});
function setSharedDealershipData(data) {
const dealershipModal = $("#dealership-modal");
// Generic
dealershipModal.data("blipData", data.blipData);
dealershipModal.data("markerData", data.markerData);
dealershipModal.data("vehiclesData", data.vehiclesData);
$("#dealership-account-name").val(data.accountName);
// Spawn points
setPointToPointsList($("#dealership-spawn-points-list"), true, true, data.spawnPointsList);
// Showroom
$("#dealership-showroom-coords-x").val(data.showroomPoint.coords.x);
$("#dealership-showroom-coords-y").val(data.showroomPoint.coords.y);
$("#dealership-showroom-coords-z").val(data.showroomPoint.coords.z);
$("#dealership-showroom-heading").val(data.showroomPoint.heading);
// Options
dealershipModal.data("societiesData", data.societiesToSendMoneyTo);
$("#dealership-pay-with-society-money").prop("checked", data.payWithSocietyMoney).change();
// Loan data
$("#dealership-loan-is-active").prop("checked", data.loanData.isActive).change();
$("#dealership-loan-percentage").val(data.loanData.percentage).change();
$("#dealership-loan-interval").val(data.loanData.intervalDays);
// Test drive data
$("#dealership-is-test-drive-active").prop("checked", data.testDriveData.isActive).change();
$("#dealership-test-drive-duration").val(data.testDriveData.duration);
$("#dealership-test-drive-change-routing-bucket").prop("checked", data.testDriveData.changeRoutingBucket);
$("#dealership-test-drive-coords-x").val(data.testDriveData.pointData.coords.x);
$("#dealership-test-drive-coords-y").val(data.testDriveData.pointData.coords.y);
$("#dealership-test-drive-coords-z").val(data.testDriveData.pointData.coords.z);
$("#dealership-test-drive-heading").val(data.testDriveData.pointData.heading);
}
function setAutoDealershipData(data) {
const dealershipModal = $("#dealership-modal");
// Coordinates
setPointToPointsList($("#auto-dealership-coords-list"), false, false, data.coordinatesList);
// Restrictions
dealershipModal.data("jobsData", data.jobsData);
setRequiredLicenseForDealership(data.requiredLicense)
// Options
dealershipModal.data("payingSociety", data.payingSociety);
// Resell data
$("#dealership-is-resell-active").prop("checked", data.resellData.isActive).change();
$("#dealership-resell-percentage").val(data.resellData.percentage);
setPointToPointsList($("#dealership-resell-points-list"), false, false, data.resellData.points);
dealershipModal.data("resellPointMarkerData", data.resellData.markerData);
}
function setPlayerDealershipData(data) {
// Generic
$("#player-dealership-price").val(data.price);
$("#player-dealership-resell-percentage").val(data.resellPercentage);
// Coordinates
$("#player-dealership-coords-x").val(data.coordinates.x);
$("#player-dealership-coords-y").val(data.coordinates.y);
$("#player-dealership-coords-z").val(data.coordinates.z);
// Display points
setPointToPointsList($("#player-dealership-display-points-list"), true, true, data.displayPointsList);
// Enter showroom coords
$("#dealership-enter-showroom-coords-x").val(data.enterShowroomCoords.x);
$("#dealership-enter-showroom-coords-y").val(data.enterShowroomCoords.y);
$("#dealership-enter-showroom-coords-z").val(data.enterShowroomCoords.z);
}
function editDealership(id) {
const dealershipModal = $("#dealership-modal");
const dealershipInfo = dealerships[id];
dealershipModal.data("dealershipId", id);
dealershipModal.data("action", "edit");
$("#delete-dealership-btn").show();
$("#save-dealership-btn").text(getLocalizedText("menu:confirm"));
const data = dealershipInfo.data;
// Generic
$("#dealership-label").val(dealershipInfo.label);
setSharedDealershipData(data);
if(dealershipInfo.type == "auto") {
setAutoDealershipData(data);
} else {
setPlayerDealershipData(data);
}
// As last input, so all elements are already added to the DOM
$(`input[name=dealership-type][value=${dealershipInfo.type}]`).prop("checked", true).change();
dealershipModal.modal("show");
}
function getSharedDealershipData() {
const dealershipModal = $("#dealership-modal");
return {
// Generic
blipData: dealershipModal.data("blipData"),
markerData: dealershipModal.data("markerData"),
vehiclesData: dealershipModal.data("vehiclesData"),
accountName: $("#dealership-account-name").val(),
// Spawn points
spawnPointsList: getPointFromPointsList( $("#dealership-spawn-points-list") ),
// Showroom
showroomPoint: {
coords: {
x: parseFloat( $("#dealership-showroom-coords-x").val() ),
y: parseFloat( $("#dealership-showroom-coords-y").val() ),
z: parseFloat( $("#dealership-showroom-coords-z").val() ),
},
heading: parseFloat( $("#dealership-showroom-heading").val() ),
},
// Options
societiesToSendMoneyTo: dealershipModal.data("societiesData"),
payWithSocietyMoney: $("#dealership-pay-with-society-money").prop("checked"),
loanData: {
isActive: $("#dealership-loan-is-active").prop("checked"),
percentage: parseInt( $("#dealership-loan-percentage").val() ),
intervalDays: parseInt( $("#dealership-loan-interval").val() )
},
testDriveData: {
isActive: $("#dealership-is-test-drive-active").prop("checked"),
duration: parseInt( $("#dealership-test-drive-duration").val() ),
changeRoutingBucket: $("#dealership-test-drive-change-routing-bucket").prop("checked"),
pointData: {
coords: {
x: parseFloat( $("#dealership-test-drive-coords-x").val() ),
y: parseFloat( $("#dealership-test-drive-coords-y").val() ),
z: parseFloat( $("#dealership-test-drive-coords-z").val() ),
},
heading: parseFloat( $("#dealership-test-drive-heading").val() ),
}
}
}
}
function getAutoDealershipData() {
const dealershipModal = $("#dealership-modal");
const sharedData = getSharedDealershipData();
const data = {
// Coordinates
coordinatesList: getPointFromPointsList( $("#auto-dealership-coords-list") ),
// Restrictions
jobsData: dealershipModal.data("jobsData"),
requiredLicense: $("#dealership-choose-required-license-btn").data("licenseType"),
// Options
payingSociety: dealershipModal.data("payingSociety"),
resellData: {
isActive: $("#dealership-is-resell-active").prop("checked"),
percentage: parseInt( $("#dealership-resell-percentage").val() ),
points: getPointFromPointsList( $("#dealership-resell-points-list") ),
markerData: dealershipModal.data("resellPointMarkerData")
},
}
return {...sharedData, ...data}
}
function getPlayerDealershipData() {
const sharedData = getSharedDealershipData();
const data = {
// Generic
price: parseInt( $("#player-dealership-price").val() ),
resellPercentage: parseInt( $("#player-dealership-resell-percentage").val() ),
// Coordinates
coordinates: {
x: parseFloat( $("#player-dealership-coords-x").val() ),
y: parseFloat( $("#player-dealership-coords-y").val() ),
z: parseFloat( $("#player-dealership-coords-z").val() ),
},
// Display points
displayPointsList: getPointFromPointsList( $("#player-dealership-display-points-list") ),
// Enter showroom coords
enterShowroomCoords: {
x: parseFloat( $("#dealership-enter-showroom-coords-x").val() ),
y: parseFloat( $("#dealership-enter-showroom-coords-y").val() ),
z: parseFloat( $("#dealership-enter-showroom-coords-z").val() ),
}
}
return {...sharedData, ...data}
}
$("#dealership-form").submit(async function(event) {
if(isThereAnyErrorInForm(event)) return;
let dealershipModal = $("#dealership-modal");
let action = dealershipModal.data("action");
const dealershipType = $("input[name=dealership-type]:checked").val();
let dealershipInfo = {
label: $("#dealership-label").val(),
type: dealershipType,
data: dealershipType == "auto" ? getAutoDealershipData() : getPlayerDealershipData()
}
let success = null;
switch(action) {
case "create": {
success = await $.post(`https://${resName}/createDealership`, JSON.stringify(dealershipInfo));
break;
}
case "edit": {
success = await $.post(`https://${resName}/updateDealership`, JSON.stringify({dealershipId: dealershipModal.data("dealershipId"), dealershipInfo: dealershipInfo}));
break;
}
}
if(!success) return;
dealershipModal.modal("hide");
loadDealerships();
})
$("#delete-dealership-btn").click(async function() {
let dealershipModal = $("#dealership-modal");
let dealershipId = dealershipModal.data("dealershipId");
const success = await $.post(`https://${resName}/deleteDealership`, JSON.stringify({dealershipId: dealershipId}));
if(!success) return;
dealershipModal.modal("hide");
loadDealerships();
});
$("#import-dealership-btn").click(async function() {
const dealershipModal = $("#dealership-modal");
const dealershipId = dealershipModal.data("dealershipId");
const importedData = await dealershipsDialog();
const oldAction = dealershipModal.data("action"); // To remember if it's an edit or create
dealerships[dealershipId] = importedData;
editDealership(dealershipId);
dealershipModal.data("action", oldAction);
})
$(document).keyup(function(e) {
if (e.key === "Escape") {
exitShowroom();
closeMenu();
}
});
/*
*/
async function takeVehicleImage(spawnName) {
$('html').hide();
await $.post(`https://${resName}/takeVehicleImage`, JSON.stringify({spawnName}));
$('html').show();
}
async function deleteVehicle(spawnName) {
if(!await confirmDeletion()) return;
const response = await $.post(`https://${resName}/deleteVehicle`, JSON.stringify({spawnName}));
showServerResponse(response);
if(response === true) {
loadVehicles();
}
}
let vehiclesDatatable = $("#vehicles-container").DataTable( {
"lengthMenu": [15, 30, 50],
"order": [
[ $('th[data-translation-id="menu:valid"]').index(), 'desc' ],
[ $('th[data-translation-id="menu:spawn_name"]').index(), 'asc' ]
],
"columnDefs": [
{
"targets": -1, // Last column
"data": null,
"className": "col-1",
"defaultContent": `
<div class="d-inline-flex gap-3">
<button class='btn btn-danger py-0 px-2 delete-vehicle-btn' data-bs-toggle="tooltip" data-bs-placement="top" title="Delete"><i class=\"bi bi-trash\"></i></button>
<button class='btn btn-info py-0 px-2 take-image-btn' data-bs-toggle="tooltip" data-bs-placement="top" title="Take image"><i class=\"bi bi-image\"></i></button>
</div>
`
},
{
"targets": -3, // 'type' column
"className": "col-1",
}
],
"createdRow": function (row, data, index) {
$('td', row).css('white-space', 'nowrap').addClass("py-3");
let vehicleData = data[data.length - 1];
$(row).find(".delete-vehicle-btn").click(function() {
deleteVehicle(vehicleData.spawnName);
}).tooltip();
$(row).find(".take-image-btn").click(function() {
takeVehicleImage(vehicleData.spawnName);
}).tooltip();
}
});
let vehicles = {};
async function loadVehicles() {
const rawVehicles = await $.post(`https://${resName}/getAllVehicles`);
// Manually create the table to avoid incompatibilities due table indexing
vehicles = {};
for(const[k, vehicleData] of Object.entries(rawVehicles)) {
vehicles[vehicleData.spawnName] = vehicleData;
}
vehiclesDatatable.clear();
for(const[id, vehicleData] of Object.entries(vehicles)) {
const spawnName = vehicleData.isValid
? vehicleData.spawnName
: `<span class="text-danger fw-bold">${vehicleData.spawnName}</span>`;
vehiclesDatatable.row.add([
spawnName ?? "???",
vehicleData.label ?? "???",
vehicleData.class ?? "???",
vehicleData.type ?? "???",
vehicleData.isValid ? "✅" : "❌",
vehicleData
]);
}
vehiclesDatatable.draw();
}
async function setDefaultDataOfVehicle() {
$("#create-vehicle-spawn-name").val("");
$("#create-vehicle-label").val("");
$("#create-vehicle-class").val("sport");
$("input[name=create-vehicle-type][value=car]").prop("checked", true).change();
// Remove all things in select #create-vehicle-class
$("#create-vehicle-class").empty();
const classes = await $.post(`https://${resName}/getAllClasses`);
for(const [k, classData] of Object.entries(classes)) {
$("#create-vehicle-class").append(`<option value="${classData.id}">${classData.label}</option>`);
}
}
$("#new-vehicle-btn").click(function() {
let vehicleModal = $("#vehicle-modal");
setDefaultDataOfVehicle();
vehicleModal.modal("show");
});
async function isVehicleValid(spawnName) {
return await $.post(`https://${resName}/isVehicleValid`, JSON.stringify({spawnName}));
}
$("#vehicle-form").submit(async function(event) {
if(isThereAnyErrorInForm(event)) return;
let vehicleModal = $("#vehicle-modal");
const vehicleInfo = {
spawnName: $("#create-vehicle-spawn-name").val(),
label: $("#create-vehicle-label").val(),
class: $("#create-vehicle-class").val(),
type: $("input[name=create-vehicle-type]:checked").val(),
}
if(!await isVehicleValid(vehicleInfo.spawnName)) {
swal("ERROR", `Spawn name not valid!`, "error");
return;
}
let submitButton = event.originalEvent.submitter;
let submitButtonName = submitButton.name;
const response = await $.post(`https://${resName}/createVehicle`, JSON.stringify(vehicleInfo));
showServerResponse(response);
if(response !== true) return;
if (submitButtonName == "create-vehicle-with-image-btn") {
takeVehicleImage(vehicleInfo.spawnName);
}
vehicleModal.modal("hide");
loadVehicles();
})
$("#all-vehicles-picture-btn").click(async function() {
if(!await confirmDeletion()) return;
closeMenu();
$.post(`https://${resName}/takeAllVehiclesImages`);
})
/*
*/
let classesDatatable = $("#classes-container").DataTable( {
"lengthMenu": [15, 30, 50],
"createdRow": function (row, data, index) {
$('td', row).css('white-space', 'nowrap').addClass("py-3");
$(row).addClass("clickable");
let classData = data[data.length - 1];
$(row).click(function() {
editClass(classData.id);
});
}
});
let classes = {};
async function loadClasses() {
const rawClasses = await $.post(`https://${resName}/getAllClasses`);
// Manually create the table to avoid incompatibilities due table indexing
classes = {};
for(const[k, classData] of Object.entries(rawClasses)) {
classes[classData.id] = classData;
}
classesDatatable.clear();
for(const[id, classData] of Object.entries(classes)) {
classesDatatable.row.add([
classData.id,
classData.label,
classData
]);
}
classesDatatable.draw();
}
function setClassConfig(config={}){
$("#create-class-id").val(config.id);
$("#create-class-label").val(config.label);
$("#create-class-id").prop("disabled", config.id ? true : false);
}
$("#new-class-btn").click(function() {
let classModal = $("#class-modal");
// Converts from edit modal to create modal
classModal.data("action", "create");
$("#delete-class-btn").hide();
$("#save-class-btn").text( getLocalizedText("menu:create") );
setClassConfig();
classModal.modal("show");
});
$("#class-form").submit(async function(event) {
if(isThereAnyErrorInForm(event)) return;
let classModal = $("#class-modal");
const classInfo = {
id: $("#create-class-id").val(),
label: $("#create-class-label").val(),
}
let action = classModal.data("action");
let response = null;
switch(action) {
case "create": {
response = await $.post(`https://${resName}/createClass`, JSON.stringify(classInfo));
break;
}
case "edit": {
response = await $.post(`https://${resName}/updateClass`, JSON.stringify({classId: classInfo.id, classInfo}));
break;
}
}
showServerResponse(response);
if(response !== true) return;
classModal.modal("hide");
loadClasses();
})
function editClass(classId) {
const classModal = $("#class-modal");
const classInfo = classes[classId];
classModal.data("classId", classId);
classModal.data("action", "edit");
$("#delete-class-btn").show();
$("#save-class-btn").text(getLocalizedText("menu:confirm"));
setClassConfig(classInfo);
classModal.modal("show");
}
$("#delete-class-btn").click(async function() {
if(!await confirmDeletion()) return;
let classModal = $("#class-modal");
let classId = classModal.data("classId");
const response = await $.post(`https://${resName}/deleteClass`, JSON.stringify({classId}));
showServerResponse(response);
if(response !== true) return;
classModal.modal("hide");
loadClasses();
});