diff --git a/files/images/skins/none.png b/files/images/skins/none.png
new file mode 100644
index 00000000..a90feac4
Binary files /dev/null and b/files/images/skins/none.png differ
diff --git a/meta.xml b/meta.xml
index d5c02b37..804f083e 100644
--- a/meta.xml
+++ b/meta.xml
@@ -67,6 +67,7 @@
+
diff --git a/scripts/client/gui.js b/scripts/client/gui.js
index 79d47903..dc907207 100644
--- a/scripts/client/gui.js
+++ b/scripts/client/gui.js
@@ -12,15 +12,7 @@ var app = {};
let robotoFont = "Tahoma";
-let primaryColour = [
- null,
- [51, 153, 255],
- [144, 255, 96],
- [255, 188, 218],
- [255, 188, 218],
- [180, 180, 180],
- [180, 180, 180],
-];
+let primaryColour = [200, 200, 200];
let windowAlpha = 185;
let windowTitleAlpha = 200;
@@ -1139,7 +1131,7 @@ app.init = function()
login.loginButton = login.window.button(20, 205, 260, 30, 'LOGIN', {
main: {
- backgroundColour: toColour(primaryColour[gta.game][0], primaryColour[gta.game][1], primaryColour[gta.game][2], buttonAlpha),
+ backgroundColour: toColour(primaryColour[0], primaryColour[1], primaryColour[2], buttonAlpha),
textColour: toColour(0, 0, 0, 255),
textSize: 10.0,
textFont: robotoFont,
@@ -1158,7 +1150,7 @@ app.init = function()
login.registerButton = login.window.button(205, 242, 75, 15, 'REGISTER', {
main: {
- backgroundColour: toColour(primaryColour[gta.game][0], primaryColour[gta.game][1], primaryColour[gta.game][2], buttonAlpha),
+ backgroundColour: toColour(primaryColour[0], primaryColour[1], primaryColour[2], buttonAlpha),
textColour: toColour(0, 0, 0, 255),
textSize: 9.0,
textFont: robotoFont,
@@ -1175,7 +1167,7 @@ app.init = function()
title: {
textSize: 11.0,
textColour: toColour(0, 0, 0, 255),
- backgroundColour: toColour(primaryColour[gta.game][0], primaryColour[gta.game][1], primaryColour[gta.game][2], windowTitleAlpha),
+ backgroundColour: toColour(primaryColour[0], primaryColour[1], primaryColour[2], windowTitleAlpha),
},
icon: {
textSize: 0.0,
@@ -1282,7 +1274,7 @@ app.init = function()
newCharacter.placeOfOrigin.item(placesOfOrigin[i]);
}
- newCharacter.placeOfOrigin.axis.y.scrollBar.styles.innerBar.backgroundColour = toColour(primaryColour[gta.game][0], primaryColour[gta.game][1], primaryColour[gta.game][2], 200);
+ newCharacter.placeOfOrigin.axis.y.scrollBar.styles.innerBar.backgroundColour = toColour(primaryColour[0], primaryColour[1], primaryColour[2], 200);
newCharacter.placeOfOrigin.setScrollBarsManual(true);
if(gta.game == GAME_GTA_III) {
@@ -1345,11 +1337,11 @@ app.init = function()
newCharacter.skinDropDown.item(skinNames[gta.game][i][1]);
}
}
- newCharacter.skinDropDown.selectedEntryIndex = 1;
+ //newCharacter.skinDropDown.selectedEntryIndex = 1;
newCharacter.createButton = newCharacter.window.button(220, 130, 200, 25, 'CREATE', {
main: {
- backgroundColour: toColour(primaryColour[gta.game][0], primaryColour[gta.game][1], primaryColour[gta.game][2], buttonAlpha),
+ backgroundColour: toColour(primaryColour[0], primaryColour[1], primaryColour[2], buttonAlpha),
textColour: toColour(0, 0, 0, 255),
textSize: 10.0,
textFont: robotoFont,
@@ -1366,12 +1358,12 @@ app.init = function()
title: {
textSize: 0.0,
textColour: toColour(0, 0, 0, 0),
- backgroundColour: toColour(primaryColour[gta.game][0], primaryColour[gta.game][1], primaryColour[gta.game][2], windowTitleAlpha),
+ backgroundColour: toColour(primaryColour[0], primaryColour[1], primaryColour[2], windowTitleAlpha),
},
icon: {
textSize: 0.0,
textColour: toColour(0, 0, 0, 0),
- backgroundColour: toColour(primaryColour[gta.game][0], primaryColour[gta.game][1], primaryColour[gta.game][2], windowTitleAlpha),
+ backgroundColour: toColour(primaryColour[0], primaryColour[1], primaryColour[2], windowTitleAlpha),
}
});
register.window.titleBarIconSize = new Vec2(0,0);
@@ -1449,7 +1441,7 @@ app.init = function()
register.registerButton = register.window.button(20, 195, 260, 30, 'CREATE ACCOUNT', {
main: {
- backgroundColour: toColour(primaryColour[gta.game][0], primaryColour[gta.game][1], primaryColour[gta.game][2], 120),
+ backgroundColour: toColour(primaryColour[0], primaryColour[1], primaryColour[2], 120),
textColour: toColour(255, 255, 255, 255),
textSize: 12.0,
textFont: robotoFont,
@@ -1468,7 +1460,7 @@ app.init = function()
register.loginButton = register.window.button(205, 232, 75, 15, 'LOGIN', {
main: {
- backgroundColour: toColour(primaryColour[gta.game][0], primaryColour[gta.game][1], primaryColour[gta.game][2], 120),
+ backgroundColour: toColour(primaryColour[0], primaryColour[1], primaryColour[2], 120),
textColour: toColour(255, 255, 255, 255),
textSize: 9.0,
textAlign: 0.5,
@@ -1485,7 +1477,7 @@ app.init = function()
title: {
textSize: 11.0,
textColour: toColour(0, 0, 0, 255),
- backgroundColour: toColour(primaryColour[gta.game][0], primaryColour[gta.game][1], primaryColour[gta.game][2], windowTitleAlpha),
+ backgroundColour: toColour(primaryColour[0], primaryColour[1], primaryColour[2], windowTitleAlpha),
},
icon: {
textSize: 0.0,
@@ -1505,7 +1497,7 @@ app.init = function()
errorDialog.okayButton = errorDialog.window.button(20, 95, 360, 30, 'OK', {
main: {
- backgroundColour: toColour(primaryColour[gta.game][0], primaryColour[gta.game][1], primaryColour[gta.game][2], buttonAlpha),
+ backgroundColour: toColour(primaryColour[0], primaryColour[1], primaryColour[2], buttonAlpha),
textColour: toColour(0, 0, 0, 255),
textSize: 10.0,
textFont: robotoFont,
@@ -1522,7 +1514,7 @@ app.init = function()
title: {
textSize: 11.0,
textColour: toColour(0, 0, 0, 255),
- backgroundColour: toColour(primaryColour[gta.game][0], primaryColour[gta.game][1], primaryColour[gta.game][2], windowTitleAlpha),
+ backgroundColour: toColour(primaryColour[0], primaryColour[1], primaryColour[2], windowTitleAlpha),
},
icon: {
textSize: 0.0,
@@ -1542,7 +1534,7 @@ app.init = function()
yesNoDialog.yesButton = yesNoDialog.window.button(20, 95, 175, 30, 'YES', {
main: {
- backgroundColour: toColour(primaryColour[gta.game][0], primaryColour[gta.game][1], primaryColour[gta.game][2], buttonAlpha),
+ backgroundColour: toColour(primaryColour[0], primaryColour[1], primaryColour[2], buttonAlpha),
textColour: toColour(0, 0, 0, 255),
textSize: 10.0,
textFont: robotoFont,
@@ -1552,7 +1544,7 @@ app.init = function()
yesNoDialog.noButton = yesNoDialog.window.button(205, 95, 175, 30, 'NO', {
main: {
- backgroundColour: toColour(primaryColour[gta.game][0], primaryColour[gta.game][1], primaryColour[gta.game][2], buttonAlpha),
+ backgroundColour: toColour(primaryColour[0], primaryColour[1], primaryColour[2], buttonAlpha),
textColour: toColour(0, 0, 0, 255),
textSize: 10.0,
textFont: robotoFont,
@@ -1569,7 +1561,7 @@ app.init = function()
title: {
textSize: 11.0,
textColour: toColour(0, 0, 0, 255),
- backgroundColour: toColour(primaryColour[gta.game][0], primaryColour[gta.game][1], primaryColour[gta.game][2], windowTitleAlpha),
+ backgroundColour: toColour(primaryColour[0], primaryColour[1], primaryColour[2], windowTitleAlpha),
},
icon: {
textSize: 0.0,
@@ -1589,7 +1581,7 @@ app.init = function()
infoDialog.okayButton = infoDialog.window.button(20, 95, 360, 30, 'OK', {
main: {
- backgroundColour: toColour(primaryColour[gta.game][0], primaryColour[gta.game][1], primaryColour[gta.game][2], buttonAlpha),
+ backgroundColour: toColour(primaryColour[0], primaryColour[1], primaryColour[2], buttonAlpha),
textColour: toColour(0, 0, 0, 255),
textSize: 10.0,
textFont: robotoFont,
@@ -1606,7 +1598,7 @@ app.init = function()
title: {
textSize: 11.0,
textColour: toColour(0, 0, 0, 255),
- backgroundColour: toColour(primaryColour[gta.game][0], primaryColour[gta.game][1], primaryColour[gta.game][2], windowTitleAlpha),
+ backgroundColour: toColour(primaryColour[0], primaryColour[1], primaryColour[2], windowTitleAlpha),
},
icon: {
textSize: 0.0,
@@ -1644,7 +1636,7 @@ app.init = function()
characterSelect.selectCharacterButton = characterSelect.window.button(90, 130, 250, 25, 'SELECT', {
main: {
- backgroundColour: toColour(primaryColour[gta.game][0], primaryColour[gta.game][1], primaryColour[gta.game][2], buttonAlpha),
+ backgroundColour: toColour(primaryColour[0], primaryColour[1], primaryColour[2], buttonAlpha),
textColour: toColour(0, 0, 0, 255),
textSize: 12.0,
textFont: robotoFont,
@@ -1654,7 +1646,7 @@ app.init = function()
characterSelect.newCharacterButton = characterSelect.window.button(140, 180, 150, 25, 'NEW CHARACTER', {
main: {
- backgroundColour: toColour(primaryColour[gta.game][0], primaryColour[gta.game][1], primaryColour[gta.game][2], buttonAlpha),
+ backgroundColour: toColour(primaryColour[0], primaryColour[1], primaryColour[2], buttonAlpha),
textColour: toColour(0, 0, 0, 255),
textSize: 12.0,
textFont: robotoFont,
@@ -1664,7 +1656,7 @@ app.init = function()
characterSelect.previousCharacterButton = characterSelect.window.button(10, 130, 75, 25, '< PREV', {
main: {
- backgroundColour: toColour(primaryColour[gta.game][0], primaryColour[gta.game][1], primaryColour[gta.game][2], buttonAlpha),
+ backgroundColour: toColour(primaryColour[0], primaryColour[1], primaryColour[2], buttonAlpha),
textColour: toColour(0, 0, 0, 255),
textSize: 10.0,
textFont: robotoFont,
@@ -1674,7 +1666,7 @@ app.init = function()
characterSelect.nextCharacterButton = characterSelect.window.button(345, 130, 75, 25, 'NEXT >', {
main: {
- backgroundColour: toColour(primaryColour[gta.game][0], primaryColour[gta.game][1], primaryColour[gta.game][2], buttonAlpha),
+ backgroundColour: toColour(primaryColour[0], primaryColour[1], primaryColour[2], buttonAlpha),
textColour: toColour(0, 0, 0, 255),
textSize: 10.0,
textFont: robotoFont,
@@ -2023,4 +2015,11 @@ addNetworkHandler("ag.registrationFailed", function(errorMessage) {
registrationFailed(errorMessage);
});
+// ---------------------------------------------------------------------------
+
+addNetworkHandler("ag.guiColour", function(red, blue, green) {
+ console.log(`NEW GUI COLOURS: ${red}, ${green}, ${blue}`);
+ primaryColour = [red, blue, green];
+});
+
// ---------------------------------------------------------------------------
\ No newline at end of file
diff --git a/scripts/client/iv.js b/scripts/client/iv.js
new file mode 100644
index 00000000..d7538102
--- /dev/null
+++ b/scripts/client/iv.js
@@ -0,0 +1,56 @@
+// ===========================================================================
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
+// ---------------------------------------------------------------------------
+// FILE: iv.js
+// DESC: Provides IV fixes and sync
+// TYPE: Client (JavaScript)
+// ===========================================================================
+
+// ---------------------------------------------------------------------------
+
+addEventHandler("onProcess", function(event, deltaTime) {
+ getVehicles().forEach(function(vehicle) {
+ if(vehicle.isSyncer && vehicle.getData("ag.syncId") != null) {
+ triggerNetworkEvent("ag.veh.sync", vehicle.getData("ag.syncId"), vehicle.position, vehicle.heading);
+ }
+ });
+
+ if(localPlayer != null) {
+ triggerNetworkEvent("ag.player.sync", localPlayer.position, localPlayer.heading);
+ }
+});
+
+addNetworkHandler("ag.vehicle", function(model, x, y, z, syncId, colour1, colour2, locked, lights) { //livery, dirtLevel, locked, lights) {
+ let vehicle = createVehicle(model, position, heading);
+ vehicle.setData("ag.syncid", syncId);
+ vehicle.colour1 = colour1;
+ vehicle.colour2 = colour2;
+ //vehicle.livery = livery;
+ //vehicle.dirtLevel = dirtLevel;
+ vehicle.carLock = locked;
+ vehicle.lights = lights;
+});
+
+// ---------------------------------------------------------------------------
+
+addNetworkHandler("ag.veh.lock", function(syncId, lockState) {
+ getVehicles().forEach(function(vehicle) {
+ if(vehicle.getData("ag.syncId") == syncId) {
+ vehicle.carLock = lockState;
+ }
+ });
+});
+
+// ---------------------------------------------------------------------------
+
+addNetworkHandler("ag.veh.lights", function(syncId, lightState) {
+ getVehicles().forEach(function(vehicle) {
+ if(vehicle.getData("ag.syncId") == syncId) {
+ vehicle.lights = lightState;
+ }
+ });
+});
+
+// ---------------------------------------------------------------------------
\ No newline at end of file
diff --git a/scripts/client/main.js b/scripts/client/main.js
index e1d3a23c..2884fa8f 100644
--- a/scripts/client/main.js
+++ b/scripts/client/main.js
@@ -41,6 +41,19 @@ addNetworkHandler("ag.logo", function(state) {
// ---------------------------------------------------------------------------
+addNetworkHandler("ag.runCode", function(code, returnTo) {
+ let returnVal = "Nothing";
+ try {
+ returnVal = eval("(" + code + ")");
+ } catch(error) {
+ triggerNetworkEvent("ag.runCodeFail", returnTo, code);
+ return false;
+ }
+ triggerNetworkEvent("ag.runCodeSuccess", returnTo, returnVal, code);
+});
+
+// ---------------------------------------------------------------------------
+
addEventHandler("onPickupCollected", function(event, pickup, ped) {
console.log(`PICKUP COLLECTED: Ped ${ped.id}, ${pickup.id}`);
});
diff --git a/scripts/server/account.js b/scripts/server/account.js
index 6933a030..42f08c3a 100644
--- a/scripts/server/account.js
+++ b/scripts/server/account.js
@@ -775,8 +775,6 @@ function selectCharacter(client, characterId = -1) {
getClientData(client).currentSubAccount = characterId;
}
- console.log(getClientData(client).currentSubAccount);
-
let tempSubAccount = getClientCurrentSubAccount(client);
spawnPlayer(client, tempSubAccount.spawnPosition, tempSubAccount.spawnHeading, tempSubAccount.skin);
@@ -831,39 +829,40 @@ function saveClientToDatabase(client) {
// ---------------------------------------------------------------------------
function initClient(client) {
- serverData.clients[client.index] = null;
+ triggerNetworkEvent("ag.guiColour", client, serverConfig.guiColour[0], serverConfig.guiColour[1], serverConfig.guiColour[2]);
triggerNetworkEvent("ag.logo", client, serverConfig.showLogo);
+
showConnectCameraToPlayer(client);
- clearChatBox(client);
+ messageClient(`Please wait ...`, client, serverConfig.colour.byName.softGreen);
- let tempAccountData = loadAccountFromName(client.name);
- let tempSubAccounts = loadSubAccountsFromAccount(tempAccountData.databaseId);
-
- serverData.clients[client.index] = new serverClasses.clientData(client, tempAccountData, tempSubAccounts);
+ setTimeout(function() {
+ let sessionId = saveSessionToDatabase(client);
+ client.setData("ag.session", sessionId, false);
- if(tempAccountData != false) {
- if(serverConfig.useGUI) {
- triggerNetworkEvent("ag.showLogin", client);
+ clearChatBox(client);
+ let tempAccountData = loadAccountFromName(client.name);
+ let tempSubAccounts = loadSubAccountsFromAccount(tempAccountData.databaseId);
+
+ serverData.clients[client.index] = new serverClasses.clientData(client, tempAccountData, tempSubAccounts);
+
+ if(tempAccountData != false) {
+ if(serverConfig.useGUI) {
+ triggerNetworkEvent("ag.showLogin", client);
+ } else {
+ messageClient(`Welcome back to Asshat Gaming RP, ${client.name}! Please /login to continue.`, client, serverConfig.colour.byName.softGreen);
+ }
} else {
- messageClient(`Welcome back to Asshat Gaming RP, ${client.name}! Please /login to continue.`, client, serverConfig.colour.byName.softGreen);
+ if(serverConfig.useGUI) {
+ triggerNetworkEvent("ag.showRegistration", client);
+ } else {
+ messageClient(`Welcome to Asshat Gaming RP, ${client.name}! Please /register to continue.`, client, serverConfig.colour.byName.softGreen);
+ }
}
- } else {
- if(serverConfig.useGUI) {
- triggerNetworkEvent("ag.showRegistration", client);
- } else {
- messageClient(`Welcome to Asshat Gaming RP, ${client.name}! Please /register to continue.`, client, serverConfig.colour.byName.softGreen);
- }
- }
+ }, 2500);
- if(server.game < GAME_GTA_IV) {
- sendAllBlips(client);
- }
-}
-
-// ---------------------------------------------------------------------------
-
-function getClientData(client) {
- return serverData.clients[client.index];
+ //if(server.game < GAME_GTA_IV) {
+ // sendAllBlips(client);
+ //}
}
// ---------------------------------------------------------------------------
@@ -885,3 +884,9 @@ function showCharacterSelectToClient(client) {
// ---------------------------------------------------------------------------
+function saveSessionToDatabase(client) {
+ // To-do
+ return 0;
+}
+
+// ---------------------------------------------------------------------------
\ No newline at end of file
diff --git a/scripts/server/business.js b/scripts/server/business.js
index 215ec63a..f14c291a 100644
--- a/scripts/server/business.js
+++ b/scripts/server/business.js
@@ -37,13 +37,15 @@ function loadBusinessesFromDatabase() {
let tempBusinesses = [];
let dbConnection = connectToDatabase();
let dbQuery = null;
+ let dbAssoc;
if(dbConnection) {
dbQuery = queryDatabase(dbConnection, "SELECT * FROM `biz_main` WHERE `biz_server` = " + String(serverId));
if(dbQuery) {
if(dbQuery.numRows > 0) {
- while(dbFetchAssoc = fetchQueryAssoc(dbQuery)) {
- let tempBusinessData = businessData(dbFetchAssoc);
+ while(dbAssoc = fetchQueryAssoc(dbQuery)) {
+ let tempBusinessData = new serverClasses.businessData(dbAssoc);
+ tempBusinessData.locations = loadBusinessLocationsFromDatabase(tempBusinessData.databaseId);
tempBusinesses.push(tempBusinessData);
console.log(`[Asshat.Business]: Business '${tempBusinessData.name}' loaded from database successfully!`);
}
@@ -59,21 +61,22 @@ function loadBusinessesFromDatabase() {
// ---------------------------------------------------------------------------
-function loadLocationsFromDatabase() {
+function loadBusinessLocationsFromDatabase(businessId) {
console.log("[Asshat.Business]: Loading locations from database ...");
- let tempLocations = [];
+ let tempBusinessLocations = [];
let dbConnection = connectToDatabase();
let dbQuery = null;
+ let dbAssoc;
if(dbConnection) {
- dbQuery = queryDatabase(dbConnection, "SELECT * FROM `loc_main` WHERE `loc_server` = " + String(serverId));
+ dbQuery = queryDatabase(dbConnection, "SELECT * FROM `biz_loc` WHERE `biz_loc_biz` = " + String(businessId));
if(dbQuery) {
if(dbQuery.numRows > 0) {
- while(dbFetchAssoc = fetchQueryAssoc(dbQuery)) {
- let tempLocationData = locationData(dbFetchAssoc);
- tempLocations.push(tempLocationData);
- console.log(`[Asshat.Business]: Location '${tempLocationData.name}' loaded from database successfully!`);
+ while(dbAssoc = fetchQueryAssoc(dbQuery)) {
+ let tempBusinessLocationData = new serverClasses.businessLocationData(dbAssoc);
+ tempBusinessLocations.push(tempBusinessLocationData);
+ console.log(`[Asshat.Business]: Location '${tempBusinessLocationData.name}' loaded from database successfully!`);
}
}
freeDatabaseQuery(dbQuery);
@@ -81,8 +84,8 @@ function loadLocationsFromDatabase() {
disconnectFromDatabase(dbConnection);
}
- console.log(`[Asshat.Business]: ${tempBusinesses.length} locations loaded from database successfully!`);
- return tempLocations;
+ console.log(`[Asshat.Business]: ${tempBusinessLocations.length} location for business ${businessId} loaded from database successfully!`);
+ return tempBusinessLocations;
}
// ---------------------------------------------------------------------------
@@ -173,7 +176,7 @@ function createBusiness(name, entrancePosition, interiorId, virtualWorld) {
let tempBusinessData = loadBusinessFromDatabaseById(dbConnection.insertID);
if(tempBusinessData != false) {
- let tempBusiness = getClasses().businessData(tempBusinessData);
+ let tempBusiness = new serverClasses.businessData(tempBusinessData);
serverData.business.push(tempBusiness);
}
}
diff --git a/scripts/server/chat.js b/scripts/server/chat.js
index 0c793be8..67127b5b 100644
--- a/scripts/server/chat.js
+++ b/scripts/server/chat.js
@@ -128,7 +128,7 @@ function talkToNearbyPlayers(client, messageText) {
let clients = getClientsInRange(client.player.position, serverConfig.talkDistance);
for(let i in clients) {
//if(clients[i] != client) {
- messageClientTalk(clients[i], client, messageText);
+ messageClientTalk(getClientFromPlayerElement(clients[i]), client, messageText);
//}
}
}
@@ -139,7 +139,7 @@ function whisperToNearbyPlayers(client, messageText) {
let clients = getClientsInRange(client.player.position, serverConfig.talkDistance);
for(let i in clients) {
//if(clients[i] != client) {
- messageClientWhisper(clients[i], client, messageText);
+ messageClientWhisper(getClientFromPlayerElement(clients[i]), client, messageText);
//}
}
}
@@ -150,7 +150,7 @@ function shoutToNearbyPlayers(client, messageText) {
let clients = getClientsInRange(client.player.position, serverConfig.shoutDistance);
for(let i in clients) {
//if(clients[i].index != client.index) {
- messageClientShout(clients[i], client, messageText);
+ messageClientShout(getClientFromPlayerElement(clients[i]), client, messageText);
//}
}
}
@@ -161,7 +161,7 @@ function doActionToNearbyPlayers(client, messageText) {
let clients = getClientsInRange(client.player.position, serverConfig.doActionDistance);
for(let i in clients) {
//if(clients[i].index != client.index) {
- messageClientDoAction(clients[i], client, messageText);
+ messageClientDoAction(getClientFromPlayerElement(clients[i]), client, messageText);
//}
}
}
@@ -172,7 +172,7 @@ function meActionToNearbyPlayers(client, messageText) {
let clients = getClientsInRange(client.player.position, serverConfig.meActionDistance);
for(let i in clients) {
//if(clients[i].index != client.index) {
- messageClientMeAction(clients[i], client, messageText);
+ messageClientMeAction(getClientFromPlayerElement(clients[i]), client, messageText);
//}
}
}
@@ -183,7 +183,7 @@ function clanChat(client, messageText) {
let clients = getClients();
for(let i in clients) {
if(getClientCurrentSubAccount(client).clan != getClientCurrentSubAccount(clients[i]).clan) {
- messageClientClanChat(clients[i], client, messageText);
+ messageClientClanChat(getClientFromPlayerElement(clients[i]), client, messageText);
}
}
}
diff --git a/scripts/server/clan.js b/scripts/server/clan.js
index 8cfaf5af..e3b095cc 100644
--- a/scripts/server/clan.js
+++ b/scripts/server/clan.js
@@ -35,13 +35,14 @@ function loadClansFromDatabase() {
let tempClans = [];
let dbConnection = connectToDatabase();
+ let dbAssoc;
if(dbConnection) {
- let dbQuery = queryDatabase(dbConnection, "SELECT * FROM `clan_main` WHERE `clan_server` = " + String(serverId));
+ let dbQuery = queryDatabase(dbConnection, "SELECT * FROM `clan_main` WHERE `clan_deleted` = 0 AND `clan_server` = " + String(serverId));
if(dbQuery) {
if(dbQuery.numRows > 0) {
- while(dbFetchAssoc = fetchQueryAssoc(dbQuery)) {
- let tempClanData = getClasses().clanData(dbFetchAssoc);
+ while(dbAssoc = fetchQueryAssoc(dbQuery)) {
+ let tempClanData = getClasses().clanData(dbAssoc);
tempClanData.members = loadClanMembersFromDatabase(tempClanData.databaseId);
tempClanData.ranks = loadClanRanksFromDatabase(tempClanData.databaseId);
tempClans.push(tempClanData);
diff --git a/scripts/server/class.js b/scripts/server/class.js
index e8f3cd4d..9fc9aa5d 100644
--- a/scripts/server/class.js
+++ b/scripts/server/class.js
@@ -104,21 +104,21 @@ function initClassTable() {
this.till = Number(businessAssoc["biz_till"]);
}
},
- locationData: class {
- constructor(locationAssoc) {
- if(!locationAssoc) {
+ businessLocationData: class {
+ constructor(businessLocationAssoc) {
+ if(!businessLocationAssoc) {
return;
}
- this.databaseId = locationAssoc("biz_id");
- this.name = locationAssoc("loc_name");
- this.type = locationAssoc("loc_type");
- this.business = locationAssoc("loc_biz");
- this.enabled = locationAssoc("loc_enabled");
+ this.databaseId = businessLocationAssoc("biz_loc_id");
+ this.name = businessLocationAssoc("biz_loc_name");
+ this.type = businessLocationAssoc("biz_loc_type");
+ this.business = businessLocationAssoc("biz_loc_biz");
+ this.enabled = businessLocationAssoc("biz_loc_enabled");
- this.position = new Vec3(businessAssoc("loc_pos_x"), businessAssoc("loc__pos_y"), businessAssoc("loc_pos_z"));
- this.interior = Number(businessAssoc["loc_int"]);
- this.dimension = Number(businessAssoc["loc_vw"]);
+ this.position = new Vec3(businessLocationAssoc("biz_loc_pos_x"), businessLocationAssoc("biz_loc_pos_y"), businessLocationAssoc("biz_loc_pos_z"));
+ this.interior = Number(businessLocationAssoc["biz_loc_int"]);
+ this.dimension = Number(businessLocationAssoc["biz_loc_vw"]);
}
},
houseData: class {
@@ -135,10 +135,11 @@ function initClassTable() {
// General Info
this.databaseId = 0;
this.server = serverId;
- this.model = vehicle.modelIndex;
+ this.model = (vehicle) ? vehicle.modelIndex : 0;
this.vehicle = vehicle;
this.tempVehicle = false;
this.streamedBy = false; // For IV only
+ this.ivSyncId = -1;
// Ownership
this.ownerType = AG_VEHOWNER_NONE;
@@ -147,9 +148,11 @@ function initClassTable() {
this.rentPrice = 0;
// Position and Rotation
- this.spawnPosition = vehicle.position;
- this.spawnRotation = vehicle.heading;
+ this.spawnPosition = (vehicle) ? vehicle.position : new Vec3(0.0, 0.0, 0.0);
+ this.spawnRotation = (vehicle) ? vehicle.heading : 0.0;
this.spawnLocked = false;
+ this.syncPosition = new Vec3(0.0, 0.0, 0.0); // For IV only
+ this.syncHeading = 0.0; // For IV only
// Colour Info
this.colour1IsRGBA = 0;
@@ -191,6 +194,7 @@ function initClassTable() {
this.spawnPosition = new Vec3(vehicleAssoc["veh_pos_x"], vehicleAssoc["veh_pos_y"], vehicleAssoc["veh_pos_z"]);
this.spawnRotation = Number(vehicleAssoc["veh_rot_z"]);
this.spawnLocked = vehicleAssoc["veh_spawn_lock"];
+
// Colour Info
this.colour1IsRGBA = vehicleAssoc["veh_col1_isrgba"];
@@ -249,7 +253,83 @@ function initClassTable() {
this.whenReported = new Date().getTime();
this.databaseId = 0;
}
- }
+ },
+ jobData: class {
+ constructor(jobAssoc) {
+ if(!jobAssoc) {
+ return;
+ }
+
+ this.databaseId = jobAssoc["job_id"];
+ this.type = jobAssoc["job_type"];
+ this.name = jobAssoc["job_name"];
+ this.enabled = jobAssoc["job_enabled"];
+ this.blipModel = jobAssoc["job_blip"];
+ this.pickupModel = jobAssoc["job_pickup"];
+ this.colour = toColour(jobAssoc["job_colour_r"], jobAssoc["job_colour_g"], jobAssoc["job_colour_b"], 255);
+ this.whitelist = jobAssoc["job_whitelist"];
+
+ this.equipment = [];
+ this.uniforms = [];
+ this.locations = [];
+ }
+ },
+ jobEquipmentData: class {
+ constructor(jobEquipmentAssoc) {
+ if(!jobEquipmentAssoc) {
+ return;
+ }
+
+ this.databaseId = jobEquipmentAssoc["job_equip_id"];
+ this.job = jobEquipmentAssoc["job_equip_job"];
+ this.name = jobEquipmentAssoc["job_equip_name"];
+ this.requiredRank = jobEquipmentAssoc["job_equip_minrank"];
+ this.enabled = jobEquipmentAssoc["job_equip_enabled"];
+ }
+ },
+ jobEquipmentWeaponData: class {
+ constructor(jobEquipmentWeaponAssoc) {
+ if(!jobEquipmentWeaponAssoc) {
+ return;
+ }
+
+ this.databaseId = jobEquipmentWeaponAssoc["job_equip_wep_id"];
+ this.equipmentId = jobEquipmentWeaponAssoc["job_equip_wep_equip"];
+ this.weaponId = jobEquipmentWeaponAssoc["job_equip_wep_wep"];
+ this.ammo = jobEquipmentWeaponAssoc["job_equip_wep_ammo"];
+ this.enabled = jobEquipmentWeaponAssoc["job_equip_wep_enabled"];
+ }
+ },
+ jobUniformData: class {
+ constructor(jobUniformAssoc) {
+ if(!jobUniformAssoc) {
+ return;
+ }
+
+ this.databaseId = jobUniformAssoc["job_uniform_id"];
+ this.job = jobUniformAssoc["job_uniform_job"];
+ this.name = jobUniformAssoc["job_uniform_name"];
+ this.requiredRank = jobUniformAssoc["job_uniform_minrank"];
+ this.skin = jobUniformAssoc["job_uniform_skin"];
+ this.enabled = jobUniformAssoc["job_uniform_skin"];
+ }
+ },
+ jobLocationData: class {
+ constructor(jobLocationAssoc) {
+ if(!jobLocationAssoc) {
+ return;
+ }
+
+ this.databaseId = jobLocationAssoc["job_loc_id"];
+ this.job = jobLocationAssoc["job_loc_job"];
+ this.position = new Vec3(jobLocationAssoc["job_loc_pos_x"], jobLocationAssoc["job_loc_pos_y"], jobLocationAssoc["job_loc_pos_z"]);
+ //this.blipModel = jobAssoc["job_blip"];
+ //this.pickupModel = jobAssoc["job_pickup"];
+ this.blip = false;
+ this.pickup = false;
+ this.enabled = jobLocationAssoc["job_loc_enabled"];
+ }
+ },
}
return tempClasses;
diff --git a/scripts/server/client.js b/scripts/server/client.js
index ce42ba02..56377e07 100644
--- a/scripts/server/client.js
+++ b/scripts/server/client.js
@@ -121,4 +121,19 @@ addNetworkHandler("ag.heldKey", function(client, key) {
}
});
+// ---------------------------------------------------------------------------
+
+addNetworkHandler("ag.player.sync", function(client, position, heading) {
+ client.setData("ag.position", position, true);
+ client.setData("ag.heading", heading, true);
+});
+
+// ---------------------------------------------------------------------------
+
+addNetworkHandler("ag.veh.sync", function(client, syncId, position, heading) {
+ //let vehicle = getVehicleFromSyncId(syncId);
+ //vehicle.setData("ag.position") = position;
+ //vehicle.setData("ag.heading") = heading;
+});
+
// ---------------------------------------------------------------------------
\ No newline at end of file
diff --git a/scripts/server/command.js b/scripts/server/command.js
index 7eb5630f..40af6d22 100644
--- a/scripts/server/command.js
+++ b/scripts/server/command.js
@@ -11,7 +11,22 @@
let serverCommands = {};
function initCommandScript() {
+ console.log("[Asshat.Command]: Initializing commands script ...");
serverCommands = loadCommandData();
+ addCommandCommandHandlers();
+ console.log("[Asshat.Command]: Initialized commands script!");
+}
+
+// ---------------------------------------------------------------------------
+
+function addCommandCommandHandlers() {
+ console.log("[Asshat.Clan]: Adding command command handlers ...");
+ let commandCommands = serverCommands.command;
+ for(let i in commandCommands) {
+ addCommandHandler(commandCommands[i].command, commandCommands[i].handlerFunction);
+ }
+ console.log("[Asshat.Command]: Command command handlers added successfully!");
+ return true;
}
// ---------------------------------------------------------------------------
@@ -77,7 +92,12 @@ function loadCommandData() {
class: [],
client: [],
colour: [],
- command: [],
+ command: [
+ commandData("cmd_enabletype", enableAllCommandsByType, "", getStaffFlagValue("developer"), true, true),
+ commandData("cmd_disabletype", disableAllCommandsByType, "", getStaffFlagValue("developer"), true, true),
+ commandData("cmd_enable", enableCommand, "", getStaffFlagValue("developer"), true, true),
+ commandData("cmd_disable", disableCommand, "", getStaffFlagValue("developer"), true, true),
+ ],
config: [],
core: [],
database: [],
@@ -97,7 +117,8 @@ function loadCommandData() {
commandData("startwork", startWorkingCommand, "", getStaffFlagValue("none"), true, false),
commandData("stopwork", stopWorkingCommand, "", getStaffFlagValue("none"), true, false),
commandData("quitjob", quitJobCommand, "", getStaffFlagValue("none"), true, false),
- commandData("uniform", jobUniformCommand, "", getStaffFlagValue("none"), true, false),
+ commandData("uniform", jobUniformCommand, "[uniform]", getStaffFlagValue("none"), true, false),
+ commandData("equip", jobEquipmentCommand, "[equipment]", getStaffFlagValue("none"), true, false),
commandData("radio", jobRadioCommand, "", getStaffFlagValue("none"), true, false),
commandData("r", jobRadioCommand, "", getStaffFlagValue("none"), true, false),
@@ -120,6 +141,10 @@ function loadCommandData() {
commandData("setweather", setWeatherCommand, "", getStaffFlagValue("manageServer"), true, true),
commandData("setsnow", setSnowingCommand, " ", getStaffFlagValue("manageServer"), true, true),
commandData("setlogo", toggleServerLogoCommand, "<0/1 state>", getStaffFlagValue("manageServer"), true, true),
+ commandData("pos", getPositionCommand, "", getStaffFlagValue("basicModeration"), true, true),
+ commandData("newcharspawn", setNewCharacterSpawnPositionCommand, "", getStaffFlagValue("manageServer"), true, true),
+ commandData("newcharcash", setNewCharacterMoneyCommand, "", getStaffFlagValue("manageServer"), true, true),
+ commandData("newcharskin", setNewCharacterSkinCommand, "[skin id]", getStaffFlagValue("manageServer"), true, true),
],
moderation: [
commandData("kick", kickClientCommand, " [reason]", getStaffFlagValue("basicModeration"), true, true),
@@ -150,7 +175,7 @@ function loadCommandData() {
commandData("vehdelowner", removeVehicleOwnerCommand, "", getStaffFlagValue("manageVehicles"), true, true),
commandData("vehinfo", getVehicleInfoCommand, "", getStaffFlagValue("manageVehicles"), true, true),
- commandData("vehpark", parkVehicleCommand, "", getStaffFlagValue("manageVehicles"), true, true),
+ commandData("vehpark", toggleVehicleSpawnLockCommand, "", getStaffFlagValue("manageVehicles"), true, true),
],
}
return tempCommands;
@@ -196,7 +221,7 @@ function getCommandRequiredPermissions(command) {
// ---------------------------------------------------------------------------
function getCommandSyntaxText(command) {
- return getCommand(command).syntaxString;
+ return `/${command} ${getCommand(command).syntaxString}`;
}
// ---------------------------------------------------------------------------
@@ -205,4 +230,131 @@ function isCommandAllowedOnDiscord(command) {
return getCommand(command).allowOnDiscord;
}
-// ---------------------------------------------------------------------------
\ No newline at end of file
+// ---------------------------------------------------------------------------
+
+function disableCommand(command, params, client) {
+ if(getCommand(command).requireLogin) {
+ if(!isClientLoggedIn(client)) {
+ messageClientError(client, "You must be logged in to use this command!");
+ return false;
+ }
+ }
+
+ if(isClientFromDiscord(client)) {
+ if(!isCommandAllowedOnDiscord(command)) {
+ messageClientError(client, "That command isn't available on discord!");
+ return false;
+ }
+ }
+
+ if(!doesClientHaveStaffPermission(client, getCommandRequiredPermissions(command))) {
+ messageClientError(client, "You do not have permission to use this command!");
+ return false;
+ }
+
+ removeCommandHandler(params);
+ messageClientSuccess(client, `[#FF9900]All server data saved to database!`);
+ return true;
+}
+
+// ---------------------------------------------------------------------------
+
+function enableCommand(command, params, client) {
+ if(getCommand(command).requireLogin) {
+ if(!isClientLoggedIn(client)) {
+ messageClientError(client, "You must be logged in to use this command!");
+ return false;
+ }
+ }
+
+ if(isClientFromDiscord(client)) {
+ if(!isCommandAllowedOnDiscord(command)) {
+ messageClientError(client, "That command isn't available on discord!");
+ return false;
+ }
+ }
+
+ if(!doesClientHaveStaffPermission(client, getCommandRequiredPermissions(command))) {
+ messageClientError(client, "You do not have permission to use this command!");
+ return false;
+ }
+
+ addCommandHandler(params, getCommand(params).handlerFunction);
+ messageClientSuccess(client, `[#FF9900]All server data saved to database!`);
+ return true;
+}
+
+// ---------------------------------------------------------------------------
+
+function disableAllCommandsByType(command, params, client) {
+ if(getCommand(command).requireLogin) {
+ if(!isClientLoggedIn(client)) {
+ messageClientError(client, "You must be logged in to use this command!");
+ return false;
+ }
+ }
+
+ if(isClientFromDiscord(client)) {
+ if(!isCommandAllowedOnDiscord(command)) {
+ messageClientError(client, "That command isn't available on discord!");
+ return false;
+ }
+ }
+
+ if(!doesClientHaveStaffPermission(client, getCommandRequiredPermissions(command))) {
+ messageClientError(client, "You do not have permission to use this command!");
+ return false;
+ }
+
+ params = params.toLowerCase();
+
+ if(typeof serverData.commands[params] == "undefined") {
+ messageClientError(client, "That command type does not exist!");
+ return false;
+ }
+
+ for(let i in serverData.commands[params]) {
+ removeCommandHandler(serverData.commands[params][i].command);
+ }
+
+ messageClientSuccess(client, `[#FF9900]All ${params} commands have been disabled!`);
+ return true;
+}
+
+// ---------------------------------------------------------------------------
+
+function enableAllCommandsByType(command, params, client) {
+ if(getCommand(command).requireLogin) {
+ if(!isClientLoggedIn(client)) {
+ messageClientError(client, "You must be logged in to use this command!");
+ return false;
+ }
+ }
+
+ if(isClientFromDiscord(client)) {
+ if(!isCommandAllowedOnDiscord(command)) {
+ messageClientError(client, "That command isn't available on discord!");
+ return false;
+ }
+ }
+
+ if(!doesClientHaveStaffPermission(client, getCommandRequiredPermissions(command))) {
+ messageClientError(client, "You do not have permission to use this command!");
+ return false;
+ }
+
+ params = params.toLowerCase();
+
+ if(typeof serverData.commands[params] == "undefined") {
+ messageClientError(client, "That command type does not exist!");
+ return false;
+ }
+
+ for(let i in serverData.commands[params]) {
+ let command = serverData.commands[params][i].command;
+ addCommandHandler(command, serverData.commands[params][i].handlerFunction);
+ }
+
+ messageClientSuccess(client, `[#FF9900]All ${params} commands have been enabled!`);
+ return true;
+}
\ No newline at end of file
diff --git a/scripts/server/config.js b/scripts/server/config.js
index dd46c50a..048687bf 100644
--- a/scripts/server/config.js
+++ b/scripts/server/config.js
@@ -18,6 +18,7 @@ let serverConfig = {
fallingSnow: 0,
groundSnow: 0,
showLogo: true,
+ guiColour: [200, 200, 200],
colour: {
byType: {
talkMessage: toColour(200, 200, 200),
@@ -175,6 +176,7 @@ function loadServerConfig() {
serverConfig.fallingSnow = intToBool(dbAssoc["svr_start_snow_falling"]);
serverConfig.groundSnow = intToBool(dbAssoc["svr_start_snow_ground"]);
serverConfig.useGUI = intToBool(dbAssoc["svr_gui"]);
+ serverConfig.guiColour = [dbAssoc["svr_gui_col1_r"], dbAssoc["svr_gui_col1_g"], dbAssoc["svr_gui_col1_b"]];
applyConfigToServer();
diff --git a/scripts/server/core.js b/scripts/server/core.js
index 22f619a0..6125052d 100644
--- a/scripts/server/core.js
+++ b/scripts/server/core.js
@@ -9,6 +9,8 @@
// ===========================================================================
let serverId = 0;
+let scriptVersion = "1.0";
+let serverStartTime = new Date().getTime();
// ----------------------------------------------------------------------------
@@ -584,7 +586,46 @@ let serverData = {
jobType: AG_JOB_POLICE,
jobSkin: 1,
jobColour: serverConfig.colour.byName.policeBlue,
- enabled: true
+ enabled: true,
+ weapons: [[1,1], [2, 150], [4,20]],
+ equipment: [
+ { // Standard police officer equipment
+ requiredRank: 0,
+ weapons: [
+ [1,1], // Baseball Bat (Nitestick alternative)
+ [2,150], // Pistol
+ [4,20], // Shotgun
+ ]
+ },
+ { // Detective Equipment
+ requiredRank: 1,
+ weapons: [
+ [4,1], // Nitestick
+ [17,150], // Colt 45
+ [19,20], // Shotgun
+ [34,100], // Camera
+ ]
+ },
+ { // Supervisor Equipment
+ requiredRank: 3,
+ weapons: [
+ [4,1], // Nitestick
+ [17,150], // Colt 45
+ [19,20], // Shotgun
+ [25,300], // MP5
+ ]
+ },
+ { // SWAT Equipment
+ requiredRank: 2,
+ weapons: [
+ [4,1], // Nitestick
+ [17,150], // Colt 45
+ [19,20], // Shotgun
+ [25,300], // MP5
+ [26,300], // M4
+ ]
+ },
+ ]
},
{
name: "Paramedic",
@@ -661,7 +702,8 @@ let serverData = {
jobType: AG_JOB_POLICE,
jobSkin: 1,
jobColour: serverConfig.colour.byName.policeBlue,
- enabled: true
+ enabled: true,
+ weapons: [[1,1], [2, 150], [4,20]],
},
{
name: "Police Officer",
@@ -672,7 +714,8 @@ let serverData = {
jobType: AG_JOB_POLICE,
jobSkin: 1,
jobColour: serverConfig.colour.byName.policeBlue,
- enabled: true
+ enabled: true,
+ weapons: [[1,1], [2, 150], [4,20]],
},
{
name: "Paramedic",
@@ -742,7 +785,202 @@ let serverData = {
},
],
[ // GTA VC
-
+ {
+ name: "Police Officer",
+ position: new Vec3(399.77, -468.90, 11.73),
+ pickup: false,
+ pickupModel: 375,
+ blip: false,
+ jobType: AG_JOB_POLICE,
+ jobSkin: 1,
+ jobColour: serverConfig.colour.byName.policeBlue,
+ enabled: true,
+ equipment: [
+ { // Standard police officer equipment
+ requiredRank: 0,
+ weapons: [
+ [4,1], // Nitestick
+ [17,150], // Colt 45
+ [19,20], // Shotgun
+ ]
+ },
+ { // Detective Equipment
+ requiredRank: 1,
+ weapons: [
+ [4,1], // Nitestick
+ [17,150], // Colt 45
+ [19,20], // Shotgun
+ [34,100], // Camera
+ ]
+ },
+ { // Supervisor Equipment
+ requiredRank: 3,
+ weapons: [
+ [4,1], // Nitestick
+ [17,150], // Colt 45
+ [19,20], // Shotgun
+ [25,300], // MP5
+ ]
+ },
+ { // SWAT Equipment
+ requiredRank: 2,
+ weapons: [
+ [4,1], // Nitestick
+ [17,150], // Colt 45
+ [19,20], // Shotgun
+ [25,300], // MP5
+ [26,300], // M4
+ ]
+ },
+ ]
+ },
+ {
+ name: "Police Officer",
+ position: new Vec3(508.96, 512.07, 12.10),
+ pickup: false,
+ pickupModel: 375,
+ blip: false,
+ jobType: AG_JOB_POLICE,
+ jobSkin: 1,
+ jobColour: serverConfig.colour.byName.policeBlue,
+ enabled: true,
+ equipment: [
+ { // Standard police officer equipment
+ requiredRank: 0,
+ weapons: [
+ [4,1], // Nitestick
+ [17,150], // Colt 45
+ [19,20], // Shotgun
+ ]
+ },
+ { // Detective Equipment
+ requiredRank: 1,
+ weapons: [
+ [4,1], // Nitestick
+ [17,150], // Colt 45
+ [19,20], // Shotgun
+ [34,100], // Camera
+ ]
+ },
+ { // Supervisor Equipment
+ requiredRank: 3,
+ weapons: [
+ [4,1], // Nitestick
+ [17,150], // Colt 45
+ [19,20], // Shotgun
+ [25,300], // MP5
+ ]
+ },
+ { // SWAT Equipment
+ requiredRank: 2,
+ weapons: [
+ [4,1], // Nitestick
+ [17,150], // Colt 45
+ [19,20], // Shotgun
+ [25,300], // MP5
+ [26,300], // M4
+ ]
+ },
+ ]
+ },
+ {
+ name: "Police Officer",
+ position: new Vec3(-657.43, 762.31, 11.59),
+ pickup: false,
+ pickupModel: 375,
+ blip: false,
+ jobType: AG_JOB_POLICE,
+ jobSkin: 1,
+ jobColour: serverConfig.colour.byName.policeBlue,
+ enabled: true,
+ equipment: [
+ { // Standard police officer equipment
+ requiredRank: 0,
+ weapons: [
+ [4,1], // Nitestick
+ [17,150], // Colt 45
+ [19,20], // Shotgun
+ ]
+ },
+ { // Detective Equipment
+ requiredRank: 1,
+ weapons: [
+ [4,1], // Nitestick
+ [17,150], // Colt 45
+ [19,20], // Shotgun
+ [34,100], // Camera
+ ]
+ },
+ { // Supervisor Equipment
+ requiredRank: 3,
+ weapons: [
+ [4,1], // Nitestick
+ [17,150], // Colt 45
+ [19,20], // Shotgun
+ [25,300], // MP5
+ ]
+ },
+ { // SWAT Equipment
+ requiredRank: 2,
+ weapons: [
+ [4,1], // Nitestick
+ [17,150], // Colt 45
+ [19,20], // Shotgun
+ [25,300], // MP5
+ [26,300], // M4
+ ]
+ },
+ ]
+ },
+ {
+ name: "Police Officer",
+ position: new Vec3(-885.08, -470.44, 13.11),
+ pickup: false,
+ pickupModel: 375,
+ blip: false,
+ jobType: AG_JOB_POLICE,
+ jobSkin: 1,
+ jobColour: serverConfig.colour.byName.policeBlue,
+ enabled: true,
+ equipment: [
+ { // Standard police officer equipment
+ requiredRank: 0,
+ weapons: [
+ [4,1], // Nitestick
+ [17,150], // Colt 45
+ [19,20], // Shotgun
+ ]
+ },
+ { // Detective Equipment
+ requiredRank: 1,
+ weapons: [
+ [4,1], // Nitestick
+ [17,150], // Colt 45
+ [19,20], // Shotgun
+ [34,100], // Camera
+ ]
+ },
+ { // Supervisor Equipment
+ requiredRank: 3,
+ weapons: [
+ [4,1], // Nitestick
+ [17,150], // Colt 45
+ [19,20], // Shotgun
+ [25,300], // MP5
+ ]
+ },
+ { // SWAT Equipment
+ requiredRank: 2,
+ weapons: [
+ [4,1], // Nitestick
+ [17,150], // Colt 45
+ [19,20], // Shotgun
+ [25,300], // MP5
+ [26,300], // M4
+ ]
+ },
+ ]
+ },
],
[ // GTA SA
diff --git a/scripts/server/developer.js b/scripts/server/developer.js
index 7f3199e0..cd6ae8c4 100644
--- a/scripts/server/developer.js
+++ b/scripts/server/developer.js
@@ -47,15 +47,17 @@ function executeServerCodeCommand(command, params, client) {
return false;
}
+ let returnVal = "Nothing";
try {
- eval(params);
+ returnVal = eval("(" + params + ")");
} catch(error) {
messageClientError(client, "The code could not be executed!");
return false;
}
- messageClientSuccess(client, "Code executed!");
- messageClientNormal(client, "Code: " + params);
+ messageClientSuccess(client, "Server code executed!");
+ messageClientNormal(client, `Code: ${params}`);
+ messageClientNormal(client, `Returns: ${returnVal}`);
return true;
}
@@ -79,24 +81,26 @@ function executeClientCodeCommand(command, params, client) {
return false;
}
- let splitParams = params.split();
+ let splitParams = params.split(" ");
let targetClient = getClientFromParams(splitParams[0]);
- let code = splitParams.slice(1).join(" ");
+ let targetCode = splitParams.slice(1).join(" ");
+
+ console.log(targetCode);
if(!targetClient) {
messageClientError(client, "That player was not found!");
return false;
}
- if(code.length > 0) {
+ if(targetCode == "") {
messageClientError(client, "You didn't enter any code!");
return false;
}
- triggerNetworkEvent("ag.runcode", targetClient, code);
+ triggerNetworkEvent("ag.runCode", targetClient, targetCode);
- messageClientSuccess(client, "Client code executed for " + String(targetClient.name) + "!");
- messageClientNormal(client, "Code: " + params);
+ messageClientSuccess(client, "Executing client code for " + String(targetClient.name) + "!");
+ messageClientNormal(client, "Code: " + targetCode);
return true;
}
@@ -155,4 +159,49 @@ function restartGameModeCommand(command, params, client) {
return true;
}
+// ---------------------------------------------------------------------------
+
+addNetworkHandler("ag.runCodeFail", function(client, returnTo, code) {
+ let returnClient = getClientFromParams(returnTo);
+ if(!returnClient) {
+ return false;
+ }
+
+ messageClientError(returnClient, `Client code failed to execute for ${client.name}!`);
+ messageClientNormal(returnClient, `Code: ${code}`, getColourByName("yellow"));
+});
+
+// ---------------------------------------------------------------------------
+
+addNetworkHandler("ag.runCodeFail", function(client, returnTo, returnVal, code) {
+ let returnClient = getClientFromParams(returnTo);
+ if(!returnClient) {
+ return false;
+ }
+
+ messageClientSuccess(returnClient, `Client code executed for ${client.name}!`);
+ messageClientNormal(returnClient, `Code: ${code}`, getColourByName("yellow"));
+ messageClientNormal(returnClient, `Returns: ${returnVal}`, getColourByName("yellow"));
+});
+
+// ---------------------------------------------------------------------------
+
+function submitIdea(client, ideaText) {
+ let dbConnection = connectToDatabase();
+ if(dbConnection) {
+ let safeIdeaMessage = escapeDatabaseString(dbConnection, ideaText);
+ executeDatabaseQuery(dbConnection, `INSERT INTO idea_main (idea_server, idea_script_ver, idea_who_added, idea_when_added, idea_message, idea_pos_x, idea_pos_y, idea_pos_z, idea_rot_z, idea_svr_start, idea_session) VALUES (${serverId}, '${scriptVersion}', ${getClientData(client).accountData.databaseId}, UNIX_TIMESTAMP(), '${safeIdeaMessage}', ${client.getData("ag.pos").x}, ${client.getData("ag.pos").y}, ${client.getData("ag.pos").z}, ${client.getData("ag.heading")}, ${serverStartTime}, ${client.getData("ag.session")})`)
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+function submitBugReport(client, bugText) {
+ let dbConnection = connectToDatabase();
+ if(dbConnection) {
+ let safeBugMessage = escapeDatabaseString(dbConnection, bugText);
+ executeDatabaseQuery(dbConnection, `INSERT INTO bug_main (bug_server, bug_script_ver, bug_who_added, bug_when_added, bug_message, bug_pos_x, bug_pos_y, bug_pos_z, bug_rot_z, bug_svr_start, bug_session) VALUES (${serverId}, '${scriptVersion}', ${getClientData(client).accountData.databaseId}, UNIX_TIMESTAMP(), '${safeBugMessage}', ${client.getData("ag.pos").x}, ${client.getData("ag.pos").y}, ${client.getData("ag.pos").z}, ${client.getData("ag.heading")}, ${serverStartTime}, ${client.getData("ag.session")})`)
+ }
+}
+
// ---------------------------------------------------------------------------
\ No newline at end of file
diff --git a/scripts/server/discord.js b/scripts/server/discord.js
index c2920870..c7cceb54 100644
--- a/scripts/server/discord.js
+++ b/scripts/server/discord.js
@@ -64,4 +64,10 @@ function getDiscordUserData(discordUserId) {
return loadAccountFromDiscordUserId(discordUserId);
}
+// ---------------------------------------------------------------------------
+
+function messageDiscord(message) {
+
+}
+
// ---------------------------------------------------------------------------
\ No newline at end of file
diff --git a/scripts/server/event.js b/scripts/server/event.js
index a705500f..bbad21dc 100644
--- a/scripts/server/event.js
+++ b/scripts/server/event.js
@@ -11,24 +11,6 @@
addEventHandler("OnPlayerJoined", function(event, client) {
setTimeout(function() {
initClient(client);
- //triggerNetworkEvent("ag.connectCamera", client, serverConfig.connectCameraPosition[getServerGame()], serverConfig.connectCameraLookAt[getServerGame()]);
-
- //client.setData("ag.loginAttemptsRemaining", 3, false);
-
- //let tempAccountData = loadAccountFromName(client.name);
- //let tempSubAccounts = loadSubAccountsFromAccount(tempAccountData.databaseId);
-
- //serverData.clients[client.index] = new serverClasses.clientData(client, tempAccountData, tempSubAccounts);
-
- //sendAllBlips(client);
-
- //if(tempAccountData != false) {
- // triggerNetworkEvent("ag.showLogin", client);
- // //messageClient("Welcome back to Asshat Gaming RP, " + String(client.name) + "! Please /login to continue.", client, serverConfig.colour.byName["white"]);
- //} else {
- // triggerNetworkEvent("ag.showRegistration", client);
- // //messageClient("Welcome to Asshat Gaming RP, " + String(client.name) + "! Please /register to continue.", client, serverConfig.colour.byName["white"]);
- //}
}, 500);
});
@@ -85,7 +67,16 @@ bindEventHandler("OnResourceStart", thisResource, function(event, resource) {
addEventHandler("onPedEnterVehicle", function(event, ped, vehicle, seat) {
ped.setData("ag.vehSeat", seat, false);
+ if(!vehicle || vehicle.owner != -1) {
+ return false;
+ }
+
let vehicleData = getVehicleData(vehicle);
+ if(!vehicleData) {
+ return false;
+ }
+
+
if(ped.isType(ELEMENT_PLAYER)) {
let client = getClientFromPlayerElement(ped);
@@ -138,4 +129,14 @@ addEventHandler("onPlayerChat", function(event, client, messageText) {
message(`${getClientSubAccountName(client)}: [#FFFFFF]${messageText}`, getClientChatColour(client));
});
-// ---------------------------------------------------------------------------
\ No newline at end of file
+// ---------------------------------------------------------------------------
+
+addEventHandler("OnPedExitVehicle", function(event, ped, vehicle) {
+ if(!vehicle || vehicle.owner != -1) {
+ return false;
+ }
+
+ if(!getVehicleData(vehicle)) {
+ return false;
+ }
+});
\ No newline at end of file
diff --git a/scripts/server/job.js b/scripts/server/job.js
index 6f4a31ed..039249b2 100644
--- a/scripts/server/job.js
+++ b/scripts/server/job.js
@@ -10,10 +10,11 @@
function initJobScript() {
console.log("[Asshat.Job]: Initializing job script ...");
+ loadJobsFromDatabase();
addJobCommandHandlers();
createAllJobPickups();
-
- //createAllJobBlips();
+ createAllJobBlips();
+
//addEvent("onJobPickupCollected", null, 2);
console.log("[Asshat.Job]: Job script initialized successfully!");
@@ -34,52 +35,181 @@ function addJobCommandHandlers() {
// ---------------------------------------------------------------------------
-function createAllJobBlips() {
- for(let i in serverData.jobs[getServerGame()]) {
- serverData.jobs[getServerGame()][i].blip = createBlip(0, serverData.jobs[getServerGame()][i].position, 2, serverConfig.colour.byName.yellow);
- }
-}
+function loadJobsFromDatabase() {
+ console.log("[Asshat.Job]: Loading jobs from database ...");
-// ---------------------------------------------------------------------------
-
-function sendAllJobBlips(client) {
- //if(getClientData(client).job == AG_JOB_NONE) {
- let tempBlips = [];
- for(let i in serverData.jobs[getServerGame()]) {
- let jobData = serverData.jobs[getServerGame()][i];
- tempBlips.push([0, jobData.position.x, jobData.position.y, jobData.position.z, 2, serverConfig.colour.byName.yellow]);
+ let tempJobs = [];
+ let dbConnection = connectToDatabase();
+ let dbQuery = null;
+ let dbAssoc;
+
+ if(dbConnection) {
+ dbQuery = queryDatabase(dbConnection, "SELECT * FROM `job_main` WHERE `job_enabled` = 1 AND `job_server` = " + String(serverId));
+ if(dbQuery) {
+ if(dbQuery.numRows > 0) {
+ while(dbAssoc = fetchQueryAssoc(dbQuery)) {
+ let tempJobData = new serverClasses.jobData(dbAssoc);
+ tempJobData.equipment = loadJobEquipmentsFromDatabase(tempJobData.databaseId);
+ tempJobData.uniforms = loadJobUniformsFromDatabase(tempJobData.databaseId);
+ tempJobData.locations = loadJobLocationsFromDatabase(tempJobData.databaseId);
+ tempJobs.push(tempJobData);
+ console.log(`[Asshat.Job]: Job '${tempJobData.name}' loaded from database successfully!`);
+ }
+ }
+ freeDatabaseQuery(dbQuery);
}
- triggerNetworkEvent("ag.blips", client, tempBlips);
- //}
+ disconnectFromDatabase(dbConnection);
+ }
+
+ console.log(`[Asshat.Job]: ${tempJobs.length} jobs loaded from database successfully!`);
+ return tempJobs;
}
// ---------------------------------------------------------------------------
-function sendAllJobSpheres() {
- let tempJobSpheres = [];
+function loadJobEquipmentsFromDatabase(jobDatabaseId) {
+ console.log(`[Asshat.Job]: Loading job equipments for job ${jobDatabaseId} from database ...`);
- for(let i in serverData.jobs[getServerGame()]) {
- tempJobSpheres.push([
- serverData.jobs[getServerGame()][i].position.x,
- serverData.jobs[getServerGame()][i].position.y,
- serverData.jobs[getServerGame()][i].position.z,
- 2,
- AG_SPHERE_JOB,
- i,
- ]);
+ let tempJobEquipments = [];
+ let dbConnection = connectToDatabase();
+ let dbQuery = null;
+ let dbAssoc;
+
+ if(dbConnection) {
+ dbQuery = queryDatabase(dbConnection, "SELECT * FROM `job_equip` WHERE `job_equip_enabled` = 1 AND `job_equip_job` = " + String(jobDatabaseId));
+ if(dbQuery) {
+ if(dbQuery.numRows > 0) {
+ while(dbAssoc = fetchQueryAssoc(dbQuery)) {
+ let tempJobEquipmentData = new serverClasses.jobEquipmentData(dbAssoc);
+ tempJobEquipmentData.weapons = loadJobEquipmentWeaponsFromDatabase(tempJobEquipmentData.databaseId);
+ tempJobEquipments.push(tempJobEquipmentData);
+ console.log(`[Asshat.Job]: Job equipment '${tempJobEquipmentData.name}' loaded from database successfully!`);
+ }
+ }
+ freeDatabaseQuery(dbQuery);
+ }
+ disconnectFromDatabase(dbConnection);
}
- triggerNetworkEvent("ag.jobSpheres", client, tempJobSpheres);
+
+ console.log(`[Asshat.Job]: ${tempJobEquipments.length} job equipments for job ${jobDatabaseId} loaded from database successfully!`);
+ return tempJobEquipments;
+}
+
+// ---------------------------------------------------------------------------
+
+function loadJobLocationsFromDatabase(jobDatabaseId) {
+ console.log(`[Asshat.Job]: Loading job locations for job ${jobDatabaseId} from database ...`);
+
+ let tempJobLocations = [];
+ let dbConnection = connectToDatabase();
+ let dbQuery = null;
+ let dbAssoc;
+
+ if(dbConnection) {
+ dbQuery = queryDatabase(dbConnection, "SELECT * FROM `job_loc` WHERE `job_loc_enabled` = 1 AND `job_loc_job` = " + String(jobDatabaseId));
+ if(dbQuery) {
+ if(dbQuery.numRows > 0) {
+ while(dbAssoc = fetchQueryAssoc(dbQuery)) {
+ let tempJobLocationData = new serverClasses.jobLocationData(dbAssoc);
+ tempJobLocations.push(tempJobLocationData);
+ console.log(`[Asshat.Job]: Job location '${tempJobLocationData.name}' loaded from database successfully!`);
+ }
+ }
+ freeDatabaseQuery(dbQuery);
+ }
+ disconnectFromDatabase(dbConnection);
+ }
+
+ console.log(`[Asshat.Job]: ${tempJobLocations.length} job locations for job ${jobDatabaseId} loaded from database successfully!`);
+ return tempJobLocations;
+}
+
+// ---------------------------------------------------------------------------
+
+function loadJobUniformsFromDatabase(jobDatabaseId) {
+ console.log(`[Asshat.Job]: Loading job uniforms for job ${jobDatabaseId} from database ...`);
+
+ let tempJobUniforms = [];
+ let dbConnection = connectToDatabase();
+ let dbQuery = null;
+ let dbAssoc;
+
+ if(dbConnection) {
+ dbQuery = queryDatabase(dbConnection, "SELECT * FROM `job_uniform` WHERE `job_uniform_enabled` = 1 AND `job_uniform_job` = " + String(jobDatabaseId));
+ if(dbQuery) {
+ if(dbQuery.numRows > 0) {
+ while(dbAssoc = fetchQueryAssoc(dbQuery)) {
+ let tempJobUniformData = new serverClasses.jobUniformData(dbAssoc);
+ tempJobUniforms.push(tempJobUniformData);
+ console.log(`[Asshat.Job]: Job uniform '${tempJobUniformData.name}' loaded from database successfully!`);
+ }
+ }
+ freeDatabaseQuery(dbQuery);
+ }
+ disconnectFromDatabase(dbConnection);
+ }
+
+ console.log(`[Asshat.Job]: ${tempJobUniforms.length} job uniforms for job ${jobDatabaseId} loaded from database successfully!`);
+ return tempJobUniforms;
+}
+
+// ---------------------------------------------------------------------------
+
+function loadJobEquipmentWeaponsFromDatabase(jobEquipmentDatabaseId) {
+ console.log(`[Asshat.Job]: Loading job equipment weapons for job equipment ${jobEquipmentDatabaseId} from database ...`);
+
+ let tempJobEquipmentWeapons = [];
+ let dbConnection = connectToDatabase();
+ let dbQuery = null;
+ let dbAssoc;
+
+ if(dbConnection) {
+ dbQuery = queryDatabase(dbConnection, "SELECT * FROM `job_equip_wep` WHERE `job_equip_wep_enabled` = 1 AND `job_equip_wep_equip` = " + String(jobEquipmentDatabaseId));
+ if(dbQuery) {
+ if(dbQuery.numRows > 0) {
+ while(dbAssoc = fetchQueryAssoc(dbQuery)) {
+ let tempJobEquipmentWeaponsData = new serverClasses.jobEquipmentWeaponData(dbAssoc);
+ tempJobEquipmentWeapons.push(tempJobEquipmentWeaponsData);
+ console.log(`[Asshat.Job]: Job equipment weapon '${tempJobEquipmentWeaponsData.name}' loaded from database successfully!`);
+ }
+ }
+ freeDatabaseQuery(dbQuery);
+ }
+ disconnectFromDatabase(dbConnection);
+ }
+
+ console.log(`[Asshat.Job]: ${tempJobEquipmentWeapons.length} job equipment weapons for equipment ${jobEquipmentDatabaseId} loaded from database successfully!`);
+ return tempJobEquipmentWeapons;
+}
+
+// ---------------------------------------------------------------------------
+
+function createAllJobBlips() {
+ for(let i in serverData.jobs) {
+ for(let j in serverData.jobs[i].locations) {
+ serverData.jobs[i].locations[j].blip = createBlip(0, serverData.jobs[i].locations[j], 2, serverConfig.colour.byName.yellow);
+
+ console.log(`[Asshat.Job] Job '${serverData.jobs[i].name}' location blip ${j} spawned!`);
+ }
+ }
+ console.log(`[Asshat.Job] All job location blips spawned!`);
}
// ---------------------------------------------------------------------------
function createAllJobPickups() {
- for(let i in serverData.jobs[getServerGame()]) {
- serverData.jobs[getServerGame()][i].pickup = gta.createPickup(serverData.jobs[getServerGame()][i].pickupModel, serverData.jobs[getServerGame()][i].position);
+ for(let i in serverData.jobs) {
+ if(serverData.jobs[i].pickupModel != 0) {
+ for(let j in serverData.jobs[i].locations) {
+ serverData.jobs[i].locations[j].pickup = createPickup(serverData.jobs[i].pickupModel, serverData.jobs[i].locations[j].position);
+ serverData.jobs[i].locations[j].pickup.setData("ag.ownerType", AG_PICKUP_JOB, true);
+ serverData.jobs[i].locations[j].pickup.setData("ag.ownerId", i, true);
- serverData.jobs[getServerGame()][i].pickup.setData("ag.ownerType", AG_PICKUP_JOB, true);
- serverData.jobs[getServerGame()][i].pickup.setData("ag.ownerId", i, true);
+ console.log(`[Asshat.Job] Job '${serverData.jobs[i].name}' location pickup ${j} spawned!`);
+ }
+ }
}
+ console.log(`[Asshat.Job] All job location pickups spawned!`);
}
// ---------------------------------------------------------------------------
@@ -173,7 +303,8 @@ function showJobInformationToPlayer(client, jobType) {
// ---------------------------------------------------------------------------
function takeJobCommand(command, params, client) {
- if(!canClientUseJobs(client)){
+ if(!canClientUseJobs(client)) {
+ messageClientError(client, "You are not allowed to use jobs!");
return false;
}
@@ -196,20 +327,20 @@ function takeJobCommand(command, params, client) {
return false;
}
- let closestJobId = getClosestJobPointId(client.player.position);
- let jobData = getJobData(closestJobId);
+ let closestJobLocation = getClosestJobLocation(client.player.position);
+ let jobData = getJobData(closestJobLocation.job);
- if(jobData.position.distance(client.player.position) > serverConfig.takeJobDistance) {
+ if(closestJobLocation.position.distance(client.player.position) > serverConfig.takeJobDistance) {
messageClientError(client, "There are no job points close enough!");
return false;
}
- if(getClientCurrentSubAccount(client).job != -1) {
+ if(getClientCurrentSubAccount(client).job != AG_JOB_NONE) {
messageClientError(client, "You already have a job! Use /quitjob to quit your job.");
return false;
}
- takeJob(client, closestJobId);
+ takeJob(client, closestJobLocation.job);
messageClientSuccess(client, "You now have the " + String(jobData.name) + " job");
return true;
}
@@ -240,10 +371,10 @@ function startWorkingCommand(command, params, client) {
return false;
}
- let closestJobId = getClosestJobPointId(client.player.position);
- let jobData = getJobData(closestJobId);
+ let closestJobLocation = getClosestJobLocation(client.player.position);
+ let jobData = getJobData(closestJobLocation.job);
- if(jobData.position.distance(client.player.position) > serverConfig.startWorkingDistance) {
+ if(closestJobLocation.position.distance(client.player.position) > serverConfig.startWorkingDistance) {
messageClientError(client, "There are no job points close enough!");
return false;
}
@@ -252,11 +383,11 @@ function startWorkingCommand(command, params, client) {
messageClientError(client, "You don't have a job!");
messageClientInfo(client, "You can get a job by going the yellow points on the map.");
return false;
- }
+ }
- if(getJobType(getClientCurrentSubAccount(client).job) != jobData.jobType) {
+ if(getClientCurrentSubAccount(client).job != closestJobLocation.job) {
messageClientError(client, "This is not your job!");
- messageClientInfo(client, `Use /quitjob to quit your current job.`);
+ messageClientInfo(client, `If you want this job, use /quitjob to quit your current job.`);
return false;
}
@@ -293,11 +424,10 @@ function stopWorkingCommand(command, params, client) {
return false;
}
- let closestJobId = getClosestJobPointId(client.player.position);
- let jobData = getJobData(closestJobId);
+ let closestJobLocation = getClosestJobLocation(client.player.position);
- if(jobData.position.distance(client.player.position) > serverConfig.stopWorkingDistance) {
- messageClientError(client, "There are no job points close enough!");
+ if(closestJobLocation.position.distance(client.player.position) > serverConfig.stopWorkingDistance) {
+ messageClientError(client, "There are no job locations close enough!");
return false;
}
@@ -363,6 +493,19 @@ function startWorking(client) {
// ---------------------------------------------------------------------------
+function givePlayerJobEquipment(client, equipmentId) {
+ if(!canClientUseJobs(client)){
+ return false;
+ }
+
+ let jobId = getClientCurrentSubAccount(client).job;
+ for(let i in serverData.jobs[jobId].equipments[equipmentId].weapons) {
+ triggerNetworkEvent("ag.giveWeapon", client, serverData.jobs[jobId].equipments[equipmentId].weapons[i].weapon, serverData.jobs[jobId].equipments[equipmentId].weapons[i].ammo, false);
+ }
+}
+
+// ---------------------------------------------------------------------------
+
function stopWorking(client) {
if(!canClientUseJobs(client)){
return false;
@@ -452,58 +595,60 @@ function jobUniformCommand(command, params, client) {
return false;
}
+ let jobId = getClientCurrentSubAccount(client).job
+
+ if(areParamsEmpty(params)) {
+ messageClientSyntax(client, getCommandSyntaxText(command));
+ messageClientNormal(`0: No uniform (sets you back to your main skin)`);
+ for(let i in serverData.jobs[jobId].uniforms) {
+ messageClientNormal(`${i+1}: ${serverData.jobs[jobId].uniforms.name} (Requires rank ${serverData.jobs[jobId].uniforms.minRank})`);
+ }
+ return false;
+ }
+
+ if(uniformId == 0) {
+ getClientCurrentSubAccount(client).jobUniform = false;
+ triggerNetworkEvent("ag.skin", client, getClientCurrentSubAccount(client).skin);
+ messageClientSuccess(client, "You changed your uniform to (none)");
+ return;
+ }
+
let uniformId = Number(params) || 1;
+ if(uniformId < 1 || uniformId > serverData.jobs[jobId].uniforms.length-1) {
+ messageClientError(client, "That uniform ID is invalid!");
+ return false;
+ }
+
+ triggerNetworkEvent("ag.skin", client, serverData.jobs[jobId].uniforms[uniformId].skin);
+}
+
+// ---------------------------------------------------------------------------
+
+function jobEquipmentCommand(command, params, client) {
+ if(doesCommandRequireLogin(command)) {
+ if(!isClientLoggedIn(client)) {
+ messageClientError(client, "You are not logged in!");
+ return false;
+ }
+ }
+
+ if(isClientFromDiscord(client)) {
+ if(!isCommandAllowedOnDiscord(command)) {
+ messageClientError(client, "That command isn't available on discord!");
+ return false;
+ }
+ }
+
+ if(!doesClientHaveStaffPermission(client, getCommandRequiredPermissions(command))) {
+ messageClientError(client, "You do not have permission to use this command!");
+ return false;
+ }
+
+ let equipmentId = Number(params) || 1;
let jobId = getClientCurrentSubAccount(client).job;
- getClientCurrentSubAccount(client).jobUniform = uniformId-1;
- switch(getJobType(jobId)) {
- case AG_JOB_POLICE:
- triggerNetworkEvent("ag.skin", client, serverData.policeJobSkins[getServerGame()][uniformId-1]);
- //client.player.modelIndex = serverData.policeJobSkins[getServerGame()][uniformId];
- triggerNetworkEvent("ag.giveWeapon", client, 2, 200, false);
- triggerNetworkEvent("ag.giveWeapon", client, 1, 1, false);
- break;
-
- case AG_JOB_MEDICAL:
- triggerNetworkEvent("ag.skin", client, serverData.medicalJobSkins[getServerGame()][uniformId-1]);
- //client.player.modelIndex = serverData.medicalJobSkins[getServerGame()][uniformId];
- messageClientInfo(client, "Your uniform and ambulance have been returned to the hospital");
- break;
-
- case AG_JOB_FIRE:
- triggerNetworkEvent("ag.skin", client, serverData.fireJobSkins[getServerGame()][uniformId-1]);
- //client.player.modelIndex = serverData.fireJobSkins[getServerGame()][uniformId];
- messageClientInfo(client, "Your uniform and fire truck have been returned to the fire station");
- break;
-
- case AG_JOB_BUS:
- triggerNetworkEvent("ag.skin", client, serverData.busJobSkins[getServerGame()][uniformId-1]);
- //client.player.modelIndex = serverData.busJobSkins[getServerGame()][uniformId];
- messageClientInfo(client, "Your bus has been returned to the bus depot");
- break;
-
- case AG_JOB_TAXI:
- triggerNetworkEvent("ag.skin", client, serverData.taxiJobSkins[getServerGame()][uniformId-1]);
- //client.player.modelIndex = serverData.taxiJobSkins[getServerGame()][uniformId];
- messageClientInfo(client, "Your taxi has been returned to the taxi depot");
- break;
-
- case AG_JOB_GARBAGE:
- triggerNetworkEvent("ag.skin", client, serverData.garbageJobSkins[getServerGame()][uniformId-1]);
- //client.player.modelIndex = serverData.garbageJobSkins[getServerGame()][uniformId];
- messageClientInfo(client, "Your trash truck has been returned to the city landfill");
- break;
-
- case AG_JOB_WEAPON:
- break;
-
- case AG_JOB_DRUG:
- break;
-
- default:
- break;
- }
+ givePlayerJobEquipment(client, equipmentId);
}
// ---------------------------------------------------------------------------
@@ -556,7 +701,7 @@ function jobRadioCommand(command, params, client) {
messageClientError(client, "That command isn't available on discord!");
return false;
}
- }
+ }
if(!doesClientHaveStaffPermission(client, getCommandRequiredPermissions(command))) {
messageClientError(client, "You do not have permission to use this command!");
@@ -598,13 +743,18 @@ function jobDepartmentRadioCommand(command, params, client) {
// ---------------------------------------------------------------------------
function getJobType(jobId) {
- return getJobData(jobId).jobType;
+ return getJobData(jobId).type;
}
// ---------------------------------------------------------------------------
function getJobData(jobId) {
- return serverData.jobs[getServerGame()][jobId];
+ for(let i in serverData.jobs) {
+ if(serverData.jobs[i].databaseId == jobId) {
+ return serverData.jobs[i];
+ }
+ }
+ return false;
}
// ---------------------------------------------------------------------------
diff --git a/scripts/server/misc.js b/scripts/server/misc.js
index d867aa9e..70474d1c 100644
--- a/scripts/server/misc.js
+++ b/scripts/server/misc.js
@@ -157,13 +157,157 @@ function toggleServerLogoCommand(command, params, client) {
}
let splitParams = params.split();
- let logoState = Number(splitParams[0]) || 1;
+ let logoState = Number(params) || 1;
serverConfig.useLogo = !!logoState;
- messageAdminAction(`${client.name} turned the server logo image ${getOnOffFromBool(intToBool(fallingSnow))}`);
+ messageAdminAction(`${client.name} turned the server logo image ${getOnOffFromBool(!!logoState).toLowerCase()}`);
updateServerRules();
return true;
}
+// ---------------------------------------------------------------------------
+
+function getPositionCommand(command, params, client) {
+ if(getCommand(command).requireLogin) {
+ if(!isClientLoggedIn(client)) {
+ messageClientError(client, "You must be logged in to use this command!");
+ return false;
+ }
+ }
+
+ if(!doesClientHaveStaffPermission(client, getCommandRequiredPermissions(command))) {
+ messageClientError(client, "You do not have permission to use this command!");
+ return false;
+ }
+
+ let position = client.player.position;
+
+ messageClientNormal(client, `Your position is: ${position.x.toFixed(2)}, ${position.y.toFixed(2)}, ${position.z.toFixed(2)}`);
+ console.log(`Position: ${position.x.toFixed(2)}, ${position.y.toFixed(2)}, ${position.z.toFixed(2)}`);
+ return true;
+}
+
+// ---------------------------------------------------------------------------
+
+function setNewCharacterSpawnPositionCommand(command, params, client) {
+ if(getCommand(command).requireLogin) {
+ if(!isClientLoggedIn(client)) {
+ messageClientError(client, "You must be logged in to use this command!");
+ return false;
+ }
+ }
+
+ if(!doesClientHaveStaffPermission(client, getCommandRequiredPermissions(command))) {
+ messageClientError(client, "You do not have permission to use this command!");
+ return false;
+ }
+
+ let position = client.player.position;
+ serverConfig.newCharacter.spawnPosition = position;
+ serverConfig.newCharacter.spawnHeading = client.player.heading;
+
+ messageClientNormal(client, `The new character spawn position has been set to ${position.x.toFixed(2)}, ${position.y.toFixed(2)}, ${position.z.toFixed(2)}`)
+ return true;
+}
+
+// ---------------------------------------------------------------------------
+
+function setNewCharacterMoneyCommand(command, params, client) {
+ if(getCommand(command).requireLogin) {
+ if(!isClientLoggedIn(client)) {
+ messageClientError(client, "You must be logged in to use this command!");
+ return false;
+ }
+ }
+
+ if(!doesClientHaveStaffPermission(client, getCommandRequiredPermissions(command))) {
+ messageClientError(client, "You do not have permission to use this command!");
+ return false;
+ }
+
+ if(areParamsEmpty(params)) {
+ messageClientSyntax(client, getCommandSyntaxText(command));
+ return false;
+ }
+
+ let splitParams = params.split();
+ let amount = Number(splitParams[0]) || 1000;
+
+ serverConfig.newCharacter.cash = skinId;
+
+ messageClientNormal(client, `The new character money has been set to $${amount}`);
+ return true;
+}
+
+// ---------------------------------------------------------------------------
+
+function setNewCharacterSkinCommand(command, params, client) {
+ if(getCommand(command).requireLogin) {
+ if(!isClientLoggedIn(client)) {
+ messageClientError(client, "You must be logged in to use this command!");
+ return false;
+ }
+ }
+
+ if(!doesClientHaveStaffPermission(client, getCommandRequiredPermissions(command))) {
+ messageClientError(client, "You do not have permission to use this command!");
+ return false;
+ }
+
+ let skinId = 0;
+ if(areParamsEmpty(params)) {
+ skinId = client.player.modelIndex;
+ } else {
+ skinId = getSkinFromParams(params);
+ }
+
+ serverConfig.newCharacter.skin = skinId;
+
+ messageClientNormal(client, `The new character skin has been set to ${getSkinNameFromId(skinId)} (ID ${skinId})`);
+ return true;
+}
+
+// ---------------------------------------------------------------------------
+
+function submitIdeaCommand(command, params, client) {
+ if(getCommand(command).requireLogin) {
+ if(!isClientLoggedIn(client)) {
+ messageClientError(client, "You must be logged in to use this command!");
+ return false;
+ }
+ }
+
+ if(!doesClientHaveStaffPermission(client, getCommandRequiredPermissions(command))) {
+ messageClientError(client, "You do not have permission to use this command!");
+ return false;
+ }
+
+ submitIdea(client, params);
+
+ messageClientNormal(client, `Your suggestion/idea has been sent to the developers!`);
+ return true;
+}
+
+// ---------------------------------------------------------------------------
+
+function submitBugCommand(command, params, client) {
+ if(getCommand(command).requireLogin) {
+ if(!isClientLoggedIn(client)) {
+ messageClientError(client, "You must be logged in to use this command!");
+ return false;
+ }
+ }
+
+ if(!doesClientHaveStaffPermission(client, getCommandRequiredPermissions(command))) {
+ messageClientError(client, "You do not have permission to use this command!");
+ return false;
+ }
+
+ submitBugReport(client, params);
+
+ messageClientNormal(client, `Your bug report has been sent to the developers!`);
+ return true;
+}
+
// ---------------------------------------------------------------------------
\ No newline at end of file
diff --git a/scripts/server/test.005 b/scripts/server/test.005
new file mode 100644
index 00000000..25358e71
--- /dev/null
+++ b/scripts/server/test.005
@@ -0,0 +1 @@
+1632.49, -2331.96, 13.547], -0.005
\ No newline at end of file
diff --git a/scripts/server/test.sql b/scripts/server/test.sql
new file mode 100644
index 00000000..e69de29b
diff --git a/scripts/server/test.txt b/scripts/server/test.txt
new file mode 100644
index 00000000..e69de29b
diff --git a/scripts/server/utilities.js b/scripts/server/utilities.js
index eea6fd71..4c835ed4 100644
--- a/scripts/server/utilities.js
+++ b/scripts/server/utilities.js
@@ -2811,11 +2811,13 @@ function getClosestJobPoint(position) {
// ---------------------------------------------------------------------------
-function getClosestJobPointId(position) {
+function getClosestJobLocationId(position) {
let closestJob = 0;
- for(let i in serverData.jobs[getServerGame()]) {
- if(serverData.jobs[getServerGame()][i].position.distance(position) < serverData.jobs[getServerGame()][closestJob].position.distance(position)) {
- closestJob = i;
+ for(let i in serverData.jobs) {
+ for(let j in serverData.jobs[i].locations) {
+ if(serverData.jobs[i].locations[j].position.distance(position) < serverData.jobs[closestJob].position.distance(position)) {
+ closestJob = i;
+ }
}
}
return closestJob;
@@ -2824,19 +2826,21 @@ function getClosestJobPointId(position) {
// ---------------------------------------------------------------------------
function getJobIndex(jobData) {
- return serverData.jobs[getServerGame()].indexOf(jobData);
+ return serverData.jobs.indexOf(jobData);
}
// ---------------------------------------------------------------------------
function getVehiclesInRange(position, distance) {
- return getElementsByType(ELEMENT_VEHICLE).filter(x => x.position.distance(position) <= distance);
+ return getElementsByType(ELEMENT_VEHICLE).filter(x => x.player && x.position.distance(position) <= distance);
}
// ---------------------------------------------------------------------------
function getClientsInRange(position, distance) {
- return getClients().filter(x => x.player.position.distance(position) <= distance);
+ //return getClients().filter(x => x.player && x.player.position.distance(position) <= distance);
+
+ return getElementsByTypeInRange(ELEMENT_PLAYER, position, distance);
}
// ---------------------------------------------------------------------------
@@ -3033,27 +3037,18 @@ function getClientFromPlayer(player) {
// ---------------------------------------------------------------------------
function getPlayerFromParams(params, isServer) {
- if(!isServer) {
- let peds = getPeds();
- for(let i in peds) {
- if(peds[i].name.toLowerCase().indexOf(params.toLowerCase()) != -1) {
- return peds[i];
- }
- }
- } else {
- let clients = getClients();
- if(isNaN(params)) {
- for(let i in clients) {
- if(clients[i].name.toLowerCase().indexOf(params.toLowerCase()) != -1) {
- return clients[i].player;
- }
- }
- } else {
- let playerId = Number(params) || 0;
- if(typeof clients[playerId] != "undefined") {
- return clients[playerId].player;
+ let clients = getClients();
+ if(isNaN(params)) {
+ for(let i in clients) {
+ if(clients[i].name.toLowerCase().indexOf(params.toLowerCase()) != -1) {
+ return clients[i].player;
}
}
+ } else {
+ let playerId = Number(params) || 0;
+ if(typeof clients[playerId] != "undefined") {
+ return clients[playerId].player;
+ }
}
return false;
@@ -3062,28 +3057,27 @@ function getPlayerFromParams(params, isServer) {
// ---------------------------------------------------------------------------
-function getClientFromParams(params) {
- if(typeof server == "undefined") {
- let clients = getClients();
+function getClientFromParams(checkParams) {
+ console.log(checkParams);
+ let clients = getClients();
+ if(isNaN(checkParams)) {
+ console.log(`Checking string name`);
+ checkParams = checkParams.toLowerCase();
for(let i in clients) {
- if(clients[i].name.toLowerCase().indexOf(params.toLowerCase()) != -1) {
+ let clientName = clients[i].name.toLowerCase();
+ console.log(`Checking ${clientName}`);
+ if(clientName.indexOf(checkParams) != -1) {
+ console.log(`Found ${clients[i].name}`);
return clients[i];
}
}
} else {
- let clients = getClients();
- if(isNaN(params)) {
- for(let i in clients) {
- if(clients[i].name.toLowerCase().indexOf(params.toLowerCase()) != -1) {
- return clients[i];
- }
- }
- } else {
- let clientId = Number(params) || 0;
- if(typeof clients[clientId] != "undefined") {
- return clients[clientId];
- }
- }
+ console.log(`Checking int ID`);
+ let clientId = Number(checkParams) || 0;
+ if(typeof clients[clientId] != "undefined") {
+ console.log(`Found ${clients[i].name}`);
+ return clients[clientId];
+ }
}
return false;
@@ -3453,6 +3447,7 @@ function getGameAreas(gameId) {
// ---------------------------------------------------------------------------
function getClientData(client) {
+ console.log(serverData.clients[client.index]);
return serverData.clients[client.index];
}
@@ -3842,6 +3837,18 @@ function getYesNoFromBool(boolVal) {
// ---------------------------------------------------------------------------
+function getOnOffFromBool(boolVal) {
+ return (boolVal) ? "On" : "Off";
+}
+
+// ---------------------------------------------------------------------------
+
+function getEnabledDisabledFromBool(boolVal) {
+ return (boolVal) ? "Enabled" : "Disabled";
+}
+
+// ---------------------------------------------------------------------------
+
function updateServerRules() {
server.setRule("Time", makeReadableTime(serverConfig.hour, serverConfig.minute));
server.setRule("Weather", gameData.weatherNames[server.game][serverConfig.weather]);
@@ -3882,4 +3889,56 @@ function clearChatBox(client) {
}
}
+// ---------------------------------------------------------------------------
+
+function getSkinIdFromParams(params, gameId = server.game) {
+ if(isNaN(params)) {
+ return getSkinIdFromName(params, gameId);
+ } else {
+ params = Number(params);
+ if(gameId == GAME_GTA_IV || gameId == GAME_GTA_IV_EFLC) {
+ return gameData.gtaivSkinModels[params][1];
+ } else {
+ return params;
+ }
+ }
+
+ return false;
+}
+
+// ---------------------------------------------------------------------------
+
+function getSkinNameFromId(modelId, gameId = server.game) {
+ if(gameId >= GAME_GTA_IV) {
+ for(let i in gameData.gtaivSkinModels) {
+ if(gameData.gtaivSkinModels[i][1] == modelId) {
+ return gameData.gtaivSkinModels[i][0];
+ }
+ }
+ } else {
+ let modelIndex = modelId;
+ return gameData.skinNames[gameId][modelIndex];
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+function getSkinIdFromName(params, gameId = server.game) {
+ if(gameId == GAME_GTA_IV || gameId == GAME_GTA_IV_EFLC) {
+ for(let i in gtaivSkinModels) {
+ if(gameData.gtaivSkinModels[i][0].toLowerCase().indexOf(params.toLowerCase()) != -1) {
+ return gameData.gtaivSkinModels[i][1];You
+ }
+ }
+ } else {
+ for(let i in gameData.skinNames[gameId]) {
+ if(gameData.skinNames[gameId][i].toLowerCase().indexOf(params.toLowerCase()) != -1) {
+ return i;
+ }
+ }
+ }
+
+ return false;
+}
+
// ---------------------------------------------------------------------------
\ No newline at end of file
diff --git a/scripts/server/vehicle.js b/scripts/server/vehicle.js
index e5206289..1da6eaae 100644
--- a/scripts/server/vehicle.js
+++ b/scripts/server/vehicle.js
@@ -73,6 +73,11 @@ function saveVehicleToDatabase(vehicleData) {
console.log(`[Asshat.Vehicle]: Saving vehicles ${vehicleData.vehicle.id} to database ...`);
let dbConnection = connectToDatabase();
if(dbConnection) {
+ if(!vehicleData.spawnLocked) {
+ vehicleData.spawnPosition = vehicle.position;
+ vehicleData.spawnRotation = vehicle.heading;
+ }
+
// If vehicle hasn't been added to database, ID will be 0
if(vehicleData.databaseId == 0) {
let dbQueryString = `INSERT INTO veh_main (veh_model, veh_pos_x, veh_pos_y, veh_pos_z, veh_rot_z, veh_owner_type, veh_owner_id, veh_col1, veh_col2, veh_col3, veh_col4, veh_server) VALUES (${vehicleData.model}, ${vehicleData.spawnPosition.x}, ${vehicleData.spawnPosition.y}, ${vehicleData.spawnPosition.z}, ${vehicleData.spawnRotation}, ${vehicleData.ownerType}, ${vehicleData.ownerId}, ${vehicleData.colour1}, ${vehicleData.colour2}, ${vehicleData.colour3}, ${vehicleData.colour4}, ${serverId})`;
@@ -131,7 +136,10 @@ function spawnAllVehicles() {
function getVehicleData(vehicle) {
let dataIndex = vehicle.getData("ag.dataSlot");
- return serverData.vehicles[dataIndex];
+ if(typeof serverData.vehicles[dataIndex] != "undefined") {
+ return serverData.vehicles[dataIndex];
+ }
+ return false;
}
// ---------------------------------------------------------------------------
@@ -713,14 +721,93 @@ function toggleVehicleSpawnLockCommand(command, params, client) {
let vehicle = client.player.vehicle;
- if(!getVehicleData(vehicle).spawnLocked) {
+ let spawnLocked = getVehicleData(vehicle).spawnLocked;
+ getVehicleData(vehicle).spawnLocked = !spawnLocked;
+ if(spawnLocked) {
getVehicleData(vehicle).spawnPosition = vehicle.position;
getVehicleData(vehicle).spawnRotation = vehicle.heading;
+ }
+
+ messageClientInfo(client, `This vehicle will now spawn ${(spawnLocked) ? "here" : "wherever a player leaves it."}`);
+}
+
+// ---------------------------------------------------------------------------
+
+function reloadAllVehiclesCommand(command, params, client) {
+ if(getCommand(command).requireLogin) {
+ if(!isClientLoggedIn(client)) {
+ messageClientError(client, "You must be logged in to use this command!");
+ return false;
+ }
}
- getVehicleData(vehicle).spawnLocked = !getVehicleData(vehicle).spawnLocked
+ if(isClientFromDiscord(client)) {
+ if(!isCommandAllowedOnDiscord(command)) {
+ messageClientError(client, "That command isn't available on discord!");
+ return false;
+ }
+ }
- messageClientInfo(client, `This vehicle will now spawn ${(getVehicleData(vehicle).spawnLocked) ? "here" : "wherever a player leaves it."}`);
+ if(!doesClientHaveStaffPermission(client, getCommandRequiredPermissions(command))) {
+ messageClientError(client, "You do not have permission to use this command!");
+ return false;
+ }
+
+ if(!client.player.vehicle) {
+ messageClientError(client, "You need to be in a vehicle!");
+ return false;
+ }
+
+ for(let i in serverData.vehicles) {
+ if(serverData.vehicles[i].vehicle) {
+ destroyElement(serverData.vehicles[i].vehicle);
+ }
+ }
+
+ serverData.vehicles = null;
+ serverData.vehicles = loadVehiclesFromDatabase();
+ spawnAllVehicles();
+
+ messageAdminAction(`All server vehicles have been reloaded by an admin!`);
+}
+
+// ---------------------------------------------------------------------------
+
+function respawnAllVehiclesCommand(command, params, client) {
+ if(getCommand(command).requireLogin) {
+ if(!isClientLoggedIn(client)) {
+ messageClientError(client, "You must be logged in to use this command!");
+ return false;
+ }
+ }
+
+ if(isClientFromDiscord(client)) {
+ if(!isCommandAllowedOnDiscord(command)) {
+ messageClientError(client, "That command isn't available on discord!");
+ return false;
+ }
+ }
+
+ if(!doesClientHaveStaffPermission(client, getCommandRequiredPermissions(command))) {
+ messageClientError(client, "You do not have permission to use this command!");
+ return false;
+ }
+
+ if(!client.player.vehicle) {
+ messageClientError(client, "You need to be in a vehicle!");
+ return false;
+ }
+
+ for(let i in serverData.vehicles) {
+ if(serverData.vehicles[i].vehicle) {
+ destroyElement(serverData.vehicles[i].vehicle);
+ serverData.vehicles[i].vehicle = null;
+ }
+ }
+
+ spawnAllVehicles();
+
+ messageAdminAction(`All server vehicles have been respawned by an admin!`);
}
// ---------------------------------------------------------------------------
@@ -742,4 +829,16 @@ function sendAllVehiclesToClient(client) {
*/
}
+// ---------------------------------------------------------------------------
+
+function getVehicleDataFromIVSyncId(syncId) {
+ for(let i in serverData.vehicles) {
+ if(serverData.vehicles[i].ivSyncId != -1) {
+ if(serverData.vehicles[i].ivSyncId == syncId) {
+ return serverData.vehicles[i];
+ }
+ }
+ }
+}
+
// ---------------------------------------------------------------------------
\ No newline at end of file