diff --git a/TODO.md b/TODO.md
new file mode 100644
index 00000000..f1f72f5f
--- /dev/null
+++ b/TODO.md
@@ -0,0 +1,5 @@
+* Custom key binds
+* Ice cream job
+ * VC: -862.39, -578.35, 11.10
+
+* Messaging commands - player position util
\ No newline at end of file
diff --git a/meta.xml b/meta.xml
index 804f083e..10b28fcd 100644
--- a/meta.xml
+++ b/meta.xml
@@ -1,6 +1,12 @@
+
+
+
+
+
+
@@ -24,8 +30,10 @@
+
+
@@ -63,9 +71,10 @@
-
+
+
diff --git a/scripts/client/gui.js b/scripts/client/gui.js
index dc907207..e012e93e 100644
--- a/scripts/client/gui.js
+++ b/scripts/client/gui.js
@@ -141,7 +141,7 @@ let skinNames = [
[58, "Delivery Guy", "Skin058.png"],
[59, "Business Man", "Skin059.png"],
[60, "Marty Chonks", "Skin060.png"],
- [61, "Cia Agent", "Skin061.png"],
+ [61, "CIA Agent", "Skin061.png"],
[62, "Female Client", "Skin062.png"],
[63, "Young Woman", "Skin063.png"],
[64, "Business Woman", "Skin064.png"],
@@ -203,12 +203,12 @@ let skinNames = [
],
[ // GTA Vice City
[0, "Tommy Vercetti", false],
- [1, "Police Officer", false],
- [2, "SWAT Officer", false],
- [3, "FBI Agent", false],
- [4, "Army Soldier", false],
- [5, "Paramedic", false],
- [6, "Fireman", false],
+ //[1, "Police Officer", false],
+ //[2, "SWAT Officer", false],
+ //[3, "FBI Agent", false],
+ //[4, "Army Soldier", false],
+ //[5, "Paramedic", false],
+ //[6, "Fireman", false],
[7, "Golfer", false],
[8, "INVALID", false],
[9, "Random Lady", false],
@@ -293,18 +293,18 @@ let skinNames = [
[88, "Shark", false],
[89, "Diaz Guy", false],
[90, "Diaz Guy", false],
- [91, "Security Guard", false],
- [92, "Security Guard", false],
+ //[91, "Security Guard", false],
+ //[92, "Security Guard", false],
[93, "Biker", false],
[94, "Biker", false],
[95, "Vercetti Guy", false],
[96, "Vercetti Guy", false],
- [97, "Undercover Cop", false],
- [98, "Undercover Cop", false],
- [99, "Undercover Cop", false],
- [100, "Undercover Cop ", false],
- [101, "Undercover Cop", false],
- [102, "Undercover Cop", false],
+ //[97, "Undercover Cop", false],
+ //[98, "Undercover Cop", false],
+ //[99, "Undercover Cop", false],
+ //[100, "Undercover Cop ", false],
+ //[101, "Undercover Cop", false],
+ //[102, "Undercover Cop", false],
[103, "Random Guy", false],
[104, "Bodyguard", false],
[105, "Prostitute", false],
@@ -322,7 +322,7 @@ let skinNames = [
[117, "Mercedes", false],
[118, "Love Fist", false],
[119, "Alex Scrub", false],
- [120, "Officer Lance Vance", false],
+ //[120, "Officer Lance Vance", false],
[121, "Lance Vance", false],
[122, "Cortez", false],
[123, "SWAT 2", false],
@@ -368,7 +368,7 @@ let skinNames = [
[163, "Tommy Vercetti (SpandEx Overalls)", false],
[164, "Tommy Vercetti (Golfer)", false],
[165, "Tommy Vercetti (Cuban)", false],
- [166, "Tommy Vercetti (Cop)", false],
+ //[166, "Tommy Vercetti (Cop)", false],
[167, "Tommy Vercetti (Robbery Suit)", false],
[168, "Tommy Vercetti (T-Shirt and Jeans)", false],
[169, "Tommy Vercetti (Striped Suit)", false],
@@ -393,11 +393,11 @@ let skinNames = [
],
[ // GTA San Andreas
- [0, "Carl 'CJ' Johnson", false],
+ //[0, "Carl 'CJ' Johnson", false],
[1, "The Truth", false],
[2, "Maccer", false],
[3, "Andre", false],
- [4, "Barry 'Big Bear' Thorne", false],
+ [4, "Barry Big Bear Thorne", false],
[5, "Emmet", false],
[6, "Taxi Driver/Train Driver", false],
[7, "Janitor", false],
@@ -413,7 +413,7 @@ let skinNames = [
[17, "Businessman", false],
[18, "Beach Visitor", false],
[19, "DJ", false],
- [20, "Rich Guy (Madd Dogg's Manager)", false],
+ [20, "Rich Guy (Madd Doggs Manager)", false],
[21, "Normal Ped", false],
[22, "Normal Ped", false],
[23, "Bmxer", false],
@@ -558,9 +558,9 @@ let skinNames = [
[162, "Hillbilly", false],
[163, "Black Bouncer", false],
[164, "White Bouncer", false],
- [165, "White Mib Agent", false],
- [166, "Black Mib Agent", false],
- [167, "Cluckin' Bell Worker", false],
+ [165, "White MIB Agent", false],
+ [166, "Black MIB Agent", false],
+ [167, "Cluckin Bell Worker", false],
[168, "Hotdog/Chilli Dog Vendor", false],
[169, "Normal Ped", false],
[170, "Normal Ped", false],
@@ -658,43 +658,43 @@ let skinNames = [
[262, "Cab Driver", false],
[263, "Normal Ped", false],
[264, "Clown (Ice-Cream Van Driver)", false],
- [265, "Officer Frank Tenpenny", false],
- [266, "Officer Eddie Pulaski", false],
- [267, "Officer Jimmy Hernandez", false],
+ //[265, "Officer Frank Tenpenny", false],
+ //[266, "Officer Eddie Pulaski", false],
+ //[267, "Officer Jimmy Hernandez", false],
[268, "Dwaine/Dwayne", false],
- [269, "Melvin 'Big Smoke' Harris (Mission)", false],
- [270, "Sean 'Sweet' Johnson", false],
- [271, "Lance 'Ryder' Wilson", false],
+ [269, "Melvin Big Smoke Harris (Mission)", false],
+ [270, "Sean Sweet Johnson", false],
+ [271, "Lance Ryder Wilson", false],
[272, "Mafia Boss", false],
[273, "T-Bone Mendez", false],
- [274, "Paramedic", false],
- [275, "Paramedic", false],
- [276, "Paramedic", false],
- [277, "Firefighter", false],
- [278, "Firefighter", false],
- [279, "Firefighter", false],
- [280, "Los Santos Police Officer", false],
- [281, "San Fierro Police Officer", false],
- [282, "Las Venturas Police Officer", false],
- [283, "County Sheriff", false],
- [284, "Motorbike Cop", false],
- [285, "S.W.A.T.", false],
- [286, "Federal Agent", false],
- [287, "Army Soldier", false],
- [288, "Desert Sheriff", false],
+ //[274, "Paramedic", false],
+ //[275, "Paramedic", false],
+ //[276, "Paramedic", false],
+ //[277, "Firefighter", false],
+ //[278, "Firefighter", false],
+ //[279, "Firefighter", false],
+ //[280, "Los Santos Police Officer", false],
+ //[281, "San Fierro Police Officer", false],
+ //[282, "Las Venturas Police Officer", false],
+ //[283, "County Sheriff", false],
+ //[284, "Motorbike Cop", false],
+ //[285, "S.W.A.T.", false],
+ //[286, "Federal Agent", false],
+ //[287, "Army Soldier", false],
+ //[288, "Desert Sheriff", false],
[289, "Zero", false],
[290, "Ken Rosenberg", false],
[291, "Kent Paul", false],
[292, "Cesar Vialpando", false],
- [293, "Jeffery 'Og Loc' Martin/Cross", false],
+ [293, "Jeffery Og Loc Martin/Cross", false],
[294, "Wu Zi Mu (Woozie)", false],
[295, "Michael Toreno", false],
[296, "Jizzy B.", false],
[297, "Madd Dogg", false],
[298, "Catalina", false],
[299, "Claude Speed", false],
- [300, "Lance 'Ryder' Wilson", false],
- [301, "Lance 'Ryder' Wilson (robbery mask)", false],
+ [300, "Lance Ryder Wilson", false],
+ [301, "Lance Ryder Wilson (robbery mask)", false],
[302, "Emmet", false],
[303, "Unknown", false],
[304, "Denise", false],
@@ -703,10 +703,10 @@ let skinNames = [
[307, "T-Bone Mendez", false],
[308, "Forelli", false],
[309, "Mechanic", false],
- [310, "Barry 'Big Bear' Thorne (Skinny)", false],
- [311, "Melvin 'Big Smoke' Harris (Vest)", false],
- [312, "Army Guy", false],
- [313, "Barry 'Big Bear' Thorne (Fat)", false],
+ [310, "Barry Big Bear Thorne (Skinny)", false],
+ [311, "Melvin Big Smoke Harris (Vest)", false],
+ //[312, "Army Guy", false],
+ [313, "Barry Big Bear Thorne (Fat)", false],
],
false,
[
@@ -1095,7 +1095,7 @@ app.init = function()
textColour: toColour(0, 0, 0, 0),
}
});
- login.window.titleBarIconSize = new Vec2(0,0);
+ login.window.titleBarIconSize = toVector2(0,0);
login.window.titleBarHeight = 0;
login.logoImage = login.window.image(100, 20, 100, 100, "files/images/main-logo.png");
@@ -1157,6 +1157,7 @@ app.init = function()
textAlign: 0.5,
},
}, showRegistration);
+ console.log("LOGIN WINDOW ADDED");
// ---------------------------------------------------------------------------------
@@ -1324,7 +1325,7 @@ app.init = function()
newCharacter.skinImage.remove();
}
if(gta.game == GAME_GTA_III) {
- newCharacter.skinImage = newCharacter.window.image(265, 30, 110, 70, "files/images/skins/gta3/" + skinImagePath.toString());
+ newCharacter.skinImage = newCharacter.window.image(265, 30, 110, 70, "files/images/skins/gta3/" + toString(skinImagePath));
} else {
newCharacter.skinImage = newCharacter.window.image(265, 30, 110, 70, "files/images/skins/none.png");
}
@@ -1347,7 +1348,8 @@ app.init = function()
textFont: robotoFont,
textAlign: 0.5,
},
- }, checkNewCharacter);
+ }, checkNewCharacter);
+ console.log("NEWCHAR WINDOW ADDED");
// ---------------------------------------------------------------------------------
@@ -1366,7 +1368,7 @@ app.init = function()
backgroundColour: toColour(primaryColour[0], primaryColour[1], primaryColour[2], windowTitleAlpha),
}
});
- register.window.titleBarIconSize = new Vec2(0,0);
+ register.window.titleBarIconSize = toVector2(0,0);
register.window.titleBarHeight = 0;
register.window.image(115, 10, 65, 65, "files/images/main-logo.png");
@@ -1677,8 +1679,6 @@ app.init = function()
characterSelect.skinImage = characterSelect.window.image(265, 30, 130, 85, "files/images/skins/gta3/Skin000.png");
// ---------------------------------------------------------------------------
-
- closeAllWindows();
};
@@ -1734,7 +1734,7 @@ let checkNewCharacter = function() {
triggerNetworkEvent("ag.checkNewCharacter",
newCharacter.firstNameInput.lines[0],
newCharacter.lastNameInput.lines[0],
- String(String(newCharacter.dateOfBirth.day) + "/" + String(newCharacter.dateOfBirth.month) + "/" + String(newCharacter.dateOfBirth.year)),
+ toString(toString(newCharacter.dateOfBirth.day) + "/" + toString(newCharacter.dateOfBirth.month) + "/" + toString(newCharacter.dateOfBirth.year)),
placesOfOrigin[newCharacter.placeOfOrigin.selectedEntryIndex],
skinNames[gta.game][newCharacter.skinDropDown.selectedEntryIndex][0],
);
@@ -1828,14 +1828,13 @@ let showCharacterSelect = function(firstName, lastName, placeOfOrigin, dateOfBir
mexui.setInput(true);
characterSelect.nameText.text = lastName + ", " + firstName;
- characterSelect.dateOfBirthText.text = "Born: " + String(dateOfBirth);
- characterSelect.placeOfOrigin.text = "From: " + String(placeOfOrigin);
+ characterSelect.dateOfBirthText.text = "Born: " + toString(dateOfBirth);
+ characterSelect.placeOfOrigin.text = "From: " + toString(placeOfOrigin);
if(characterSelect.skinImage != null) {
characterSelect.skinImage.remove();
}
- console.log(skinId);
let skinImagePath = "Skin000.png";
for(let i in skinNames[gta.game]) {
if(skinNames[gta.game][i][0] == skinId) {
@@ -1843,7 +1842,7 @@ let showCharacterSelect = function(firstName, lastName, placeOfOrigin, dateOfBir
}
}
- characterSelect.skinImage = characterSelect.window.image(265, 30, 130, 85, "files/images/skins/gta3/" + String(skinImagePath));
+ characterSelect.skinImage = characterSelect.window.image(265, 30, 130, 85, "files/images/skins/gta3/" + toString(skinImagePath));
characterSelect.window.shown = true;
}
@@ -1910,15 +1909,13 @@ let switchCharacterSelect = function(firstName, lastName, placeOfOrigin, dateOfB
setChatWindowEnabled(false);
characterSelect.window.shown = false;
characterSelect.nameText.text = lastName + ", " + firstName;
- characterSelect.dateOfBirthText.text = "Born: " + String(dateOfBirth);
- characterSelect.placeOfOrigin.text = "From: " + String(placeOfOrigin);
+ characterSelect.dateOfBirthText.text = "Born: " + toString(dateOfBirth);
+ characterSelect.placeOfOrigin.text = "From: " + toString(placeOfOrigin);
if(characterSelect.skinImage != null) {
characterSelect.skinImage.remove();
}
- console.log(skinId);
-
let skinImagePath = "Skin000.png";
for(let i in skinNames[gta.game]) {
if(skinNames[gta.game][i][0] == skinId) {
@@ -1926,19 +1923,20 @@ let switchCharacterSelect = function(firstName, lastName, placeOfOrigin, dateOfB
}
}
- characterSelect.skinImage = characterSelect.window.image(265, 30, 130, 85, "files/images/skins/gta3/" + String(skinImagePath));
+ characterSelect.skinImage = characterSelect.window.image(265, 30, 130, 85, "files/images/skins/gta3/" + toString(skinImagePath));
characterSelect.window.shown = true;
}
// ---------------------------------------------------------------------------
bindEventHandler("OnResourceReady", thisResource, function(event, resource) {
- app.init();
+
});
// ---------------------------------------------------------------------------
addNetworkHandler("ag.showLogin", function() {
+ console.log("SHOWING LOGIN");
showLogin();
});
@@ -1957,6 +1955,7 @@ addNetworkHandler("ag.showNewCharacter", function() {
// ---------------------------------------------------------------------------
addNetworkHandler("ag.showCharacterSelect", function(firstName, lastName, placeOfOrigin, dateOfBirth, skinId) {
+ console.log("SHOWING CHAR SELECT");
showCharacterSelect(firstName, lastName, placeOfOrigin, dateOfBirth, skinId);
});
@@ -1975,6 +1974,7 @@ addNetworkHandler("ag.showError", function(errorMessage, errorTitle) {
// ---------------------------------------------------------------------------
addNetworkHandler("ag.showPrompt", function(promptMessage, promptTitle) {
+ console.log("SHOWING PROMPT");
showYesNo(promptMessage, promptTitle);
});
@@ -2017,9 +2017,12 @@ addNetworkHandler("ag.registrationFailed", function(errorMessage) {
// ---------------------------------------------------------------------------
-addNetworkHandler("ag.guiColour", function(red, blue, green) {
- console.log(`NEW GUI COLOURS: ${red}, ${green}, ${blue}`);
- primaryColour = [red, blue, green];
+addNetworkHandler("ag.guiColour", function(red, green, blue) {
+ console.log("NEW GUI COLOURS");
+ primaryColour = [red, green, blue];
+ app.init();
+ console.log("APP INIT");
+ closeAllWindows();
});
// ---------------------------------------------------------------------------
\ No newline at end of file
diff --git a/scripts/client/iv.js b/scripts/client/iv.js
index d7538102..7c23a511 100644
--- a/scripts/client/iv.js
+++ b/scripts/client/iv.js
@@ -10,21 +10,45 @@
// ---------------------------------------------------------------------------
+let syncPosition = false;
+
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(gta.game == GAME_GTA_IV) {
+ getVehicles().forEach(function(vehicle) {
+ if(vehicle.isSyncer && vehicle.getData("ag.syncId") != null) {
+ triggerNetworkEvent("ag.veh.sync", vehicle.getData("ag.syncId"), vehicle.position, vehicle.heading.toFixed(2));
+ }
+ });
+
+ if(localPlayer != null && syncPosition) {
+ if(localPlayer.health <= 0) {
+ triggerNetworkEvent("ag.player.death", localPlayer.position, localPlayer.heading.toFixed(2));
+ } else {
+ triggerNetworkEvent("ag.player.sync", localPlayer.position, localPlayer.heading.toFixed(2));
+
+ if(localPlayer.vehicle) {
+ if(localPlayer.getData("ag.veh") == null) {
+ if(localPlayer.vehicle.getData("ag.syncId") != null) {
+ triggerNetworkEvent("ag.iv.veh", localPlayer.getData("ag.syncId"));
+ localPlayer.setData("ag.veh", localPlayer.vehicle);
+ }
+ }
+ } else {
+ if(localPlayer.getData("ag.veh") != null) {
+ triggerNetworkEvent("ag.iv.veh", -1);
+ localPlayer.removeData("ag.veh", localPlayer.vehicle);
+ }
+ }
+ }
}
- });
-
- 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) {
+// ---------------------------------------------------------------------------
+
+addNetworkHandler("ag.vehicle", function(syncId, model, position, heading, colour1, colour2, locked, lights) { //livery, dirtLevel, locked, lights) {
let vehicle = createVehicle(model, position, heading);
- vehicle.setData("ag.syncid", syncId);
+ vehicle.setData("ag.syncId", syncId);
vehicle.colour1 = colour1;
vehicle.colour2 = colour2;
//vehicle.livery = livery;
@@ -36,21 +60,68 @@ addNetworkHandler("ag.vehicle", function(model, x, y, z, syncId, colour1, colour
// ---------------------------------------------------------------------------
addNetworkHandler("ag.veh.lock", function(syncId, lockState) {
- getVehicles().forEach(function(vehicle) {
- if(vehicle.getData("ag.syncId") == syncId) {
- vehicle.carLock = lockState;
- }
- });
+ if(isGTAIV()) {
+ getVehicleFromSyncId(syncId).locked = lockState;
+ } else {
+ getVehicleFromSyncId(syncId).carLock = lockState;
+ }
});
// ---------------------------------------------------------------------------
addNetworkHandler("ag.veh.lights", function(syncId, lightState) {
- getVehicles().forEach(function(vehicle) {
- if(vehicle.getData("ag.syncId") == syncId) {
- vehicle.lights = lightState;
- }
- });
+ getVehicleFromSyncId(syncId).lights = lightState;
});
+// ---------------------------------------------------------------------------
+
+addNetworkHandler("ag.veh.engine", function(syncId, engineState) {
+ getVehicleFromSyncId(syncId).engine = engineState;
+});
+
+// ---------------------------------------------------------------------------
+
+addNetworkHandler("ag.veh.colours", function(syncId, colour1, colour2) {
+ getVehicleFromSyncId(syncId).colour1 = colour1;
+ getVehicleFromSyncId(syncId).colour2 = colour2;
+});
+
+// ---------------------------------------------------------------------------
+
+addNetworkHandler("ag.veh.repair", function(syncId) {
+ getVehicleFromSyncId(syncId).fix();
+});
+
+// ---------------------------------------------------------------------------
+
+addNetworkHandler("ag.iv.syncPosition", function(state) {
+ syncPosition = state;
+});
+
+// ---------------------------------------------------------------------------
+
+function getVehicleFromIVSyncId(syncId) {
+ let vehicles = getVehicles();
+ for(let i in vehicles) {
+ if(vehicles[i].getData("ag.syncId")) {
+ if(vehicles[i].getData("ag.syncId") == syncId) {
+ return vehicles[i];
+ }
+ }
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+function getVehicleFromSyncId(syncId) {
+ let vehicles = getVehicles();
+ for(let i in vehicles) {
+ if(vehicles[i].getData("ag.syncId") != null) {
+ if(vehicles[i].getData("ag.syncId") == syncId) {
+ return vehicles[i];
+ }
+ }
+ }
+}
+
// ---------------------------------------------------------------------------
\ No newline at end of file
diff --git a/scripts/client/main.js b/scripts/client/main.js
index 2884fa8f..ee56831f 100644
--- a/scripts/client/main.js
+++ b/scripts/client/main.js
@@ -60,6 +60,12 @@ addEventHandler("onPickupCollected", function(event, pickup, ped) {
// ---------------------------------------------------------------------------
+bindEventHandler("onResourceStart", thisResource, function(event, resource) {
+ triggerNetworkEvent("ag.clientReady");
+});
+
+// ---------------------------------------------------------------------------
+
addNetworkHandler("ag.clearWeapons", function() {
localPlayer.clearWeapons();
});
@@ -108,7 +114,8 @@ function syncVehicle(vehicle) {
}
}
}
-addNetworkHandler("ag.veh.sync", syncVehicle);
+addNetworkHandler("ag.veh.sync", syncVehicle)
+;
// ---------------------------------------------------------------------------
@@ -146,7 +153,7 @@ addNetworkHandler("ag.blips", function(blipData) {
function showIslandBlips() {
for(let i in allServerBlips) {
- let position = new Vec3(allServerBlips[i][1], allServerBlips[i][2], allServerBlips[i][3]);
+ let position = toVector3(allServerBlips[i][1], allServerBlips[i][2], allServerBlips[i][3]);
if(getIslandFromPosition(position) == getIslandFromPosition(localPlayer.position)) {
let tempBlip = createBlip(position, allServerBlips[i][0], allServerBlips[i][4], allServerBlips[i][5]);
currentServerBlips.push(tempBlip);
@@ -250,8 +257,8 @@ addEventHandler("OnDrawnHUD", function (event) {
if(bigMessageFont != null && mainLogo != null) {
/*
if(showLoginMessage) {
- let logoPos = new Vec2(gta.width/2-128, gta.height/2-256);
- let logoSize = new Vec2(256, 256);
+ let logoPos = toVector2(gta.width/2-128, gta.height/2-256);
+ let logoSize = toVector2(256, 256);
drawing.drawRectangle(mainLogo, logoPos, logoSize);
let y = gta.height/2+10;
@@ -262,8 +269,8 @@ addEventHandler("OnDrawnHUD", function (event) {
}
if(showRegisterMessage) {
- let logoPos = new Vec2(gta.width/2-128, gta.height/2-256);
- let logoSize = new Vec2(256, 256);
+ let logoPos = toVector2(gta.width/2-128, gta.height/2-256);
+ let logoSize = toVector2(256, 256);
drawing.drawRectangle(mainLogo, logoPos, logoSize);
let y = gta.height/2+10;
@@ -277,8 +284,8 @@ addEventHandler("OnDrawnHUD", function (event) {
// Draw logo in corner of screen
if(mainLogo != null && showLogo) {
- let logoPos = new Vec2(gta.width-132, gta.height-132);
- let logoSize = new Vec2(128, 128);
+ let logoPos = toVector2(gta.width-132, gta.height-132);
+ let logoSize = toVector2(128, 128);
drawing.drawRectangle(mainLogo, logoPos, logoSize);
}
});
@@ -299,4 +306,78 @@ addEventHandler("OnResourceStart", function(event, resource) {
logoStream.close();
}
}
-});
\ No newline at end of file
+});
+
+// ---------------------------------------------------------------------------
+
+function openAllGarages() {
+ switch(gta.game) {
+ case GAME_GTA_III:
+ for(let i=0;i<=26;i++) {
+ openGarage(i);
+ }
+ break;
+
+ case GAME_GTA_VC:
+ for(let i=0;i<=32;i++) {
+ openGarage(i);
+ }
+ break;
+
+ case GAME_GTA_SA:
+ for(let i=0;i<=44;i++) {
+ openGarage(i);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+function closeAllGarages() {
+ switch(gta.game) {
+ case GAME_GTA_III:
+ for(let i=0;i<=26;i++) {
+ closeGarage(i);
+ }
+ break;
+
+ case GAME_GTA_VC:
+ for(let i=0;i<=32;i++) {
+ closeGarage(i);
+ }
+ break;
+
+ case GAME_GTA_SA:
+ for(let i=0;i<=44;i++) {
+ closeGarage(i);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+addNetworkHandler("ag.freeze", function(state) {
+ gui.showCursor(state, !state);
+});
+
+// ---------------------------------------------------------------------------
+
+addNetworkHandler("ag.control", function(state) {
+ gui.showCursor(state, false);
+});
+
+// ---------------------------------------------------------------------------
+
+addNetworkHandler("ag.fadeCamera", function(state, time) {
+ gta.fadeCamera(state, time);
+});
+
+// ---------------------------------------------------------------------------
\ No newline at end of file
diff --git a/scripts/client/nametags.js b/scripts/client/nametags.js
index 4d57d6fc..f3eac748 100644
--- a/scripts/client/nametags.js
+++ b/scripts/client/nametags.js
@@ -111,7 +111,6 @@ function updateNametags(element) {
health = 1.0;
}
- //console.log("Armour: " + String(element.armour));
let armour = element.armour/100.0;
if(armour > 1.0) {
armour = 1.0;
diff --git a/scripts/server/account.js b/scripts/server/account.js
index 42f08c3a..b594a2dc 100644
--- a/scripts/server/account.js
+++ b/scripts/server/account.js
@@ -63,6 +63,40 @@ function loginCommand(command, params, client) {
// ---------------------------------------------------------------------------
+function autoLoginByIPCommand(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 flagValue = getAccountSettingsFlagValue("autoLoginIP");
+
+ if(getClientData(client).accountData.settings & flagValue) {
+ getClientData(client).accountData.settings = getClientData(client).accountData.settings & ~flagValue;
+ messageClientSuccess(client, `You will not be automatically logged in via your current IP (${client.ip})`);
+ } else {
+ getClientData(client).accountData.settings = getClientData(client).accountData.settings | flagValue;
+ messageClientSuccess(client, `You will now be automatically logged in from your current IP (${client.ip})`);
+ }
+ return true;
+}
+
+// ---------------------------------------------------------------------------
+
function registerCommand(command, params, client) {
if(doesCommandRequireLogin(command)) {
if(!isClientLoggedIn(client)) {
@@ -167,8 +201,8 @@ function switchCharacterCommand(command, params, client) {
return false;
}
- getClientCurrentSubAccount(client).spawnPosition = client.player.position;
- getClientCurrentSubAccount(client).spawnHeading = client.player.heading;
+ getClientCurrentSubAccount(client).spawnPosition = getPlayerPosition(client);
+ getClientCurrentSubAccount(client).spawnHeading = getPlayerHeading(client);
saveSubAccountToDatabase(getClientCurrentSubAccount(client));
@@ -208,7 +242,7 @@ function newCharacterCommand(command, params, client) {
let firstName = splitParams[0];
let lastName = splitParams[1];
- checkNewCharacter(client, firstName, lastName, "01/01/1901", "Liberty City", serverConfig.newCharacter.skin);
+ checkNewCharacter(client, firstName, lastName, "01/01/1901", "Liberty City", getServerConfig().newCharacter.skin);
}
// ---------------------------------------------------------------------------
@@ -238,7 +272,7 @@ function useCharacterCommand(command, params, client) {
return false;
}
- let characterId = Number(params) || 1;
+ let characterId = toInteger(params) || 1;
selectCharacter(client, characterId-1);
}
@@ -246,6 +280,10 @@ function useCharacterCommand(command, params, client) {
// ---------------------------------------------------------------------------
function isClientLoggedIn(client) {
+ if(client.console) {
+ return true;
+ }
+
let loggedIn = getClientData(client).loggedIn;
return loggedIn;
}
@@ -253,6 +291,10 @@ function isClientLoggedIn(client) {
// ---------------------------------------------------------------------------
function isClientRegistered(client) {
+ if(client.console) {
+ return true;
+ }
+
if(getClientData(client).accountData != false) {
if(getClientData(client).accountData.databaseId != 0) {
return true;
@@ -291,6 +333,10 @@ function loadAccountFromName(accountName) {
if(dbQuery.numRows > 0) {
let dbAssoc = fetchQueryAssoc(dbQuery);
let tempAccountData = new serverClasses.accountData(dbAssoc);
+ tempAccountData.keyBinds = loadAccountKeybindsFromDatabase(tempAccountData.databaseId);
+ tempAccountData.messages = loadAccountMessagesFromDatabase(tempAccountData.databaseId);
+ tempAccountData.notes = loadAccountStaffNotesFromDatabase(tempAccountData.databaseId);
+ tempAccountData.contacts = loadAccountContactsFromDatabase(tempAccountData.databaseId);
freeDatabaseQuery(dbQuery);
return tempAccountData;
@@ -322,70 +368,8 @@ function loadAccountFromId(accountId) {
// ---------------------------------------------------------------------------
-function loadSubAccountFromName(firstName, lastName) {
- let dbConnection = connectToDatabase();
- if(dbConnection) {
- firstName = escapeDatabaseString(dbConnection, firstName);
- lastName = escapeDatabaseString(dbConnection, lastName);
- let dbQueryString = `SELECT * FROM sacct_main WHERE sacct_name_first = '${firstName}' AND sacct_name_last = '${lastName}' LIMIT 1;`;
- let dbQuery = queryDatabase(dbConnection, dbQueryString);
- if(dbQuery) {
- let dbAssoc = fetchQueryAssoc(dbQuery);
- freeDatabaseQuery(dbQuery);
- return new serverClasses.subAccountData(dbAssoc);
- }
- disconnectFromDatabase(dbConnection);
- }
-
- return false;
-}
-
-// ---------------------------------------------------------------------------
-
-function loadSubAccountFromId(subAccountId) {
- let dbConnection = connectToDatabase();
- if(dbConnection) {
- let dbQueryString = `SELECT * FROM sacct_main WHERE sacct_id = ${subAccountId} LIMIT 1;`;
- let dbQuery = queryDatabase(dbConnection, dbQueryString);
- if(dbQuery) {
- let dbAssoc = fetchQueryAssoc(dbQuery);
- freeDatabaseQuery(dbQuery);
- return new serverClasses.subAccountData(dbAssoc);
- }
- disconnectFromDatabase(dbConnection);
- }
-
- return false;
-}
-
-// ---------------------------------------------------------------------------
-
-function loadSubAccountsFromAccount(accountId) {
- let tempSubAccounts = [];
- let dbAssoc = false;
- if(accountId > 0) {
- let dbConnection = connectToDatabase();
- if(dbConnection) {
- let dbQueryString = `SELECT * FROM sacct_main WHERE sacct_acct = ${accountId} AND sacct_server = ${serverId}`;
- let dbQuery = queryDatabase(dbConnection, dbQueryString);
- if(dbQuery) {
- while(dbAssoc = fetchQueryAssoc(dbQuery)) {
- let tempSubAccount = new serverClasses.subAccountData(dbAssoc);
- tempSubAccounts.push(tempSubAccount);
- }
- freeDatabaseQuery(dbQuery);
- }
- disconnectFromDatabase(dbConnection);
- }
- }
-
- return tempSubAccounts;
-}
-
-// ---------------------------------------------------------------------------
-
function getAccountHashingFunction() {
- switch(serverConfig.accountPasswordHash.toLowerCase()) {
+ switch(toLowerCase(getServerConfig().accountPasswordHash)) {
case "md5":
return module.hashing.md5;
@@ -443,7 +427,7 @@ function hashAccountPassword(name, password) {
// ---------------------------------------------------------------------------
function saltAccountInfo(name, password) {
- return "ag.gaming." + String(accountSaltHash) + "." + String(name) + "." + String(password);
+ return "ag.gaming." + toString(accountSaltHash) + "." + toString(name) + "." + toString(password);
}
// ---------------------------------------------------------------------------
@@ -455,9 +439,18 @@ function loginSuccess(client) {
client.administrator = true;
}
- if(serverConfig.useGUI) {
- triggerNetworkEvent("ag.loginSuccess", client);
+ if(getClientData(client).subAccounts.length == 0) {
+ if(getServerConfig().useGUI) {
+ triggerNetworkEvent("ag.showPrompt", client, "You have no characters. Would you like to make one?", "No characters");
+ client.setData("ag.prompt", AG_PROMPT_CREATEFIRSTCHAR, false);
+ } else {
+ messageClientAlert(client, `You have no characters. Use /newchar to make one.`);
+ }
+ } else {
+ showCharacterSelectToClient(client);
}
+
+ getClientData(client).accountData.ipAddress = client.ip;
}
// ---------------------------------------------------------------------------
@@ -468,22 +461,9 @@ function saveAccountToDatabase(accountData) {
let safePassword = escapeDatabaseString(dbConnection, accountData.password);
let safeStaffTitle = escapeDatabaseString(dbConnection, accountData.staffTitle);
let safeEmailAddress = escapeDatabaseString(dbConnection, accountData.emailAddress);
- //let safeIRCAccount = dbConnection.escapeString(accountData.ircAccount);
+ //let safeIRCAccount = dbConnection.escapetoString(accountData.ircAccount);
- let dbQueryString = `UPDATE acct_main SET acct_pass='${safePassword}', acct_settings=${accountData.settings}, acct_staff_flags=${accountData.flags.admin}, acct_staff_title='${safeStaffTitle}', acct_mod_flags=${String(accountData.flags.moderation)}, acct_discord=${String(accountData.discordAccount)}, acct_email='${safeEmailAddress}' WHERE acct_id=${accountData.databaseId}`;
- let dbQuery = queryDatabase(dbConnection, dbQueryString);
- //freeDatabaseQuery(dbQuery);
- disconnectFromDatabase(dbConnection);
- }
-}
-
-// ---------------------------------------------------------------------------
-
-function saveSubAccountToDatabase(subAccountData) {
- let dbConnection = connectToDatabase();
-
- if(dbConnection) {
- let dbQueryString = `UPDATE sacct_main SET sacct_pos_x=${subAccountData.spawnPosition.x}, sacct_pos_y=${subAccountData.spawnPosition.y}, sacct_pos_z=${subAccountData.spawnPosition.z}, sacct_angle=${subAccountData.spawnHeading}, sacct_skin=${subAccountData.skin}, sacct_cash=${subAccountData.cash} WHERE sacct_id=${subAccountData.databaseId}`;
+ let dbQueryString = `UPDATE acct_main SET acct_pass='${safePassword}', acct_settings=${accountData.settings}, acct_staff_flags=${accountData.flags.admin}, acct_staff_title='${safeStaffTitle}', acct_mod_flags=${toString(accountData.flags.moderation)}, acct_discord=${toString(accountData.discordAccount)}, acct_email='${safeEmailAddress}', acct_ip='${accountData.ipAddress}' WHERE acct_id=${accountData.databaseId}`;
let dbQuery = queryDatabase(dbConnection, dbQueryString);
//freeDatabaseQuery(dbQuery);
disconnectFromDatabase(dbConnection);
@@ -511,32 +491,11 @@ function createAccount(name, password, email = "") {
// ---------------------------------------------------------------------------
-function createSubAccount(accountId, firstName, lastName, skinId, dateOfBirth, placeOfOrigin) {
- console.log(`[Asshat.Account] Attempting to create subaccount ${firstName} ${lastName} in database`);
- let dbConnection = connectToDatabase();
-
- if(dbConnection) {
- let safeFirstName = escapeDatabaseString(dbConnection, firstName);
- let safeLastName = escapeDatabaseString(dbConnection, lastName);
- let safePlaceOfOrigin = escapeDatabaseString(dbConnection, placeOfOrigin);
-
- let dbQuery = queryDatabase(dbConnection, `INSERT INTO sacct_main (sacct_acct, sacct_name_first, sacct_name_last, sacct_skin, sacct_origin, sacct_when_born, sacct_pos_x, sacct_pos_y, sacct_pos_z, sacct_angle, sacct_cash, sacct_server) VALUES (${accountId}, '${safeFirstName}', '${safeLastName}', ${skinId}, '${safePlaceOfOrigin}', '${dateOfBirth}', ${serverConfig.newCharacter.spawnPosition.x}, ${serverConfig.newCharacter.spawnPosition.y}, ${serverConfig.newCharacter.spawnPosition.z}, ${serverConfig.newCharacter.spawnHeading}, ${serverConfig.newCharacter.money}, ${serverId})`);
- if(getDatabaseInsertId(dbConnection) > 0) {
- return loadSubAccountFromId(getDatabaseInsertId(dbConnection));
- }
- disconnectFromDatabase(dbConnection);
- }
-
- return false;
-}
-
-// ---------------------------------------------------------------------------
-
function checkLogin(client, password) {
let loginAttemptsRemaining = client.getData("ag.loginAttemptsRemaining")-1;
if(isClientLoggedIn(client)) {
- if(serverConfig.useGUI) {
+ if(getServerConfig().useGUI) {
triggerNetworkEvent("ag.loginSuccess", client);
} else {
messageClientError(client, "You are already logged in!");
@@ -545,7 +504,7 @@ function checkLogin(client, password) {
}
if(!isClientRegistered(client)) {
- if(serverConfig.useGUI) {
+ if(getServerConfig().useGUI) {
triggerNetworkEvent("ag.showRegistration", client);
} else {
messageClientError(client, "Your name is not registered! Use /register to make an account.");
@@ -554,7 +513,7 @@ function checkLogin(client, password) {
}
if(areParamsEmpty(password)) {
- if(serverConfig.useGUI) {
+ if(getServerConfig().useGUI) {
triggerNetworkEvent("ag.loginFailed", client, `Invalid password! ${loginAttemptsRemaining} tries remaining.`);
} else {
messageClientError(client, "You must enter a password!");
@@ -563,36 +522,29 @@ function checkLogin(client, password) {
}
if(!isAccountPasswordCorrect(getClientData(client).accountData, hashAccountPassword(client.name, password))) {
- if(serverConfig.useGUI) {
+ if(getServerConfig().useGUI) {
triggerNetworkEvent("ag.loginFailed", client, `Invalid password! ${loginAttemptsRemaining} tries remaining.`);
} else {
messageClientError(client, `Invalid password! ${loginAttemptsRemaining} tries remaining.`);
}
return false;
}
+
+ if(getServerConfig().useGUI) {
+ triggerNetworkEvent("ag.loginSuccess", client);
+ }
loginSuccess(client);
-
- if(getClientData(client).subAccounts.length == 0) {
- if(serverConfig.useGUI) {
- triggerNetworkEvent("ag.showPrompt", client, "You have no characters. Would you like to make one?", "No characters");
- client.setData("ag.prompt", AG_PROMPT_CREATEFIRSTCHAR, false);
- } else {
- messageClientAlert(client, `You have no characters. Use /newchar to make one.`);
- }
- } else {
- showCharacterSelectToClient(client);
- }
}
addNetworkHandler("ag.checkLogin", checkLogin);
// ---------------------------------------------------------------------------
function checkRegistration(client, password, confirmPassword = "", emailAddress = "") {
- console.log("[Asshat.Account]: Checking registration for " + String(client.name));
+ console.log("[Asshat.Account]: Checking registration for " + toString(client.name));
if(isClientRegistered(client)) {
- if(serverConfig.useGUI) {
+ if(getServerConfig().useGUI) {
triggerNetworkEvent("ag.showLogin", client);
} else {
messageClientError(client, "Your name is already registered!");
@@ -601,7 +553,7 @@ function checkRegistration(client, password, confirmPassword = "", emailAddress
}
if(isClientLoggedIn(client)) {
- if(serverConfig.useGUI) {
+ if(getServerConfig().useGUI) {
triggerNetworkEvent("ag.loginSuccess", client);
} else {
messageClientError(client, "You are already logged in!");
@@ -610,7 +562,7 @@ function checkRegistration(client, password, confirmPassword = "", emailAddress
}
if(areParamsEmpty(password)) {
- if(serverConfig.useGUI) {
+ if(getServerConfig().useGUI) {
triggerNetworkEvent("ag.registrationFailed", client, "Password cannot be blank!");
} else {
messageClientError(client, "The password cannot be blank!");
@@ -618,21 +570,21 @@ function checkRegistration(client, password, confirmPassword = "", emailAddress
return false;
}
- if(serverConfig.useGUI) {
+ if(getServerConfig().useGUI) {
if(areParamsEmpty(confirmPassword)) {
triggerNetworkEvent("ag.registrationFailed", client, "Password confirm cannot be blank!");
return false;
}
}
- if(serverConfig.useGUI) {
+ if(getServerConfig().useGUI) {
if(areParamsEmpty(emailAddress)) {
triggerNetworkEvent("ag.registrationFailed", client, "Email address cannot be blank!");
return false;
}
}
- if(serverConfig.useGUI) {
+ if(getServerConfig().useGUI) {
if(password != confirmPassword) {
triggerNetworkEvent("ag.registrationFailed", client, "The passwords must match!");
return false;
@@ -640,7 +592,7 @@ function checkRegistration(client, password, confirmPassword = "", emailAddress
}
if(!doesPasswordMeetRequirements(password)) {
- if(serverConfig.useGUI) {
+ if(getServerConfig().useGUI) {
// Work on this later. Function should return true by default anyway for now.
triggerNetworkEvent("ag.registrationFailed", client, "Password doesn't meet requirements!");
} else {
@@ -649,7 +601,7 @@ function checkRegistration(client, password, confirmPassword = "", emailAddress
return false
}
- if(serverConfig.useGUI) {
+ if(getServerConfig().useGUI) {
if(!isValidEmailAddress(emailAddress)) {
triggerNetworkEvent("ag.registrationFailed", client, "You must put a valid email!");
return false
@@ -658,7 +610,7 @@ function checkRegistration(client, password, confirmPassword = "", emailAddress
let accountData = createAccount(client.name, password, emailAddress);
if(!accountData) {
- if(serverConfig.useGUI) {
+ if(getServerConfig().useGUI) {
triggerNetworkEvent("ag.registrationFailed", client, "Something went wrong. Your account could not be created!");
} else {
messageClientAlert(client, "Something went wrong. Your account could not be created!");
@@ -674,7 +626,7 @@ function checkRegistration(client, password, confirmPassword = "", emailAddress
messageClientSuccess(client, "Your account has been created!");
messageClientAlert(client, "To play on the server, you will need to make a character.");
- if(serverConfig.useGUI) {
+ if(getServerConfig().useGUI) {
triggerNetworkEvent("ag.registrationSuccess", client);
triggerNetworkEvent("ag.showPrompt", client, "You have no characters. Would you like to make one?", "No Characters");
client.setData("ag.prompt", AG_PROMPT_CREATEFIRSTCHAR, false);
@@ -686,107 +638,6 @@ addNetworkHandler("ag.checkRegistration", checkRegistration);
// ---------------------------------------------------------------------------
-function checkNewCharacter(client, firstName, lastName, dateOfBirth, placeOfOrigin, skinId) {
- if(areParamsEmpty(firstName)) {
- triggerNetworkEvent("ag.newCharacterFailed", client, "First name cannot be blank!");
- return false;
- }
- firstName = firstName.trim();
-
- if(areParamsEmpty(lastName)) {
- triggerNetworkEvent("ag.newCharacterFailed", client, "Last name cannot be blank!");
- return false;
- }
- lastName = lastName.trim();
-
- if(areParamsEmpty(dateOfBirth)) {
- triggerNetworkEvent("ag.newCharacterFailed", client, "Date of birth cannot be blank!");
- return false;
- }
-
- if(areParamsEmpty(placeOfOrigin)) {
- triggerNetworkEvent("ag.newCharacterFailed", client, "Place of origin cannot be blank!");
- return false;
- }
-
- if(areParamsEmpty(skinId)) {
- triggerNetworkEvent("ag.newCharacterFailed", client, "Invalid skin!");
- return false;
- }
-
- let subAccountData = createSubAccount(getClientData(client).accountData.databaseId, firstName, lastName, skinId, dateOfBirth, placeOfOrigin);
- if(!subAccountData) {
- if(serverConfig.useGUI) {
- triggerNetworkEvent("ag.newCharacterFailed", client, "Something went wrong. Your character could not be created!");
- } else {
- messageClientAlert(client, "Something went wrong. Your character could not be created!");
- }
- messageClientAlert(client, "Asshat Gaming staff have been notified of the problem and will fix it shortly.");
- return false;
- }
-
- getClientData(client).subAccounts = loadSubAccountsFromAccount(getClientData(client).accountData.databaseId);
- getClientData(client).currentSubAccount = 0;
- let tempSubAccount = getClientData(client).subAccounts[0];
- showCharacterSelectToClient(client);
-}
-addNetworkHandler("ag.checkNewCharacter", checkNewCharacter);
-
-// ---------------------------------------------------------------------------
-
-addNetworkHandler("ag.previousCharacter", function(client) {
- if(getClientData(client).subAccounts.length > 1) {
- if(getClientData(client).currentSubAccount <= 0) {
- getClientData(client).currentSubAccount = getClientData(client).subAccounts.length-1;
- } else {
- getClientData(client).currentSubAccount--;
- }
-
- let subAccountId = getClientData(client).currentSubAccount;
- let tempSubAccount = getClientData(client).subAccounts[subAccountId];
- triggerNetworkEvent("ag.switchCharacterSelect", client, tempSubAccount.firstName, tempSubAccount.lastName, tempSubAccount.placeOfOrigin, tempSubAccount.dateOfBirth, tempSubAccount.skin);
- }
-});
-
-// ---------------------------------------------------------------------------
-
-addNetworkHandler("ag.nextCharacter", function(client) {
- if(getClientData(client).subAccounts.length > 1) {
- if(getClientData(client).currentSubAccount >= getClientData(client).subAccounts.length-1) {
- getClientData(client).currentSubAccount = 0;
- } else {
- getClientData(client).currentSubAccount++;
- }
-
- let subAccountId = getClientData(client).currentSubAccount;
- let tempSubAccount = getClientData(client).subAccounts[subAccountId];
- triggerNetworkEvent("ag.switchCharacterSelect", client, tempSubAccount.firstName, tempSubAccount.lastName, tempSubAccount.placeOfOrigin, tempSubAccount.dateOfBirth, tempSubAccount.skin);
- }
-});
-
-// ---------------------------------------------------------------------------
-
-function selectCharacter(client, characterId = -1) {
- if(serverConfig.useGUI) {
- triggerNetworkEvent("ag.characterSelectSuccess", client);
- }
-
- if(characterId != -1) {
- getClientData(client).currentSubAccount = characterId;
- }
-
- let tempSubAccount = getClientCurrentSubAccount(client);
- spawnPlayer(client, tempSubAccount.spawnPosition, tempSubAccount.spawnHeading, tempSubAccount.skin);
-
- messageClientNormal(client, `You are playing as ${tempSubAccount.firstName} ${tempSubAccount.lastName}`, getColourByName("white"));
- messageClientNormal(client, "This server is in early development and may restart at any time for updates.", getColourByName("orange"));
- messageClientNormal(client, "Please report any bugs using /bug and suggestions using /idea", getColourByName("yellow"));
- triggerNetworkEvent("ag.restoreCamera", client);
-}
-addNetworkHandler("ag.selectCharacter", selectCharacter);
-
-// ---------------------------------------------------------------------------
-
function isValidEmailAddress(emailAddress) {
return true;
}
@@ -816,10 +667,8 @@ function saveClientToDatabase(client) {
saveAccountToDatabase(getClientData(client).accountData);
let subAccountData = getClientCurrentSubAccount(client);
- if(client.player) {
- subAccountData.spawnPosition = client.player.position;
- subAccountData.spawnHeading = client.player.heading;
- }
+ subAccountData.spawnPosition = getPlayerPosition(client);
+ subAccountData.spawnHeading = getPlayerHeading(client);
saveSubAccountToDatabase(subAccountData);
console.log(`[Asshat.Account]: Saved client ${client.name} to database successfully!`);
@@ -829,11 +678,11 @@ function saveClientToDatabase(client) {
// ---------------------------------------------------------------------------
function initClient(client) {
- triggerNetworkEvent("ag.guiColour", client, serverConfig.guiColour[0], serverConfig.guiColour[1], serverConfig.guiColour[2]);
- triggerNetworkEvent("ag.logo", client, serverConfig.showLogo);
-
+ triggerNetworkEvent("ag.guiColour", client, getServerConfig().guiColour[0], getServerConfig().guiColour[1], getServerConfig().guiColour[2]);
+ triggerNetworkEvent("ag.logo", client, getServerConfig().showLogo);
+
showConnectCameraToPlayer(client);
- messageClient(`Please wait ...`, client, serverConfig.colour.byName.softGreen);
+ messageClient(`Please wait ...`, client, getColourByName("softGreen"));
setTimeout(function() {
let sessionId = saveSessionToDatabase(client);
@@ -843,19 +692,24 @@ function initClient(client) {
let tempAccountData = loadAccountFromName(client.name);
let tempSubAccounts = loadSubAccountsFromAccount(tempAccountData.databaseId);
- serverData.clients[client.index] = new serverClasses.clientData(client, tempAccountData, tempSubAccounts);
+ getServerData().clients[client.index] = new serverClasses.clientData(client, tempAccountData, tempSubAccounts);
if(tempAccountData != false) {
- if(serverConfig.useGUI) {
- triggerNetworkEvent("ag.showLogin", client);
+ if(isAccountAutoIPLoginEnabled(tempAccountData) && getClientData(client).accountData.ipAddress == client.ip) {
+ messageClientAlert(client, "You have been automatically logged in via IP!");
+ loginSuccess(client);
} else {
- messageClient(`Welcome back to Asshat Gaming RP, ${client.name}! Please /login to continue.`, client, serverConfig.colour.byName.softGreen);
+ if(getServerConfig().useGUI) {
+ triggerNetworkEvent("ag.showLogin", client);
+ } else {
+ messageClient(`Welcome back to Asshat Gaming RP, ${client.name}! Please /login to continue.`, client, getColourByName("softGreen"));
+ }
}
} else {
- if(serverConfig.useGUI) {
+ if(getServerConfig().useGUI) {
triggerNetworkEvent("ag.showRegistration", client);
} else {
- messageClient(`Welcome to Asshat Gaming RP, ${client.name}! Please /register to continue.`, client, serverConfig.colour.byName.softGreen);
+ messageClient(`Welcome to Asshat Gaming RP, ${client.name}! Please /register to continue.`, client, getColourByName("softGreen"));
}
}
}, 2500);
@@ -867,26 +721,147 @@ function initClient(client) {
// ---------------------------------------------------------------------------
-function showCharacterSelectToClient(client) {
- if(serverConfig.useGUI) {
- getClientData(client).currentSubAccount = 0;
- let tempSubAccount = getClientData(client).subAccounts[0];
- triggerNetworkEvent("ag.showCharacterSelect", client, tempSubAccount.firstName, tempSubAccount.lastName, tempSubAccount.placeOfOrigin, tempSubAccount.dateOfBirth, tempSubAccount.skin);
- } else {
- //let emojiNumbers = ["➊", "➋", "➌", "➍", "➎", "➏", "➐", "➑", "➒"];
- //let emojiNumbers = ["①", "②", "③", "④", "⑤", "⑥", "⑦", "⑧", "⑨"];
- messageClientNormal(client, `You have the following characters. Use /usechar to select one:`, serverConfig.colour.byName.teal);
- getClientData(client).subAccounts.forEach(function(subAccount, index) {
- messageClientNormal(client, `${index+1} • [#CCCCCC]${subAccount.firstName} ${subAccount.lastName}`);
- });
- }
-}
-
-// ---------------------------------------------------------------------------
-
function saveSessionToDatabase(client) {
// To-do
return 0;
}
+// ---------------------------------------------------------------------------
+
+function createDefaultKeybindsForAccount(accountDatabaseId) {
+ for(let i in getServerConfig().defaultKeybinds) {
+ quickDatabaseQuery(`INSERT INTO acct_hotkey (acct_hotkey_acct, acct_hotkey_key, acct_hotkey_cmdstr, acct_hotkey_when_added) VALUES (${accountDatabaseId}, ${getServerConfig().defaultKeybinds[i].key}, '${getServerConfig().defaultKeybinds[i].commandString}', UNIX_TIMESTAMP())`);
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+function loadAccountKeybindsFromDatabase(accountDatabaseID) {
+ console.log(`[Asshat.Account]: Loading account keybinds for account ${accountDatabaseID} from database ...`);
+
+ let tempAccountKeybinds = [];
+ let dbConnection = connectToDatabase();
+ let dbQuery = null;
+ let dbAssoc;
+
+ if(dbConnection) {
+ dbQuery = queryDatabase(dbConnection, "SELECT * FROM `acct_hotkey` WHERE `acct_hotkey_enabled` = 1 AND `acct_hotkey_acct` = " + toString(accountDatabaseID));
+ if(dbQuery) {
+ if(dbQuery.numRows > 0) {
+ while(dbAssoc = fetchQueryAssoc(dbQuery)) {
+ let tempAccountKeyBindData = new serverClasses.accountKeybindData(dbAssoc);
+ tempAccountKeybinds.push(tempAccountKeybinds);
+ console.log(`[Asshat.Account]: Account keybind '${tempAccountKeyBindData.databaseId}' loaded from database successfully!`);
+ }
+ }
+ freeDatabaseQuery(dbQuery);
+ }
+ disconnectFromDatabase(dbConnection);
+ }
+
+ console.log(`[Asshat.Account]: ${tempAccountKeybinds.length} account keybinds for account ${accountDatabaseID} loaded from database successfully!`);
+ return tempAccountKeybinds;
+}
+
+// ---------------------------------------------------------------------------
+
+function loadAccountStaffNotesFromDatabase(accountDatabaseID) {
+ console.log(`[Asshat.Account]: Loading account staff notes for account ${accountDatabaseID} from database ...`);
+
+ let tempAccountStaffNotes = [];
+ let dbConnection = connectToDatabase();
+ let dbQuery = null;
+ let dbAssoc;
+
+ if(dbConnection) {
+ dbQuery = queryDatabase(dbConnection, "SELECT * FROM `acct_note` WHERE `acct_note_deleted` = 0 AND `acct_note_acct` = " + toString(accountDatabaseID));
+ if(dbQuery) {
+ if(dbQuery.numRows > 0) {
+ while(dbAssoc = fetchQueryAssoc(dbQuery)) {
+ let tempAccountStaffNoteData = new serverClasses.accountStaffNoteData(dbAssoc);
+ tempAccountStaffNotes.push(tempAccountStaffNoteData);
+ console.log(`[Asshat.Account]: Account staff note '${tempAccountStaffNoteData.databaseId}' loaded from database successfully!`);
+ }
+ }
+ freeDatabaseQuery(dbQuery);
+ }
+ disconnectFromDatabase(dbConnection);
+ }
+
+ console.log(`[Asshat.Account]: ${tempAccountStaffNotes.length} account staff notes for account ${accountDatabaseID} loaded from database successfully!`);
+ return tempAccountStaffNotes;
+}
+
+// ---------------------------------------------------------------------------
+
+function loadAccountContactsFromDatabase(accountDatabaseID) {
+ console.log(`[Asshat.Account]: Loading account contacts for account ${accountDatabaseID} from database ...`);
+
+ let tempAccountContacts = [];
+ let dbConnection = connectToDatabase();
+ let dbQuery = null;
+ let dbAssoc;
+
+ if(dbConnection) {
+ dbQuery = queryDatabase(dbConnection, "SELECT * FROM `acct_contact` WHERE `acct_contact_deleted` = 0 AND `acct_contact_acct` = " + toString(accountDatabaseID));
+ if(dbQuery) {
+ if(dbQuery.numRows > 0) {
+ while(dbAssoc = fetchQueryAssoc(dbQuery)) {
+ let tempAccountContactData = new serverClasses.accountContactData(dbAssoc);
+ tempAccountContacts.push(tempAccountContactData);
+ console.log(`[Asshat.Account]: Account contact '${tempAccountContactData.databaseId}' loaded from database successfully!`);
+ }
+ }
+ freeDatabaseQuery(dbQuery);
+ }
+ disconnectFromDatabase(dbConnection);
+ }
+
+ console.log(`[Asshat.Account]: ${tempAccountContacts.length} account contacts for account ${accountDatabaseID} loaded from database successfully!`);
+ return tempAccountContacts;
+}
+
+// ---------------------------------------------------------------------------
+
+function loadAccountMessagesFromDatabase(accountDatabaseID) {
+ console.log(`[Asshat.Account]: Loading account messages for account ${accountDatabaseID} from database ...`);
+
+ let tempAccountMessages = [];
+ let dbConnection = connectToDatabase();
+ let dbQuery = null;
+ let dbAssoc;
+
+ if(dbConnection) {
+ dbQuery = queryDatabase(dbConnection, "SELECT * FROM `acct_msg` WHERE `acct_msg_deleted` = 0 AND `acct_msg_acct` = " + toString(accountDatabaseID));
+ if(dbQuery) {
+ if(dbQuery.numRows > 0) {
+ while(dbAssoc = fetchQueryAssoc(dbQuery)) {
+ let tempAccountMessageData = new serverClasses.accountContactData(dbAssoc);
+ tempAccountMessages.push(tempAccountMessageData);
+ console.log(`[Asshat.Account]: Account contact '${tempAccountMessageData.databaseId}' loaded from database successfully!`);
+ }
+ }
+ freeDatabaseQuery(dbQuery);
+ }
+ disconnectFromDatabase(dbConnection);
+ }
+
+ console.log(`[Asshat.Account]: ${tempAccountMessages.length} account messages for account ${accountDatabaseID} loaded from database successfully!`);
+ return tempAccountMessages;
+}
+
+// ---------------------------------------------------------------------------
+
+function isAccountAutoIPLoginEnabled(accountData) {
+ let accountSettings = accountData.settings;
+ let flagValue = getAccountSettingsFlagValue("autoLoginIP");
+ return hasBitFlag(accountSettings, flagValue);
+}
+
+// ---------------------------------------------------------------------------
+
+addNetworkHandler("ag.clientReady", function(client) {
+
+});
+
// ---------------------------------------------------------------------------
\ No newline at end of file
diff --git a/scripts/server/ban.js b/scripts/server/ban.js
index 15ba5b87..3c44bd10 100644
--- a/scripts/server/ban.js
+++ b/scripts/server/ban.js
@@ -28,7 +28,7 @@ function initBanScript() {
function addBanCommandHandlers() {
console.log("[Asshat.Ban]: Adding ban command handlers ...");
- let banCommands = serverData.commands.ban;
+ let banCommands = getServerData().commands.ban;
for(let i in banCommands) {
addCommandHandler(banCommands[i].command, banCommands[i].handlerFunction);
}
@@ -125,7 +125,7 @@ function ipBanCommand(command, params, client, fromDiscord) {
function banAccount(accountId, adminAccountId, reason) {
let dbConnection = connectToDatabase();
if(dbConnection) {
- let safeReason = dbConnection.escapeString(reason);
+ let safeReason = dbConnection.escapetoString(reason);
let dbQuery = queryDatabase(dbConnection, `INSERT INTO ban_main (ban_type, ban_detail, ban_who_banned, ban_reason) VALUES (${banType.account}, ${accountId}, ${adminAccountId}, '${safeReason}');`);
freeDatabaseQuery(dbQuery);
dbConnection.close();
@@ -140,7 +140,7 @@ function banAccount(accountId, adminAccountId, reason) {
function banSubAccount(subAccountId, adminAccountId, reason) {
let dbConnection = connectToDatabase();
if(dbConnection) {
- let safeReason = dbConnection.escapeString(reason);
+ let safeReason = dbConnection.escapetoString(reason);
let dbQuery = queryDatabase(dbConnection, `INSERT INTO ban_main (ban_type, ban_detail, ban_who_banned, ban_reason) VALUES (${banType.subAccount}, ${subAccountId}, ${adminAccountId}, '${safeReason}');`);
freeDatabaseQuery(dbQuery);
dbConnection.close();
@@ -155,7 +155,7 @@ function banSubAccount(subAccountId, adminAccountId, reason) {
function banIPAddress(ipAddress, adminAccountId, reason) {
let dbConnection = connectToDatabase();
if(dbConnection) {
- let safeReason = dbConnection.escapeString(reason);
+ let safeReason = dbConnection.escapetoString(reason);
let dbQuery = queryDatabase(dbConnection, `INSERT INTO ban_main (ban_type, ban_detail, ban_who_banned, ban_reason) VALUES (${banType.ipAddress}, INET_ATON(${ipAddress}), ${adminAccountId}, '${safeReason}');`);
freeDatabaseQuery(dbQuery);
dbConnection.close();
@@ -210,7 +210,7 @@ function unbanIPAddress(ipAddress, adminAccountId) {
// ---------------------------------------------------------------------------
function isAccountBanned(accountId) {
- let bans = serverData.bans;
+ let bans = getServerData().bans;
for(let i in bans) {
if(bans[i].type == banType.account) {
if(bans[i].detail == accountId) {
@@ -225,7 +225,7 @@ function isAccountBanned(accountId) {
// ---------------------------------------------------------------------------
function isSubAccountBanned(subAccountId) {
- let bans = serverData.bans;
+ let bans = getServerData().bans;
for(let i in bans) {
if(bans[i].type == banType.subAcount) {
if(bans[i].detail == subAccountId) {
@@ -240,7 +240,7 @@ function isSubAccountBanned(subAccountId) {
// ---------------------------------------------------------------------------
function isIpAddressBanned(ipAddress) {
- let bans = serverData.bans;
+ let bans = getServerData().bans;
for(let i in bans) {
if(bans[i].type == banType.ipAddress) {
if(bans[i].detail == ipAddress) {
diff --git a/scripts/server/bitflag.js b/scripts/server/bitflag.js
index bcf81f5d..38769b8b 100644
--- a/scripts/server/bitflag.js
+++ b/scripts/server/bitflag.js
@@ -8,14 +8,104 @@
// TYPE: Server (JavaScript)
// ===========================================================================
+// ---------------------------------------------------------------------------
+
+let serverBitFlags = {
+ staffFlags: {},
+ moderationFlags: {},
+ factionFlags: {},
+ clanFlags: {},
+ accountSettingsFlags: {},
+ subAccountSettingsFlags: {},
+};
+
+// ---------------------------------------------------------------------------
+
+let serverBitFlagKeys = {
+ staffFlagKeys: [
+ "none",
+ "basicModeration",
+ "manageHouses",
+ "manageVehicles",
+ "manageBusinesses",
+ "manageFactions",
+ "manageClans",
+ "manageServer",
+ "manageAdmins",
+ "developer"
+ ],
+ moderationFlagKeys: [
+ "none",
+ "muted",
+ "frozen",
+ "hackerBox",
+ "jobBanned",
+ "ammuBanned",
+ "policeBanned",
+ "fireBanned",
+ "gunBanned",
+ ],
+ factionFlagKeys: [
+ "none",
+ "police",
+ "medical",
+ "fire",
+ "government"
+ ],
+ clanFlagKeys: [
+ "none",
+ "illegal",
+ "legal",
+ "mafia",
+ "streetGang",
+ "weapons",
+ "drugs",
+ "humanTrafficking",
+ "vigilante",
+ "hitContracts"
+ ],
+ clanPermissionFlagKeys: [
+ "none",
+ "inviteMember",
+ "removeMember",
+ "memberRank",
+ "memberFlags",
+ "memberTag",
+ "memberTitle",
+ "rankFlags",
+ "rankTag",
+ "rankTitle",
+ "clanTag",
+ "clanName",
+ "manageVehicles",
+ "manageHouses",
+ "manageBusinesses",
+ "owner"
+ ],
+ accountSettingsFlagKeys: [
+ "none",
+ "useWhiteList",
+ "useBlackList",
+ "twoStepAuth",
+ "authAttemptAlert",
+ "alertWithGUI",
+ "errorWithGUI",
+ "askWithGUI",
+ "autoLoginIP",
+ ],
+ subAccountSettingsFlagKeys: [],
+}
+
+// ---------------------------------------------------------------------------
+
function initBitFlagScript() {
- serverData.staffFlags = createBitFlagTable(serverData.staffFlagKeys);
- serverData.moderationFlags = createBitFlagTable(serverData.moderationFlagKeys);
- serverData.accountSettingsFlags = createBitFlagTable(serverData.accountSettingsFlagKeys);
- //serverData.subAccountSettingsFlags = createBitFlagTable(serverData.subAccountSettingsFlagKeys);
- serverData.clanFlags = createBitFlagTable(serverData.clanFlagKeys);
- serverData.clanPermissionFlags = createBitFlagTable(serverData.clanPermissionFlagKeys);
- serverData.factionFlags = createBitFlagTable(serverData.factionFlagKeys);
+ getServerData().staffFlags = createBitFlagTable(getServerData().staffFlagKeys);
+ getServerData().moderationFlags = createBitFlagTable(getServerData().moderationFlagKeys);
+ getServerData().accountSettingsFlags = createBitFlagTable(getServerData().accountSettingsFlagKeys);
+ //getServerData().subAccountSettingsFlags = createBitFlagTable(getServerData().subAccountSettingsFlagKeys);
+ getServerData().clanFlags = createBitFlagTable(getServerData().clanFlagKeys);
+ getServerData().clanPermissionFlags = createBitFlagTable(getServerData().clanPermissionFlagKeys);
+ getServerData().factionFlags = createBitFlagTable(getServerData().factionFlagKeys);
return true;
}
@@ -43,16 +133,26 @@ function createBitFlagTable(keyNames) {
// ---------------------------------------------------------------------------
+function hasBitFlag(allFlags, checkForFlag) {
+ return (allFlags & checkForFlag);
+}
+
+// ---------------------------------------------------------------------------
+
function doesClientHaveStaffPermission(client, requiredFlags) {
+ if(client.console) {
+ return true;
+ }
+
if(requiredFlags == getStaffFlagValue("none")) {
return true;
}
let staffFlags = 0;
if(!isClientFromDiscord(client)) {
- staffFlags = serverData.clients[client.index].accountData.staffFlags;
+ staffFlags = getServerData().clients[client.index].accountData.flags.admin;
} else {
- staffFlags = getDiscordUserData(client).accountData.staffFlags;
+ staffFlags = getDiscordUserData(client).accountData.flags.admin;
}
// -1 is automatic override (having -1 for staff flags is basically god mode admin level)
@@ -74,11 +174,39 @@ function getStaffFlagValue(flagName) {
return -1;
}
- if(typeof serverData.staffFlags[flagName] === "undefined") {
+ if(typeof getServerData().staffFlags[flagName] === "undefined") {
return false;
}
- return serverData.staffFlags[flagName];
+ return getServerData().staffFlags[flagName];
+}
+
+// ---------------------------------------------------------------------------
+
+function getAccountSettingsFlagValue(flagName) {
+ if(flagName == "all") {
+ return -1;
+ }
+
+ if(typeof getServerData().accountSettingsFlags[flagName] === "undefined") {
+ return false;
+ }
+
+ return getServerData().accountSettingsFlags[flagName];
+}
+
+// ---------------------------------------------------------------------------
+
+function getAccountFlagsFlagValue(flagName) {
+ if(flagName == "all") {
+ return -1;
+ }
+
+ if(typeof getServerData().accountFlags[flagName] === "undefined") {
+ return false;
+ }
+
+ return getServerData().accountFlags[flagName];
}
// ---------------------------------------------------------------------------
@@ -88,7 +216,7 @@ function giveClientStaffFlag(client, flagName) {
return false;
}
- getClientData(client).accountData.staffFlags = getClientData(client).accountData.staffFlags | getStaffFlagValue(flagName);
+ getClientData(client).accountData.flags.admin = getClientData(client).accountData.flags.admin | getStaffFlagValue(flagName);
return true;
}
@@ -99,14 +227,37 @@ function takeClientStaffFlag(client, flagName) {
return false;
}
- getClientData(client).accountData.staffFlags = getClientData(client).accountData.staffFlags & ~getStaffFlagValue(flagName);
+ getClientData(client).accountData.flags.admin = getClientData(client).accountData.flags.admin & ~getStaffFlagValue(flagName);
+ return true;
+}
+
+// ---------------------------------------------------------------------------
+
+function addBitFlag(allFlags, flagValue) {
+ return allFlags | flagValue;
+}
+
+// ---------------------------------------------------------------------------
+
+function removeBitFlag(allFlags, flagValue) {
+ return allFlags & ~flagValue;
+}
+
+// ---------------------------------------------------------------------------
+
+function takeClientStaffFlag(client, flagName) {
+ if(!getStaffFlagValue(flagName)) {
+ return false;
+ }
+
+ getClientData(client).accountData.flags.admin = getClientData(client).accountData.flags.admin & ~getStaffFlagValue(flagName);
return true;
}
// ---------------------------------------------------------------------------
function clearClientStaffFlags(client) {
- getClientData(client).accountData.staffFlags = getStaffFlagValue("none");
+ getClientData(client).accountData.flags.admin = getStaffFlagValue("none");
return true;
}
diff --git a/scripts/server/business.js b/scripts/server/business.js
index f14c291a..73fe74b6 100644
--- a/scripts/server/business.js
+++ b/scripts/server/business.js
@@ -10,7 +10,7 @@
function initBusinessScript() {
console.log("[Asshat.Business]: Initializing business script ...");
- serverData.businesses = loadBusinessesFromDatabase();
+ getServerData().businesses = loadBusinessesFromDatabase();
createAllBusinessPickups();
addBusinessCommandHandlers();
console.log("[Asshat.Business]: Business script initialized successfully!");
@@ -40,7 +40,7 @@ function loadBusinessesFromDatabase() {
let dbAssoc;
if(dbConnection) {
- dbQuery = queryDatabase(dbConnection, "SELECT * FROM `biz_main` WHERE `biz_server` = " + String(serverId));
+ dbQuery = queryDatabase(dbConnection, "SELECT * FROM `biz_main` WHERE `biz_server` = " + toString(serverId));
if(dbQuery) {
if(dbQuery.numRows > 0) {
while(dbAssoc = fetchQueryAssoc(dbQuery)) {
@@ -70,7 +70,7 @@ function loadBusinessLocationsFromDatabase(businessId) {
let dbAssoc;
if(dbConnection) {
- dbQuery = queryDatabase(dbConnection, "SELECT * FROM `biz_loc` WHERE `biz_loc_biz` = " + String(businessId));
+ dbQuery = queryDatabase(dbConnection, "SELECT * FROM `biz_loc` WHERE `biz_loc_biz` = " + toString(businessId));
if(dbQuery) {
if(dbQuery.numRows > 0) {
while(dbAssoc = fetchQueryAssoc(dbQuery)) {
@@ -156,8 +156,8 @@ function createBusinessLocationCommand(command, params, client) {
return false;
}
- let locationType = String(splitParams[0]);
- let businessId = Number(splitParams[1]) || (isPlayerInAnyBusiness(client.player)) ? getPlayerBusiness(client.player) : getClosestBusinessEntrance(client.player.position);
+ let locationType = toString(splitParams[0]);
+ let businessId = toInteger(splitParams[1]) || (isPlayerInAnyBusiness(client.player)) ? getPlayerBusiness(client.player) : getClosestBusinessEntrance(client.player.position);
createBusinessLocation(locationType, businessId);
messageClientSuccess(client, "Business created in " + getAreaName(client.player.position) + " (" + params + ")");
@@ -171,13 +171,13 @@ function createBusiness(name, entrancePosition, interiorId, virtualWorld) {
if(dbConnection) {
escapedName = escapeDatabaseString(dbConnection, escapedName)
- let dbQuery = queryDatabase(dbConnection, "INSERT INTO `biz_main` (`biz_server`, `biz_name`, `biz_entrance_x`, `biz_entrance_y`, `biz_entrance_z`, `biz_entrance_int`, `biz_entrance_vw`) VALUES (" + String(serverId) + ", '" + escapedName + "', " + String(entrancePosition.x) + ", " + String(entrancePosition.y) + ", " + String(entrancePosition.z) + ", " + String(interiorId) + ", " + String(virtualWorld) + ")");
+ let dbQuery = queryDatabase(dbConnection, "INSERT INTO `biz_main` (`biz_server`, `biz_name`, `biz_entrance_x`, `biz_entrance_y`, `biz_entrance_z`, `biz_entrance_int`, `biz_entrance_vw`) VALUES (" + toString(serverId) + ", '" + escapedName + "', " + toString(entrancePosition.x) + ", " + toString(entrancePosition.y) + ", " + toString(entrancePosition.z) + ", " + toString(interiorId) + ", " + toString(virtualWorld) + ")");
disconnectFromDatabase(dbConnection);
let tempBusinessData = loadBusinessFromDatabaseById(dbConnection.insertID);
if(tempBusinessData != false) {
let tempBusiness = new serverClasses.businessData(tempBusinessData);
- serverData.business.push(tempBusiness);
+ getServerData().business.push(tempBusiness);
}
}
return true;
@@ -210,7 +210,7 @@ function deleteBusinessCommand(command, params, client) {
return false;
}
- let businessId = Number(splitParams[1]) || (isPlayerInAnyBusiness(client.player)) ? getPlayerBusiness(client.player) : getClosestBusinessEntrance(client.player.position);
+ let businessId = toInteger(splitParams[1]) || (isPlayerInAnyBusiness(client.player)) ? getPlayerBusiness(client.player) : getClosestBusinessEntrance(client.player.position);
deleteBusiness(businessId);
messageClientSuccess(client, `Business '${tempBusinessData.name} deleted!`);
}
@@ -245,7 +245,7 @@ function deleteBusinessLocationCommand(command, params, client) {
return false;
}
- //let businessId = Number(splitParams[1]);
+ //let businessId = toInteger(splitParams[1]);
//deleteBusinessLocation(businessId);
//messageClientSuccess(client, `Business '${tempBusinessData.name} deleted!`);
}
@@ -279,11 +279,11 @@ function setBusinessNameCommand(command, params, client) {
let splitParams = params.split(" ");
- let newBusinessName = String(splitParams[0]);
- let businessId = Number(splitParams[1]) || (isPlayerInAnyBusiness(client.player)) ? getPlayerBusiness(client.player) : getClosestBusinessEntrance(client.player.position);
+ let newBusinessName = toString(splitParams[0]);
+ let businessId = toInteger(splitParams[1]) || (isPlayerInAnyBusiness(client.player)) ? getPlayerBusiness(client.player) : getClosestBusinessEntrance(client.player.position);
- serverData.businesses[businessId].name = newBusinessName;
- messageClientSuccess(client, `Business '${serverData.businesses[businessId].name}' renamed to '${newBusinessName}'!`);
+ getServerData().businesses[businessId].name = newBusinessName;
+ messageClientSuccess(client, `Business '${getServerData().businesses[businessId].name}' renamed to '${newBusinessName}'!`);
}
// ---------------------------------------------------------------------------
@@ -321,7 +321,7 @@ function setBusinessOwnerCommand(command, params, client) {
let splitParams = params.split(" ");
let newBusinessOwner = getClientFromParams(splitParams[0]);
- let businessId = Number(splitParams[1]) || (isPlayerInAnyBusiness(client.player)) ? getPlayerBusiness(client.player) : getClosestBusinessEntrance(client.player.position);
+ let businessId = toInteger(splitParams[1]) || (isPlayerInAnyBusiness(client.player)) ? getPlayerBusiness(client.player) : getClosestBusinessEntrance(client.player.position);
if(!newBusinessOwner) {
messageClientError("Player not found!");
@@ -333,8 +333,8 @@ function setBusinessOwnerCommand(command, params, client) {
return false;
}
- serverData.businesses[businessId].ownerId = serverData.clients[newBusinessOwner.index].accountData.databaseId;
- messageClientSuccess(client, `Business '${serverData.businesses[businessId].name}' owner set to '${newBusinessOwner.name}'!`);
+ getServerData().businesses[businessId].ownerId = getServerData().clients[newBusinessOwner.index].accountData.databaseId;
+ messageClientSuccess(client, `Business '${getServerData().businesses[businessId].name}' owner set to '${newBusinessOwner.name}'!`);
}
// ---------------------------------------------------------------------------
@@ -371,10 +371,10 @@ function lockBusinessCommand(command, params, client) {
let splitParams = params.split(" ");
- let businessId = Number(splitParams[0]) || (isPlayerInAnyBusiness(client.player)) ? getPlayerBusiness(client.player) : getClosestBusinessEntrance(client.player.position);
+ let businessId = toInteger(splitParams[0]) || (isPlayerInAnyBusiness(client.player)) ? getPlayerBusiness(client.player) : getClosestBusinessEntrance(client.player.position);
- serverData.businesses[businessId].locked = !serverData.businesses[businessId].locked;
- messageClientSuccess(client, "Business " + serverData.businesses[businessId].name + " " + (serverData.businesses[businessId].locked) ? "locked" : "unlocked" + "!");
+ getServerData().businesses[businessId].locked = !getServerData().businesses[businessId].locked;
+ messageClientSuccess(client, "Business " + getServerData().businesses[businessId].name + " " + (getServerData().businesses[businessId].locked) ? "locked" : "unlocked" + "!");
}
// ---------------------------------------------------------------------------
@@ -406,11 +406,11 @@ function setBusinessEntranceFeeCommand(command, params, client) {
let splitParams = params.split(" ");
- let entranceFee = Number(splitParams[0]) || 0;
- let businessId = Number(splitParams[1]) || (isPlayerInAnyBusiness(client.player)) ? getPlayerBusiness(client.player) : getClosestBusinessEntrance(client.player.position);
+ let entranceFee = toInteger(splitParams[0]) || 0;
+ let businessId = toInteger(splitParams[1]) || (isPlayerInAnyBusiness(client.player)) ? getPlayerBusiness(client.player) : getClosestBusinessEntrance(client.player.position);
- serverData.businesses[businessId].entranceFee = entranceFee;
- messageClientSuccess(client, `Business '${serverData.businesses[businessId].name}' entrance fee to $'${entranceFee}'!`);
+ getServerData().businesses[businessId].entranceFee = entranceFee;
+ messageClientSuccess(client, `Business '${getServerData().businesses[businessId].name}' entrance fee to $'${entranceFee}'!`);
}
// ---------------------------------------------------------------------------
@@ -442,17 +442,17 @@ function withdrawFromBusinessCommand(command, params, client) {
let splitParams = params.split(" ");
- let amount = Number(splitParams[0]) || 0;
- let businessId = Number(splitParams[1]) || (isPlayerInAnyBusiness(client.player)) ? getPlayerBusiness(client.player) : getClosestBusinessEntrance(client.player.position);
+ let amount = toInteger(splitParams[0]) || 0;
+ let businessId = toInteger(splitParams[1]) || (isPlayerInAnyBusiness(client.player)) ? getPlayerBusiness(client.player) : getClosestBusinessEntrance(client.player.position);
- let tempBusinessData = serverData.businesses.filter(b => b.databaseId == businessId)[0];
+ let tempBusinessData = getServerData().businesses.filter(b => b.databaseId == businessId)[0];
- if(serverData.businesses[businessId].till < amount) {
+ if(getServerData().businesses[businessId].till < amount) {
messageClientError(client, `Business '${tempBusinessData.name}' doesn't have that much money! Use /bizbalance.`);
return false;
}
- serverData.businesses[businessId].till -= amount;
+ getServerData().businesses[businessId].till -= amount;
getClientCurrentSubAccount(client).cash += amount;
updatePlayerCash(client);
messageClientSuccess(client, `You withdrew $${amount} from business '${tempBusinessData.name}''s till'`);
@@ -487,15 +487,15 @@ function depositIntoBusinessCommand(command, params, client) {
let splitParams = params.split(" ");
- let amount = Number(splitParams[0]) || 0;
- let businessId = Number(splitParams[1]) || (isPlayerInAnyBusiness(client.player)) ? getPlayerBusiness(client.player) : getClosestBusinessEntrance(client.player.position);
+ let amount = toInteger(splitParams[0]) || 0;
+ let businessId = toInteger(splitParams[1]) || (isPlayerInAnyBusiness(client.player)) ? getPlayerBusiness(client.player) : getClosestBusinessEntrance(client.player.position);
if(getClientCurrentSubAccount(client).cash < amount) {
messageClientError(client, `You don't have that much money! You only have $${getClientCurrentSubAccount(client).cash}`);
return false;
}
- serverData.businesses[businessId].till += amount;
+ getServerData().businesses[businessId].till += amount;
getClientCurrentSubAccount(client).cash -= amount;
updatePlayerCash(client);
messageClientSuccess(client, `You deposited $${amount} into business '${tempBusinessData.name}''s till'`);
@@ -530,15 +530,15 @@ function viewBusinessTillAmountCommand(command, params, client) {
let splitParams = params.split(" ");
- let businessId = Number(splitParams[0]) || (isPlayerInAnyBusiness(client.player)) ? getPlayerBusiness(client.player) : getClosestBusinessEntrance(client.player.position);
+ let businessId = toInteger(splitParams[0]) || (isPlayerInAnyBusiness(client.player)) ? getPlayerBusiness(client.player) : getClosestBusinessEntrance(client.player.position);
- messageClientSuccess(client, `Business '${serverData.businesses[businessId].name}''s till has $'${serverData.businesses[businessId].till}'!`);
+ messageClientSuccess(client, `Business '${getServerData().businesses[businessId].name}''s till has $'${getServerData().businesses[businessId].till}'!`);
}
// ---------------------------------------------------------------------------
function getBusinessDataFromDatabaseId(databaseId) {
- let matchingBusinesses = serverData.businesses.filter(b => b.databaseId == businessId)
+ let matchingBusinesses = getServerData().businesses.filter(b => b.databaseId == businessId)
if(matchingBusinesses.length == 1) {
return matchingBusinesses[0];
}
@@ -548,7 +548,7 @@ function getBusinessDataFromDatabaseId(databaseId) {
// ---------------------------------------------------------------------------
function getClosestBusinessEntrance(position) {
- return serverData.businesses.reduce((i, j) => ((i.entrancePosition.distance(position) <= j.entrancePosition.distance(position)) ? i : j));
+ return getServerData().businesses.reduce((i, j) => ((i.entrancePosition.distance(position) <= j.entrancePosition.distance(position)) ? i : j));
}
// ---------------------------------------------------------------------------
@@ -574,7 +574,7 @@ function getPlayerBusiness(player) {
// ---------------------------------------------------------------------------
function saveAllBusinessesToDatabase() {
- for(let i in serverData.businesses) {
+ for(let i in getServerData().businesses) {
saveBusinessToDatabase(i);
}
}
@@ -582,14 +582,14 @@ function saveAllBusinessesToDatabase() {
// ---------------------------------------------------------------------------
function saveBusinessToDatabase(businessId) {
- let tempBusinessData = serverData.businesses[businessId]
+ let tempBusinessData = getServerData().businesses[businessId]
console.log(`[Asshat.Business]: Saving business '${tempBusinessData.name}' to database ...`);
let dbConnection = connectToDatabase();
if(dbConnection) {
if(tempBusinessData.databaseId == 0) {
let dbQueryString = `INSERT INTO biz_main (biz_name, biz_owner_type, biz_owner_id, biz_locked, biz_entrance_fee, biz_till, biz_entrance_pos_x, biz_entrance_pos_y, biz_entrance_pos_z, biz_entrance_rot_z, biz_entrance_int, biz_entrance_vw, biz_exit_pos_x, biz_exit_pos_y, biz_exit_pos_z, biz_exit_rot_z, biz_exit_int, biz_exit_vw) VALUES ('${tempBusinessData.name}', ${tempBusinessData.ownerType}, ${tempBusinessData.ownerId}, ${boolToInt(tempBusinessData.locked)}, ${tempBusinessData.entranceFee}, ${tempBusinessData.till}, ${tempBusinessData.entrancePos.x}, ${tempBusinessData.entrancePos.y}, ${tempBusinessData.entrancePos.z}, ${tempBusinessData.entranceHeading}, ${tempBusinessData.entranceInterior}, ${tempBusinessData.entranceDimension}, ${tempBusinessData.exitPos.x}, ${tempBusinessData.exitPos.y}, ${tempBusinessData.exitPos.z}, ${tempBusinessData.exitHeading}, ${tempBusinessData.exitInterior}, ${tempBusinessData.exitDimension})`;
queryDatabase(dbConnection, dbQueryString);
- serverData.businesses[businessId].databaseId = getDatabaseInsertId(dbConnection);
+ getServerData().businesses[businessId].databaseId = getDatabaseInsertId(dbConnection);
} else {
let dbQueryString = `UPDATE biz_main SET biz_name=${tempBusinessData.name}, biz_owner_type=${tempBusinessData.ownerType}, biz_owner_id=${tempBusinessData.ownerId}, biz_locked=${boolToInt(tempBusinessData.locked)}, biz_entrance_fee=${tempBusinessData.entranceFee}, biz_till=${tempBusinessData.till}, biz_entrance_pos_x=${tempBusinessData.entrancePos.x}, biz_entrance_pos_y=${tempBusinessData.entrancePos.y}, biz_entrance_pos_z=${tempBusinessData.entrancePos.z}, biz_entrance_rot_z=${tempBusinessData.entranceHeading}, biz_entrance_int=${tempBusinessData.entranceInterior}, biz_entrance_vw=${tempBusinessData.entranceDimension}, biz_exit_pos_x=${tempBusinessData.exitPos.x}, biz_exit_pos_y=${tempBusinessData.exitPos.y}, biz_exit_pos_z=${tempBusinessData.exitPos.z}, biz_exit_rot_z=${tempBusinessData.exitHeading}, biz_exit_int=${tempBusinessData.exitInterior}, biz_exit_vw=${tempBusinessData.exitDimension} WHERE biz_id=${tempBusinessData.databaseId}`;
queryDatabase(dbConnection, dbQueryString);
@@ -605,17 +605,17 @@ function saveBusinessToDatabase(businessId) {
// ---------------------------------------------------------------------------
function createAllBusinessPickups() {
- for(let i in serverData.businesses) {
- serverData.businesses.pickup = createPickup(serverConfig.businessPickupModel, serverData.businesses[i].position);
- serverData.businesses[i].pickup.setData("ag.ownerType", AG_PICKUP_BUSINESS, true);
- serverData.businesses[i].pickup.setData("ag.ownerId", i, true);
+ for(let i in getServerData().businesses) {
+ getServerData().businesses.pickup = createPickup(getServerConfig().businessPickupModel, getServerData().businesses[i].position);
+ getServerData().businesses[i].pickup.setData("ag.ownerType", AG_PICKUP_BUSINESS, true);
+ getServerData().businesses[i].pickup.setData("ag.ownerId", i, true);
}
}
// ---------------------------------------------------------------------------
function deleteBusiness(businessId) {
- let tempBusinessData = serverData.businesses[businessId];
+ let tempBusinessData = getServerData().businesses[businessId];
let dbConnection = connectToDatabase();
let dbQuery = null;
@@ -636,7 +636,7 @@ function deleteBusiness(businessId) {
/*
function deleteBusiness(businessId) {
- let tempBusinessData = serverData.businesses[businessId];
+ let tempBusinessData = getServerData().businesses[businessId];
let dbConnection = connectToDatabase();
let dbQuery = null;
@@ -671,9 +671,9 @@ function removePlayersFromBusiness(businessId) {
function exitBusiness(client) {
let businessId = client.getData("ag.inBusiness");
if(client.player) {
- triggerNetworkEvent("ag.interior", client, serverData.businesses[businessId].entranceInterior);
- triggerNetworkEvent("ag.dimension", client, serverData.businesses[businessId].entranceDimension);
- triggerNetworkEvent("ag.position", client, serverData.businesses[businessId].entrancePosition);
+ triggerNetworkEvent("ag.interior", client, getServerData().businesses[businessId].entranceInterior);
+ triggerNetworkEvent("ag.dimension", client, getServerData().businesses[businessId].entranceDimension);
+ triggerNetworkEvent("ag.position", client, getServerData().businesses[businessId].entrancePosition);
}
}
diff --git a/scripts/server/chat.js b/scripts/server/chat.js
index 67127b5b..dbfd9979 100644
--- a/scripts/server/chat.js
+++ b/scripts/server/chat.js
@@ -125,7 +125,7 @@ function whisperCommand(command, params, client) {
// ---------------------------------------------------------------------------
function talkToNearbyPlayers(client, messageText) {
- let clients = getClientsInRange(client.player.position, serverConfig.talkDistance);
+ let clients = getClientsInRange(client.player.position, getServerConfig().talkDistance);
for(let i in clients) {
//if(clients[i] != client) {
messageClientTalk(getClientFromPlayerElement(clients[i]), client, messageText);
@@ -136,7 +136,7 @@ function talkToNearbyPlayers(client, messageText) {
// ---------------------------------------------------------------------------
function whisperToNearbyPlayers(client, messageText) {
- let clients = getClientsInRange(client.player.position, serverConfig.talkDistance);
+ let clients = getClientsInRange(client.player.position, getServerConfig().talkDistance);
for(let i in clients) {
//if(clients[i] != client) {
messageClientWhisper(getClientFromPlayerElement(clients[i]), client, messageText);
@@ -147,7 +147,7 @@ function whisperToNearbyPlayers(client, messageText) {
// ---------------------------------------------------------------------------
function shoutToNearbyPlayers(client, messageText) {
- let clients = getClientsInRange(client.player.position, serverConfig.shoutDistance);
+ let clients = getClientsInRange(client.player.position, getServerConfig().shoutDistance);
for(let i in clients) {
//if(clients[i].index != client.index) {
messageClientShout(getClientFromPlayerElement(clients[i]), client, messageText);
@@ -158,7 +158,7 @@ function shoutToNearbyPlayers(client, messageText) {
// ---------------------------------------------------------------------------
function doActionToNearbyPlayers(client, messageText) {
- let clients = getClientsInRange(client.player.position, serverConfig.doActionDistance);
+ let clients = getClientsInRange(client.player.position, getServerConfig().doActionDistance);
for(let i in clients) {
//if(clients[i].index != client.index) {
messageClientDoAction(getClientFromPlayerElement(clients[i]), client, messageText);
@@ -169,7 +169,7 @@ function doActionToNearbyPlayers(client, messageText) {
// ---------------------------------------------------------------------------
function meActionToNearbyPlayers(client, messageText) {
- let clients = getClientsInRange(client.player.position, serverConfig.meActionDistance);
+ let clients = getClientsInRange(client.player.position, getServerConfig().meActionDistance);
for(let i in clients) {
//if(clients[i].index != client.index) {
messageClientMeAction(getClientFromPlayerElement(clients[i]), client, messageText);
diff --git a/scripts/server/clan.js b/scripts/server/clan.js
index e3b095cc..b5900a09 100644
--- a/scripts/server/clan.js
+++ b/scripts/server/clan.js
@@ -10,7 +10,7 @@
function initClanScript() {
console.log("[Asshat.Clan]: Initializing clans script ...");
- serverData.clans = loadClansFromDatabase();
+ getServerData().clans = loadClansFromDatabase();
addClanCommandHandlers();
console.log("[Asshat.Clan]: Clan script initialized successfully!");
return true;
@@ -38,7 +38,7 @@ function loadClansFromDatabase() {
let dbAssoc;
if(dbConnection) {
- let dbQuery = queryDatabase(dbConnection, "SELECT * FROM `clan_main` WHERE `clan_deleted` = 0 AND `clan_server` = " + String(serverId));
+ let dbQuery = queryDatabase(dbConnection, "SELECT * FROM `clan_main` WHERE `clan_deleted` = 0 AND `clan_server` = " + toString(serverId));
if(dbQuery) {
if(dbQuery.numRows > 0) {
while(dbAssoc = fetchQueryAssoc(dbQuery)) {
@@ -54,7 +54,7 @@ function loadClansFromDatabase() {
disconnectFromDatabase(dbConnection);
}
- console.log("[Asshat.Clan]: " + String(tempClans.length) + " clans loaded from database successfully!");
+ console.log("[Asshat.Clan]: " + toString(tempClans.length) + " clans loaded from database successfully!");
return tempClans;
}
@@ -127,13 +127,13 @@ function deleteClanCommand(command, params, client) {
return false;
}
- if(!doesClanIDExist(Number(params))) {
+ if(!doesClanIDExist(toInteger(params))) {
messageClientError(client, "That clan ID does not exist!");
return false;
}
- messageClientSuccess(client, "The '" + getClanData(Number(params)).name + "' clan has been deleted!");
- deleteClan(Number(params));
+ messageClientSuccess(client, "The '" + getClanData(toInteger(params)).name + "' clan has been deleted!");
+ deleteClan(toInteger(params));
}
// ----------------------------------------------------------------------------
@@ -448,7 +448,7 @@ function createClan(name) {
let tempClanData = loadClanFromDatabaseById(getDatabaseInsertId(dbConnection));
if(tempClanData != false) {
let tempClan = serverClasses.clanData(tempClanData);
- serverData.clans.push(tempClan);
+ getServerData().clans.push(tempClan);
}
}
return true;
diff --git a/scripts/server/class.js b/scripts/server/class.js
index 9fc9aa5d..e93147c4 100644
--- a/scripts/server/class.js
+++ b/scripts/server/class.js
@@ -48,11 +48,62 @@ function initClassTable() {
this.discordAccount = accountAssoc["acct_discord"];
this.settings = accountAssoc["acct_settings"];
this.emailAddress = accountAssoc["acct_email"];
+ this.ipAddress = accountAssoc["acct_ip"];
+ this.notes = [];
+ this.messages = [];
+ this.keybinds = [];
+ this.contacts = [];
this.subAccounts = [];
this.loggedIn = false;
}
},
+ accountContactData: class {
+ constructor(accountContactAssoc) {
+ if(!accountContactAssoc) {
+ return;
+ }
+
+ this.databaseId = accountContactAssoc["acct_contact_id"];
+ this.accountId = accountContactAssoc["acct_contact_acct"];
+ this.contactAccountId = accountContactAssoc["acct_contact_contact"];
+ this.type = accountContactAssoc["acct_contact_type"];
+ this.whenAdded = accountContactAssoc["acct_contact_when_added"];
+ }
+ },
+ accountMessageData: class {
+ constructor(accountMessageAssoc) {
+ if(!accountMessageAssoc) {
+ return;
+ }
+
+ this.databaseId = accountMessageAssoc["acct_msg_id"];
+ this.accountId = accountMessageAssoc["acct_msg_acct"];
+ this.whoSent = accountMessageAssoc["acct_msg_who_sent"];
+ this.whenSent = accountMessageAssoc["acct_msg_when_sent"];
+ this.whenRead = accountMessageAssoc["acct_msg_when_read"];
+ this.deleted = intToBool(accountMessageAssoc["acct_msg_deleted"]);
+ this.whenDeleted = accountMessageAssoc["acct_msg_when_deleted"];
+ this.folder = accountMessageAssoc["acct_msg_folder"];
+ this.message = accountMessageAssoc["acct_msg_message"];
+ }
+ },
+ accountStaffNoteData: class {
+ constructor(accountStaffNoteAssoc) {
+ if(!accountStaffNoteAssoc) {
+ return;
+ }
+
+ this.databaseId = accountStaffNoteAssoc["acct_note_id"];
+ this.accountId = accountStaffNoteAssoc["acct_note_acct"];
+ this.whoAdded = accountStaffNoteAssoc["acct_note_who_added"];
+ this.whenAdded = accountStaffNoteAssoc["acct_note_when_added"];
+ this.deleted = intToBool(accountMessageAssoc["acct_note_deleted"]);
+ this.whenDeleted = accountMessageAssoc["acct_note_when_deleted"];
+ this.server = accountMessageAssoc["acct_note_server"];
+ this.note = accountMessageAssoc["acct_note_message"];
+ }
+ },
subAccountData: class {
constructor(subAccountAssoc) {
if(!subAccountAssoc) {
@@ -68,8 +119,8 @@ function initClassTable() {
this.cash = subAccountAssoc["sacct_cash"];
this.placeOfOrigin = subAccountAssoc["sacct_origin"];
this.dateOfBirth = subAccountAssoc["sacct_when_born"];
- this.spawnPosition = new Vec3(subAccountAssoc["sacct_pos_x"], subAccountAssoc["sacct_pos_y"], subAccountAssoc["sacct_pos_z"]);
- this.spawnHeading = Number(subAccountAssoc["sacct_angle"]);
+ this.spawnPosition = toVector3(subAccountAssoc["sacct_pos_x"], subAccountAssoc["sacct_pos_y"], subAccountAssoc["sacct_pos_z"]);
+ this.spawnHeading = toInteger(subAccountAssoc["sacct_angle"]);
this.isWorking = false;
this.jobUniform = this.skin;
@@ -77,6 +128,7 @@ function initClassTable() {
this.job = subAccountAssoc["sacct_job"];
this.weapons = [];
+ this.inJail = false;
}
},
businessData: class {
@@ -91,17 +143,17 @@ function initClassTable() {
this.ownerId = businessAssoc("biz_owner_id");
this.locked = businessAssoc("biz_locked");
- this.entrancePosition = new Vec3(businessAssoc("biz_entrance_pos_x"), businessAssoc("biz_entrance_pos_y"), businessAssoc("biz_entrance_pos_z"));
- this.entranceRotation = Number(businessAssoc["biz_entrance_rot_z"]);
- this.entranceInterior = Number(businessAssoc["biz_entrance_int"]);
- this.entranceDimension = Number(businessAssoc["biz_entrance_vw"]);
+ this.entrancePosition = toVector3(businessAssoc("biz_entrance_pos_x"), businessAssoc("biz_entrance_pos_y"), businessAssoc("biz_entrance_pos_z"));
+ this.entranceRotation = toInteger(businessAssoc["biz_entrance_rot_z"]);
+ this.entranceInterior = toInteger(businessAssoc["biz_entrance_int"]);
+ this.entranceDimension = toInteger(businessAssoc["biz_entrance_vw"]);
- this.exitPosition = new Vec3(businessAssoc("biz_exit_pos_x"), businessAssoc("biz_exit_pos_y"), businessAssoc("biz_exit_pos_z"));
- this.exitRotation = Number(businessAssoc["biz_exit_rot_z"]);
- this.exitInterior = Number(businessAssoc["biz_exit_int"]);
- this.exitDimension = Number(businessAssoc["biz_exit_vw"]);
+ this.exitPosition = toVector3(businessAssoc("biz_exit_pos_x"), businessAssoc("biz_exit_pos_y"), businessAssoc("biz_exit_pos_z"));
+ this.exitRotation = toInteger(businessAssoc["biz_exit_rot_z"]);
+ this.exitInterior = toInteger(businessAssoc["biz_exit_int"]);
+ this.exitDimension = toInteger(businessAssoc["biz_exit_vw"]);
- this.till = Number(businessAssoc["biz_till"]);
+ this.till = toInteger(businessAssoc["biz_till"]);
}
},
businessLocationData: class {
@@ -116,9 +168,9 @@ function initClassTable() {
this.business = businessLocationAssoc("biz_loc_biz");
this.enabled = businessLocationAssoc("biz_loc_enabled");
- 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"]);
+ this.position = toVector3(businessLocationAssoc("biz_loc_pos_x"), businessLocationAssoc("biz_loc_pos_y"), businessLocationAssoc("biz_loc_pos_z"));
+ this.interior = toInteger(businessLocationAssoc["biz_loc_int"]);
+ this.dimension = toInteger(businessLocationAssoc["biz_loc_vw"]);
}
},
houseData: class {
@@ -139,19 +191,21 @@ function initClassTable() {
this.vehicle = vehicle;
this.tempVehicle = false;
this.streamedBy = false; // For IV only
- this.ivSyncId = -1;
+ this.syncId = -1;
// Ownership
this.ownerType = AG_VEHOWNER_NONE;
this.ownerId = 0;
this.buyPrice = 0;
this.rentPrice = 0;
+ this.rentedBy = false;
+ this.rentStart = 0;
// Position and Rotation
- this.spawnPosition = (vehicle) ? vehicle.position : new Vec3(0.0, 0.0, 0.0);
+ this.spawnPosition = (vehicle) ? vehicle.position : toVector3(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.syncPosition = toVector3(0.0, 0.0, 0.0); // For IV only
this.syncHeading = 0.0; // For IV only
// Colour Info
@@ -191,10 +245,9 @@ function initClassTable() {
this.rentPrice = vehicleAssoc["veh_buy_price"];
// Position and Rotation
- this.spawnPosition = new Vec3(vehicleAssoc["veh_pos_x"], vehicleAssoc["veh_pos_y"], vehicleAssoc["veh_pos_z"]);
- this.spawnRotation = Number(vehicleAssoc["veh_rot_z"]);
+ this.spawnPosition = toVector3(vehicleAssoc["veh_pos_x"], vehicleAssoc["veh_pos_y"], vehicleAssoc["veh_pos_z"]);
+ this.spawnRotation = toInteger(vehicleAssoc["veh_rot_z"]);
this.spawnLocked = vehicleAssoc["veh_spawn_lock"];
-
// Colour Info
this.colour1IsRGBA = vehicleAssoc["veh_col1_isrgba"];
@@ -218,6 +271,11 @@ function initClassTable() {
this.engineDamage = vehicleAssoc["veh_damage_engine"];
this.visualDamage = vehicleAssoc["veh_damage_visual"];
this.dirtLevel = vehicleAssoc["veh_dirt_level"];
+
+ // Other/Misc
+ this.insuranceAccount = 0;
+ this.fuel = 0;
+ this.flags = 0;
}
}
},
@@ -322,7 +380,7 @@ function initClassTable() {
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.position = toVector3(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;
@@ -330,6 +388,25 @@ function initClassTable() {
this.enabled = jobLocationAssoc["job_loc_enabled"];
}
},
+ keyBindData: class {
+ constructor(keyBindAssoc, key = 0, commandString = "") {
+ this.databaseId = 0;
+ this.key = key;
+ this.account = 0;
+ this.commandString = commandString;
+ this.whenAdded = 0;
+ this.enabled = true;
+
+ if(keyBindAssoc) {
+ this.databaseId = keyBindAssoc["acct_hotkey_id"];
+ this.key = keyBindAssoc["acct_hotkey_key"];
+ this.account = keyBindAssoc["acct_hotkey_acct"];
+ this.commandString = keyBindAssoc["acct_hotkey_cmdstr"];
+ this.whenAdded = keyBindAssoc["acct_hotkey_when_added"];
+ this.enabled = intToBool(keyBindAssoc["acct_hotkey_enabled"]);
+ }
+ }
+ },
}
return tempClasses;
diff --git a/scripts/server/client.js b/scripts/server/client.js
index 56377e07..2de94e2b 100644
--- a/scripts/server/client.js
+++ b/scripts/server/client.js
@@ -103,19 +103,19 @@ addNetworkHandler("ag.afk", function(client, afkState) {
// Not implemented yet
addNetworkHandler("ag.heldKey", function(client, key) {
switch(key) {
- case serverConfig.keybinds.actionKey:
+ case getServerConfig().keybinds.actionKey:
processHoldActionKey(client);
break;
- case serverConfig.keybinds.vehicleLightsKey:
+ case getServerConfig().keybinds.vehicleLightsKey:
processHoldVehicleLightsKey(client);
break;
- case serverConfig.keybinds.vehicleLockKey:
+ case getServerConfig().keybinds.vehicleLockKey:
processHoldVehicleLockKey(client);
break;
- case serverConfig.keybinds.vehicleEngineKey:
+ case getServerConfig().keybinds.vehicleEngineKey:
processHoldVehicleEngineKey(client);
break;
}
@@ -124,16 +124,39 @@ addNetworkHandler("ag.heldKey", function(client, key) {
// ---------------------------------------------------------------------------
addNetworkHandler("ag.player.sync", function(client, position, heading) {
+ //console.log(`POS: ${position}, X: ${position.x}, Y: ${position.y}, Z: ${position.z}`);
client.setData("ag.position", position, true);
client.setData("ag.heading", heading, true);
});
// ---------------------------------------------------------------------------
+addNetworkHandler("ag.player.death", function(client, position, heading) {
+ //console.log(`POS: ${position}, X: ${position.x}, Y: ${position.y}, Z: ${position.z}`);
+ client.setData("ag.position", position, true);
+ client.setData("ag.heading", heading, true);
+ processPlayerDeath(client);
+});
+
+// ---------------------------------------------------------------------------
+
addNetworkHandler("ag.veh.sync", function(client, syncId, position, heading) {
- //let vehicle = getVehicleFromSyncId(syncId);
- //vehicle.setData("ag.position") = position;
- //vehicle.setData("ag.heading") = heading;
+ let vehicleData = getVehicleDataFromSyncId(syncId);
+ if(vehicleData) {
+ vehicleData.syncPosition = position;
+ vehicleData.syncHeading = heading;
+ }
+
+});
+
+// ---------------------------------------------------------------------------
+
+addNetworkHandler("ag.iv.veh", function(client, syncId) {
+ if(syncId == -1) {
+ client.removeData("ag.vehicle");
+ } else {
+ client.setData("ag.vehicle", syncId, true);
+ }
});
// ---------------------------------------------------------------------------
\ No newline at end of file
diff --git a/scripts/server/colour.js b/scripts/server/colour.js
index e993bde6..06a4d60d 100644
--- a/scripts/server/colour.js
+++ b/scripts/server/colour.js
@@ -8,45 +8,59 @@
// TYPE: Server (JavaScript)
// ===========================================================================
+let serverColours = {
+ byType: {
+ talkMessage: toColour(200, 200, 200),
+ shoutMessage: toColour(255, 255, 200),
+ whisperMessage: toColour(130, 130, 130),
+ doActionMessage: toColour(153, 50, 204, 255),
+ meActionMessage: toColour(153, 50, 204, 255),
+ errorMessage: toColour(237, 67, 55, 255),
+ syntaxMessage: toColour(200, 200, 200, 255),
+ normalMessage: toColour(255, 255, 255, 255),
+ alertMessage: toColour(255, 255, 0, 255),
+ successMessage: toColour(0, 180, 0, 255),
+ clanChatMessage: toColour(0, 190, 0, 255),
+ },
+ byName: {
+ white: toColour(255, 255, 255, 255),
+ black: toColour(0, 0, 0, 255),
+ red: toColour(255, 0, 0, 255),
+ yellow: toColour(255, 255, 0, 255),
+ royalBlue: toColour(0, 0, 255, 255),
+ teal: toColour(0, 255, 255, 255),
+ orange: toColour(255, 128, 0, 255),
+ lightGrey: toColour(200, 200, 200, 255),
+ mediumGrey: toColour(150, 150, 150, 255),
+ darkGrey: toColour(64, 64, 64, 255),
+ policeBlue: toColour(70, 130, 180, 255),
+ medicPink: toColour(219, 112, 147, 255),
+ firefighterRed: toColour(205, 92, 92, 255),
+ busDriverGreen: toColour(50, 205, 50, 255),
+ taxiDriverYellow: toColour(240, 230, 140, 255),
+ burntYellow: toColour(210, 210, 0, 255),
+ burntOrange: toColour(210, 120, 0, 255),
+ bankGreen: toColour(0, 150, 0, 255),
+ softGreen: toColour(144, 255, 96, 255),
+ }
+};
+
+// ----------------------------------------------------------------------------
+
+function getServerColours() {
+ return serverColours;
+}
+
// ----------------------------------------------------------------------------
function getColourByType(typeName) {
- return serverConfig.colour.byType[typeName];
+ return getServerColours().byType[typeName];
}
// ----------------------------------------------------------------------------
function getColourByName(colourName) {
- return serverConfig.colour.byName[colourName];
-}
-
-// ---------------------------------------------------------------------------
-
-function rgbToHex(red, green, blue) {
- return "#" + componentToHex(red) + componentToHex(green) + componentToHex(blue);
-}
-
-// ---------------------------------------------------------------------------
-
-function componentToHex(component) {
- let hex = component.toString(16);
- return hex.length == 1 ? "0" + hex : hex;
-}
-
-// ---------------------------------------------------------------------------
-
-function hexToRGB(hex) {
- let red = parseInt((cutHex(hex)).substring(0,2),16);
- let green = parseInt((cutHex(hex)).substring(2,4),16);
- let blue = parseInt((cutHex(hex)).substring(4,6),16);
-
- return {r: red, g: green, b: blue};
-}
-
-// ---------------------------------------------------------------------------
-
-function cutHex(hex) {
- return (hex.charAt(0)=="#") ? hex.substring(1,7) : hex;
+ return getServerColours().byName[colourName];
}
// ---------------------------------------------------------------------------
\ No newline at end of file
diff --git a/scripts/server/command.js b/scripts/server/command.js
index 40af6d22..c3923866 100644
--- a/scripts/server/command.js
+++ b/scripts/server/command.js
@@ -10,6 +10,8 @@
let serverCommands = {};
+// ---------------------------------------------------------------------------
+
function initCommandScript() {
console.log("[Asshat.Command]: Initializing commands script ...");
serverCommands = loadCommandData();
@@ -37,10 +39,7 @@ function loadCommandData() {
commandData("login", loginCommand, "", getStaffFlagValue("none"), false, false),
commandData("register", registerCommand, "", getStaffFlagValue("none"), false, false),
commandData("changepass", changePasswordCommand, "", getStaffFlagValue("none"), true, false),
- //commandData("setpass", changePasswordCommand, "", getStaffFlagValue("none"), true, false),
- commandData("switchchar", switchCharacterCommand, "", getStaffFlagValue("none"), true, false),
- commandData("newchar", newCharacterCommand, " ", getStaffFlagValue("none"), true, false),
- commandData("usechar", useCharacterCommand, "", getStaffFlagValue("none"), true, false),
+ //commandData("iplogin", autoLoginByIPCommand, "", getStaffFlagValue("none"), true, false),
],
ammunation: [],
ban: [
@@ -119,6 +118,7 @@ function loadCommandData() {
commandData("quitjob", quitJobCommand, "", getStaffFlagValue("none"), true, false),
commandData("uniform", jobUniformCommand, "[uniform]", getStaffFlagValue("none"), true, false),
commandData("equip", jobEquipmentCommand, "[equipment]", getStaffFlagValue("none"), true, false),
+ commandData("reloadjobs", reloadAllJobsCommand, "", getStaffFlagValue("developer"), true, false),
commandData("radio", jobRadioCommand, "", getStaffFlagValue("none"), true, false),
commandData("r", jobRadioCommand, "", getStaffFlagValue("none"), true, false),
@@ -145,6 +145,9 @@ function loadCommandData() {
commandData("newcharspawn", setNewCharacterSpawnPositionCommand, "", getStaffFlagValue("manageServer"), true, true),
commandData("newcharcash", setNewCharacterMoneyCommand, "", getStaffFlagValue("manageServer"), true, true),
commandData("newcharskin", setNewCharacterSkinCommand, "[skin id]", getStaffFlagValue("manageServer"), true, true),
+
+ commandData("idea", submitIdeaCommand, "", getStaffFlagValue("none"), true, true),
+ commandData("bug", submitBugReportCommand, "", getStaffFlagValue("none"), true, true),
],
moderation: [
commandData("kick", kickClientCommand, " [reason]", getStaffFlagValue("basicModeration"), true, true),
@@ -161,10 +164,15 @@ function loadCommandData() {
],
security: [],
startup: [],
+ subAccount: [
+ commandData("switchchar", switchCharacterCommand, "", getStaffFlagValue("none"), true, false),
+ commandData("newchar", newCharacterCommand, " ", getStaffFlagValue("none"), true, false),
+ commandData("usechar", useCharacterCommand, "", getStaffFlagValue("none"), true, false),
+ ],
translate: [],
utilities: [],
vehicle: [
- commandData("addcar", createVehicleCommand, "", getStaffFlagValue("manageVehicles"), true, true),
+ commandData("addveh", createVehicleCommand, "", getStaffFlagValue("manageVehicles"), true, true),
commandData("lock", vehicleLockCommand, "", getStaffFlagValue("none"), true, true),
commandData("engine", vehicleEngineCommand, "", getStaffFlagValue("none"), true, true),
commandData("siren", vehicleSirenCommand, "", getStaffFlagValue("none"), true, true),
@@ -176,6 +184,13 @@ function loadCommandData() {
commandData("vehinfo", getVehicleInfoCommand, "", getStaffFlagValue("manageVehicles"), true, true),
commandData("vehpark", toggleVehicleSpawnLockCommand, "", getStaffFlagValue("manageVehicles"), true, true),
+ commandData("vehrespawnall", respawnAllVehiclesCommand, "", getStaffFlagValue("manageVehicles"), true, true),
+ commandData("vehreloadall", reloadAllVehiclesCommand, "", getStaffFlagValue("manageVehicles"), true, true),
+
+ commandData("vehrent", rentVehicleCommand, "", getStaffFlagValue("none"), true, true),
+ commandData("stoprent", stopRentingVehicleCommand, "", getStaffFlagValue("none"), true, true),
+ commandData("vehbuy", buyVehicleCommand, "", getStaffFlagValue("none"), true, true),
+ commandData("vehcolour", setVehicleColourCommand, " ", getStaffFlagValue("none"), true, true),
],
}
return tempCommands;
@@ -188,7 +203,7 @@ function getCommand(command) {
for(let i in commandGroups) {
let commandGroup = commandGroups[i];
for(let j in commandGroup)
- if(commandGroup[j].command.toLowerCase() == command.toLowerCase()) {
+ if(toLowerCase(commandGroup[j].command) == toLowerCase(command)) {
return commandGroup[j];
}
}
@@ -306,15 +321,15 @@ function disableAllCommandsByType(command, params, client) {
return false;
}
- params = params.toLowerCase();
+ params = toLowerCase(params);
- if(typeof serverData.commands[params] == "undefined") {
+ if(isNull(getServerData().commands[params])) {
messageClientError(client, "That command type does not exist!");
return false;
}
- for(let i in serverData.commands[params]) {
- removeCommandHandler(serverData.commands[params][i].command);
+ for(let i in getServerData().commands[params]) {
+ removeCommandHandler(getServerData().commands[params][i].command);
}
messageClientSuccess(client, `[#FF9900]All ${params} commands have been disabled!`);
@@ -343,16 +358,16 @@ function enableAllCommandsByType(command, params, client) {
return false;
}
- params = params.toLowerCase();
+ params = toLowerCase(params);
- if(typeof serverData.commands[params] == "undefined") {
+ if(isNull(getServerData().commands[params])) {
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);
+ for(let i in getServerData().commands[params]) {
+ let command = getServerData().commands[params][i].command;
+ addCommandHandler(command, getServerData().commands[params][i].handlerFunction);
}
messageClientSuccess(client, `[#FF9900]All ${params} commands have been enabled!`);
diff --git a/scripts/server/config.js b/scripts/server/config.js
index 048687bf..092d08c6 100644
--- a/scripts/server/config.js
+++ b/scripts/server/config.js
@@ -77,6 +77,7 @@ let serverConfig = {
takeJobDistance: 5,
stopWorkingDistance: 10,
spawnCarDistance: 5,
+ payAndSprayDistance: 5,
blipSprites: [
false,
{ // GTA III
@@ -146,10 +147,34 @@ let serverConfig = {
},
discordBotToken: "",
discordEnabled: false,
+ defaultKeybinds: [
+ new serverClasses.keyBindData(false, SDLK_o, "engine"),
+ new serverClasses.keyBindData(false, SDLK_i, "lights"),
+ new serverClasses.keyBindData(false, SDLK_l, "lock"),
+ ],
};
// ----------------------------------------------------------------------------
+function initConfigScript() {
+ console.log("[Asshat.Config]: Initializing config script ...");
+ addConfigCommandHandlers();
+ console.log("[Asshat.Config]: Config script initialized!");
+}
+
+// ---------------------------------------------------------------------------
+
+function addConfigCommandHandlers() {
+ console.log("[Asshat.Config]: Adding config command handlers ...");
+ let configCommands = serverCommands.config;
+ for(let i in configCommands) {
+ addCommandHandler(configCommands[i].command, configCommands[i].handlerFunction);
+ }
+ console.log("[Asshat.Config]: Config command handlers added!");
+}
+
+// ---------------------------------------------------------------------------
+
function loadServerConfig() {
let dbConnection = connectToDatabase();
if(dbConnection) {
@@ -160,23 +185,23 @@ function loadServerConfig() {
let dbAssoc = fetchQueryAssoc(dbQuery);
serverId = dbAssoc["svr_id"];
- serverConfig.name = dbAssoc["svr_name"];
- serverConfig.password = dbAssoc["svr_password"];
- serverConfig.newCharacter.spawnPosition = new Vec3(dbAssoc["svr_newchar_pos_x"], dbAssoc["svr_newchar_pos_y"], dbAssoc["svr_newchar_pos_z"]);
- serverConfig.newCharacter.spawnHeading = dbAssoc["svr_newchar_rot_z"];
- serverConfig.newCharacter.money = dbAssoc["svr_newchar_money"];
- serverConfig.newCharacter.bank = dbAssoc["svr_newchar_bank"];
- serverConfig.newCharacter.skin = dbAssoc["svr_newchar_skin"];
+ getServerConfig().name = dbAssoc["svr_name"];
+ getServerConfig().password = dbAssoc["svr_password"];
+ getServerConfig().newCharacter.spawnPosition = toVector3(dbAssoc["svr_newchar_pos_x"], dbAssoc["svr_newchar_pos_y"], dbAssoc["svr_newchar_pos_z"]);
+ getServerConfig().newCharacter.spawnHeading = dbAssoc["svr_newchar_rot_z"];
+ getServerConfig().newCharacter.money = dbAssoc["svr_newchar_money"];
+ getServerConfig().newCharacter.bank = dbAssoc["svr_newchar_bank"];
+ getServerConfig().newCharacter.skin = dbAssoc["svr_newchar_skin"];
- serverConfig.connectCameraPosition = new Vec3(dbAssoc["svr_connectcam_pos_x"], dbAssoc["svr_connectcam_pos_y"], dbAssoc["svr_connectcam_pos_z"]);
- serverConfig.connectCameraLookAt = new Vec3(dbAssoc["svr_connectcam_lookat_x"], dbAssoc["svr_connectcam_lookat_y"], dbAssoc["svr_connectcam_lookat_z"]);
- serverConfig.hour = dbAssoc["svr_start_time_hour"];
- serverConfig.minute = dbAssoc["svr_start_time_min"];
- serverConfig.weather = dbAssoc["svr_start_weather"];
- 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"]];
+ getServerConfig().connectCameraPosition = toVector3(dbAssoc["svr_connectcam_pos_x"], dbAssoc["svr_connectcam_pos_y"], dbAssoc["svr_connectcam_pos_z"]);
+ getServerConfig().connectCameraLookAt = toVector3(dbAssoc["svr_connectcam_lookat_x"], dbAssoc["svr_connectcam_lookat_y"], dbAssoc["svr_connectcam_lookat_z"]);
+ getServerConfig().hour = toInteger(dbAssoc["svr_start_time_hour"]);
+ getServerConfig().minute = toInteger(dbAssoc["svr_start_time_min"]);
+ getServerConfig().weather = toInteger(dbAssoc["svr_start_weather"]);
+ getServerConfig().fallingSnow = intToBool(dbAssoc["svr_start_snow_falling"]);
+ getServerConfig().groundSnow = intToBool(dbAssoc["svr_start_snow_ground"]);
+ getServerConfig().useGUI = intToBool(dbAssoc["svr_gui"]);
+ getServerConfig().guiColour = [toInteger(dbAssoc["svr_gui_col1_r"]), toInteger(dbAssoc["svr_gui_col1_g"]), toInteger(dbAssoc["svr_gui_col1_b"])];
applyConfigToServer();
@@ -190,13 +215,186 @@ function loadServerConfig() {
// ----------------------------------------------------------------------------
function applyConfigToServer() {
- server.name = serverConfig.name;
- server.password = serverConfig.password;
- gta.time.hour = serverConfig.hour;
- gta.time.minute = serverConfig.minute;
- gta.forceWeather(serverConfig.weather);
+ server.name = getServerConfig().name;
+ server.password = getServerConfig().password;
+ gta.time.hour = getServerConfig().hour;
+ gta.time.minute = getServerConfig().minute;
+ gta.forceWeather(getServerConfig().weather);
updateServerRules();
}
+// ----------------------------------------------------------------------------
+
+function saveServerConfigToDatabase() {
+ console.log(`[Asshat.Config]: Saving server configuration to database ...`);
+ let dbConnection = connectToDatabase();
+ if(dbConnection) {
+ let safeServerName = escapeDatabaseString(dbConnection, getServerConfig().name);
+ let safePassword = escapeDatabaseString(dbConnection, getServerConfig().password);
+
+ let dbQueryString = `UPDATE svr_main SET svr_logo=${boolToInt(getServerConfig().showLogo)}, svr_gui=${boolToInt(getServerConfig().useGUI)}, svr_password='${safePassword}', svr_name='${safeServerName}', svr_start_time_hour=${getServerConfig().hour}, svr_start_time_min=${getServerConfig().minute}, svr_start_weather=${getServerConfig().weather}, svr_start_snow_falling=${boolToInt(getServerConfig().fallingSnow)}, svr_start_snow_ground=${boolToInt(getServerConfig().groundSnow)}, svr_newchar_pos_x=${getServerConfig().newCharacter.spawnPosition.x}, svr_newchar_pos_y=${getServerConfig().newCharacter.spawnPosition.y}, svr_newchar_pos_z=${getServerConfig().newCharacter.spawnPosition.z}, svr_newchar_rot_z=${getServerConfig().newCharacter.spawnHeading}, svr_newchar_money=${getServerConfig().newCharacter.money}, svr_newchar_skin=${getServerConfig().newCharacter.skin}, svr_gui_col1_r=${getServerConfig().guiColour[0]}, svr_gui_col1_g=${getServerConfig().guiColour[1]}, svr_gui_col1_b=${getServerConfig().guiColour[2]} WHERE svr_id = ${serverId}`;
+ let dbQuery = queryDatabase(dbConnection, dbQueryString);
+ disconnectFromDatabase(dbConnection);
+ }
+ console.log(`[Asshat.Config]: Server configuration saved to database!`);
+}
+
+// ----------------------------------------------------------------------------
+
+function getServerConfig() {
+ return serverConfig;
+}
+
+// ----------------------------------------------------------------------------
+
+function setTimeCommand(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 hour = toInteger(splitParams[0]) || 0;
+ let minute = toInteger(splitParams[1]) || 0;
+
+ if(hour > 23 || hour < 0) {
+ messageClientError(client, "The hour must be between 0 and 23!");
+ return false;
+ }
+
+ if(minute > 59 || minute < 0) {
+ messageClientError(client, "The minute must be between 0 and 59!");
+ return false;
+ }
+
+ gta.time.hour = hour;
+ gta.time.minute = minute;
+
+ messageAdminAction(`${client.name} set the time to ${makeReadableTime(hour, minute)}`);
+ return true;
+}
+
+// ---------------------------------------------------------------------------
+
+function setWeatherCommand(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 weatherId = getWeatherFromParams(splitParams[0]);
+
+ if(!weatherId) {
+ messageClientError(client, `That weather ID or name is invalid!`);
+ return false;
+ }
+
+ gta.forceWeather(weatherId);
+
+ messageAdminAction(`${client.name} set the weather to to ${weatherNames[server.game][weatherId]}`);
+ updateServerRules();
+ return true;
+}
+
+// ---------------------------------------------------------------------------
+
+function setSnowingCommand(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 fallingSnow = toInteger(splitParams[0]) || 0;
+ let groundSnow = toInteger(splitParams[1]) || 0;
+
+ getServerConfig().fallingSnow = 0;
+
+ messageAdminAction(`${client.name} turned falling snow ${getOnOffFromBool(intToBool(fallingSnow))} and ground snow ${getOnOffFromBool(intToBool(groundSnow))}`);
+ updateServerRules();
+ return true;
+}
+
+// ---------------------------------------------------------------------------
+
+function toggleServerLogoCommand(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;
+ }
+
+ getServerConfig().useLogo = !getServerConfig().useLogo;
+
+ messageAdminAction(`${client.name} turned the server logo image ${toLowerCase(getOnOffFromBool(getServerConfig().useLogo))}`);
+ updateServerRules();
+ return true;
+}
+
+// ---------------------------------------------------------------------------
+
+function toggleServerGUICommand(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;
+ }
+
+ getServerConfig().useGUI = !getServerConfig().useGUI;
+
+ messageAdminAction(`${client.name} turned GUI ${toLowerCase(getOnOffFromBool(getServerConfig().useGUI))} for this server`);
+ updateServerRules();
+ return true;
+}
+
// ----------------------------------------------------------------------------
\ No newline at end of file
diff --git a/scripts/server/const.js b/scripts/server/const.js
index 91d0fae7..bcbc508f 100644
--- a/scripts/server/const.js
+++ b/scripts/server/const.js
@@ -62,4 +62,10 @@ const AG_HOUSEOWNER_PUBLIC = 5;
const AG_BIZLOC_NONE = 0;
const AG_BIZLOC_FUEL = 1;
const AG_BIZLOC_DRIVETHRU = 2;
-const AG_BIZLOC_VENDMACHINE = 3;
\ No newline at end of file
+const AG_BIZLOC_VENDMACHINE = 3;
+
+// Account Contact Types
+const AG_CONTACTTYPE_NONE = 0;
+const AG_CONTACTTYPE_NEUTRAL = 1;
+const AG_CONTACTTYPE_FRIEND = 2;
+const AG_CONTACTTYPE_BLOCKED = 3;
\ No newline at end of file
diff --git a/scripts/server/core.js b/scripts/server/core.js
index 6125052d..b2f1d02f 100644
--- a/scripts/server/core.js
+++ b/scripts/server/core.js
@@ -71,10 +71,13 @@ let serverData = {
"rankTitle",
"clanTag",
"clanName",
+ "manageVehicles",
+ "manageHouses",
+ "manageBusinesses",
"owner"
],
accountSettingsFlagKeys: [
- "None",
+ "none",
"useWhiteList",
"useBlackList",
"twoStepAuth",
@@ -82,6 +85,7 @@ let serverData = {
"alertWithGUI",
"errorWithGUI",
"askWithGUI",
+ "autoLoginIP",
],
subAccountSettingsFlagKeys: [],
staffFlags: {},
@@ -243,19 +247,19 @@ let serverData = {
false,
[ // GTA 3
{
- position: new Vec3(1143.875, -675.1875, 14.97),
+ position: toVector3(1143.875, -675.1875, 14.97),
heading: 1.5,
blip: false,
name: "Portland",
},
{
- position: new Vec3(340.25, -1123.375, 25.98),
+ position: toVector3(340.25, -1123.375, 25.98),
heading: 3.14,
blip: false,
name: "Staunton Island",
},
{
- position: new Vec3(-1253.0, -138.1875, 58.75),
+ position: toVector3(-1253.0, -138.1875, 58.75),
heading: 1.5,
blip: false,
name: "Shoreside Vale",
@@ -263,25 +267,25 @@ let serverData = {
],
[ // GTA VC
{
- position: new Vec3(399.77, -468.90, 11.73),
+ position: toVector3(399.77, -468.90, 11.73),
heading: 0.0,
blip: false,
name: "Washington Beach",
},
{
- position: new Vec3(508.96, 512.07, 12.10),
+ position: toVector3(508.96, 512.07, 12.10),
heading: 0.0,
blip: false,
name: "Vice Point",
},
{
- position: new Vec3(-657.43, 762.31, 11.59),
+ position: toVector3(-657.43, 762.31, 11.59),
heading: 0.0,
blip: false,
name: "Downtown",
},
{
- position: new Vec3(-885.08, -470.44, 13.11),
+ position: toVector3(-885.08, -470.44, 13.11),
heading: 0.0,
blip: false,
name: "Little Havana",
@@ -289,7 +293,7 @@ let serverData = {
],
[ // GTA SA
{
- position: new Vec3(1545.53, -1675.64, 13.561),
+ position: toVector3(1545.53, -1675.64, 13.561),
heading: -1.575,
blip: false,
name: "Los Santos",
@@ -302,67 +306,67 @@ let serverData = {
[ // GTA IV
{
- position: new Vec3(894.99, -357.39, 18.185),
+ position: toVector3(894.99, -357.39, 18.185),
heading: 2.923,
blip: false,
name: "Broker",
},
{
- position: new Vec3(435.40, 1592.29, 17.353),
+ position: toVector3(435.40, 1592.29, 17.353),
heading: 3.087,
blip: false,
name: "South Bohan",
},
{
- position: new Vec3(974.93, 1870.45, 23.073),
+ position: toVector3(974.93, 1870.45, 23.073),
heading: -1.621,
blip: false,
name: "Northern Gardens",
},
{
- position: new Vec3(1233.25, -89.13, 28.034),
+ position: toVector3(1233.25, -89.13, 28.034),
heading: 1.568,
blip: false,
name: "South Slopes",
},
{
- position: new Vec3(50.12, 679.88, 15.316),
+ position: toVector3(50.12, 679.88, 15.316),
heading: 1.569,
blip: false,
name: "Middle Park East",
},
{
- position: new Vec3(85.21, 1189.82, 14.755),
+ position: toVector3(85.21, 1189.82, 14.755),
heading: 3.127,
blip: false,
name: "East Holland",
},
{
- position: new Vec3(2170.87, 448.87, 6.085),
+ position: toVector3(2170.87, 448.87, 6.085),
heading: 1.501,
blip: false,
name: "Francis International Airport",
},
{
- position: new Vec3(213.12, -211.70, 10.752),
+ position: toVector3(213.12, -211.70, 10.752),
heading: 0.200,
blip: false,
name: "Chinatown",
},
{
- position: new Vec3(-1714.95, 276.31, 22.134),
+ position: toVector3(-1714.95, 276.31, 22.134),
heading: 1.127,
blip: false,
name: "Acter",
},
{
- position: new Vec3(-1220.73, -231.53, 3.024),
+ position: toVector3(-1220.73, -231.53, 3.024),
heading: 2.210,
blip: false,
name: "Port Tudor",
},
{
- position: new Vec3(-927.66, 1263.63, 24.587),
+ position: toVector3(-927.66, 1263.63, 24.587),
heading: -0.913,
blip: false,
name: "Leftwood",
@@ -373,19 +377,19 @@ let serverData = {
false,
[ // GTA 3
{
- position: new Vec3(1103.70, -52.45, 7.49),
+ position: toVector3(1103.70, -52.45, 7.49),
heading: 1.5,
blip: false,
name: "Portland",
},
{
- position: new Vec3(-78.48, -436.80, 16.17),
+ position: toVector3(-78.48, -436.80, 16.17),
heading: 3.14,
blip: false,
name: "Staunton Island",
},
{
- position: new Vec3(-1202.10, -14.67, 53.20),
+ position: toVector3(-1202.10, -14.67, 53.20),
heading: 1.5,
blip: false,
name: "Shoreside Vale",
@@ -402,31 +406,31 @@ let serverData = {
],
[ // GTA IV
{
- position: new Vec3(953.13, 95.90, 35.004),
+ position: toVector3(953.13, 95.90, 35.004),
heading: 1.595,
blip: false,
name: "Broker",
},
{
- position: new Vec3(-271.02, 1542.15, 20.420),
+ position: toVector3(-271.02, 1542.15, 20.420),
heading: -1.160,
blip: false,
name: "Northwood",
},
{
- position: new Vec3(1120.47, 1712.36, 10.534),
+ position: toVector3(1120.47, 1712.36, 10.534),
heading: -0.682,
blip: false,
name: "Northern Gardens",
},
{
- position: new Vec3(2364.87, 166.83, 5.813),
+ position: toVector3(2364.87, 166.83, 5.813),
heading: 0.156,
blip: false,
name: "Francis International Airport",
},
{
- position: new Vec3(295.40, -336.88, 4.963),
+ position: toVector3(295.40, -336.88, 4.963),
heading: 2.887,
blip: false,
name: "Chinatown",
@@ -437,54 +441,76 @@ let serverData = {
false,
[ // GTA 3
{
- position: new Vec3(1144.25, -596.875, 14.97),
+ position: toVector3(1144.25, -596.875, 14.97),
heading: 1.5,
blip: false,
name: "Portland",
},
{
- position: new Vec3(183.5, -17.75, 16.21),
+ position: toVector3(183.5, -17.75, 16.21),
heading: 3.14,
blip: false,
name: "Staunton Island",
},
{
- position: new Vec3(-1259.5, -44.5, 58.89),
+ position: toVector3(-1259.5, -44.5, 58.89),
heading: 1.5,
blip: false,
name: "Shoreside Vale",
},
],
[ // GTA VC
-
+ {
+ position: toVector3(493.14, 709.31, 11.80),
+ heading: 1.5,
+ blip: false,
+ name: "Unknown",
+ },
+ {
+ position: toVector3(-826.06, 1144.41, 12.41),
+ heading: 1.5,
+ blip: false,
+ name: "Unknown",
+ },
],
[ // GTA SA
-
+ {
+ position: toVector3(1172.96, -1323.42, 15.40),
+ heading: 1.5,
+ blip: false,
+ name: "All Saints",
+ },
+ {
+ position: toVector3(2034.04, -1405.07, 17.24),
+ heading: 1.5,
+ blip: false,
+ name: "County General",
+ },
],
[ // GTA UG
],
[ // GTA IV
{
- position: new Vec3(1199.59, 196.78, 33.554),
+ position: toVector3(1199.59, 196.78, 33.554),
heading: 1.633,
blip: false,
name: "Schottler",
},
{
- position: new Vec3(980.71, 1831.61, 23.898),
+ position: toVector3(980.71, 1831.61, 23.898),
heading: -0.049,
blip: false,
name: "Northern Gardens",
},
{
- position: new Vec3(-1317.27, 1277.20, 22.370),
+ position: toVector3(-1317.27, 1277.20, 22.370),
heading: 2.246,
blip: false,
name: "Leftwood",
},
{
- position: new Vec3(-1538.43, 344.58, 20.943),
+ position: toVector3(-1538.43, 344.58, 20.943),
heading: -0.156,
blip: false,
name: "Acter",
@@ -495,17 +521,17 @@ let serverData = {
false,
[ // GTA 3
{
- position: new Vec3(925.4, -360.3, 10.83),
+ position: toVector3(925.4, -360.3, 10.83),
blip: false,
name: "Portland",
},
{
- position: new Vec3(381.8, -493.8, 25.95),
+ position: toVector3(381.8, -493.8, 25.95),
blip: false,
name: "Staunton Island",
},
{
- position: new Vec3(-1142.4, 35.01, 58.61),
+ position: toVector3(-1142.4, 35.01, 58.61),
blip: false,
name: "Shoreside Vale",
},
@@ -528,12 +554,12 @@ let serverData = {
false,
[ // GTA 3
{
- position: new Vec3(1068.3, -400.9, 15.24),
+ position: toVector3(1068.3, -400.9, 15.24),
blip: false,
name: "Portland",
},
{
- position: new Vec3(348.2, -717.9, 26.43),
+ position: toVector3(348.2, -717.9, 26.43),
blip: false,
name: "Staunton Island",
},
@@ -556,7 +582,7 @@ let serverData = {
[ // GTA 3
{
- position: new Vec3(1161.9, -76.73, 7.27),
+ position: toVector3(1161.9, -76.73, 7.27),
blip: false,
name: "Portland",
},
@@ -572,548 +598,18 @@ let serverData = {
],
[ // GTA IV
- ]
+ ]
],
- jobs: [
- false,
- [ // GTA 3
- {
- name: "Police Officer",
- position: new Vec3(1143.87, -675.18, 14.97),
- pickup: false,
- pickupModel: 1383,
- blip: false,
- jobType: AG_JOB_POLICE,
- jobSkin: 1,
- jobColour: serverConfig.colour.byName.policeBlue,
- 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",
- position: new Vec3(1144.25, -596.87, 14.97),
- pickup: false,
- pickupModel: 1362,
- blip: false,
- jobType: AG_JOB_MEDICAL,
- jobSkin: 5,
- jobColour: serverConfig.colour.byName.medicPink,
- enabled: true
- },
- {
- name: "Firefighter",
- position: new Vec3(1103.70, -52.45, 7.49),
- pickup: false,
- pickupModel: 1364,
- blip: false,
- jobType: AG_JOB_FIRE,
- jobSkin: 6,
- jobColour: serverConfig.colour.byName.firefighterRed,
- enabled: true
- },
- {
- name: "Trash Collector",
- position: new Vec3(1121.8, 27.8, 1.99),
- pickup: false,
- pickupModel: 1351,
- blip: false,
- jobType: AG_JOB_GARBAGE,
- jobSkin: 53,
- jobColour: 2,
- enabled: true
- },
- {
- name: "Trash Collector",
- position: new Vec3(-66.83, -932.2, 16.47),
- pickup: false,
- pickupModel: 1351,
- blip: false,
- jobType: AG_JOB_GARBAGE,
- jobSkin: 53,
- jobColour: 2,
- enabled: true
- },
- {
- name: "Taxi Driver",
- position: new Vec3(1229.2, -740.1, 15.17),
- pickup: false,
- pickupModel: 1361,
- blip: false,
- jobType: AG_JOB_TAXI,
- jobSkin: 8,
- jobColour: 3,
- enabled: true
- },
- {
- name: "Bus Driver",
- position: new Vec3(1310.20, -1016.30, 14.88),
- pickup: false,
- pickupModel: 1361,
- blip: false,
- jobType: AG_JOB_BUS,
- jobSkin: 121,
- jobColour: 3,
- enabled: true
- },
- {
- name: "Police Officer",
- position: new Vec3(340.25, -1123.37, 25.98),
- pickup: false,
- pickupModel: 1361,
- blip: false,
- jobType: AG_JOB_POLICE,
- jobSkin: 1,
- jobColour: serverConfig.colour.byName.policeBlue,
- enabled: true,
- weapons: [[1,1], [2, 150], [4,20]],
- },
- {
- name: "Police Officer",
- position: new Vec3(-1253.0, -138.18, 58.75),
- pickup: false,
- pickupModel: 1361,
- blip: false,
- jobType: AG_JOB_POLICE,
- jobSkin: 1,
- jobColour: serverConfig.colour.byName.policeBlue,
- enabled: true,
- weapons: [[1,1], [2, 150], [4,20]],
- },
- {
- name: "Paramedic",
- position: new Vec3(183.5, -17.75, 16.21),
- pickup: false,
- pickupModel: 1361,
- blip: false,
- jobType: AG_JOB_MEDICAL,
- jobSkin: 5,
- jobColour: serverConfig.colour.byName.medicPink,
- enabled: true
- },
- {
- name: "Paramedic",
- position: new Vec3(-1259.5, -44.5, 58.89),
- pickup: false,
- pickupModel: 1361,
- blip: false,
- jobType: AG_JOB_MEDICAL,
- jobSkin: 5,
- jobColour: serverConfig.colour.byName.medicPink,
- enabled: true
- } ,
- {
- name: "Firefighter",
- position: new Vec3(-78.48, -436.80, 16.17),
- pickup: false,
- pickupModel: 1361,
- blip: false,
- jobType: AG_JOB_FIRE,
- jobSkin: 6,
- jobColour: serverConfig.colour.byName.firefighterRed,
- enabled: true
- },
- {
- name: "Firefighter",
- position: new Vec3(-1202.10, -14.67, 53.20),
- pickup: false,
- pickupModel: 1361,
- blip: false,
- jobType: AG_JOB_FIRE,
- jobSkin: 6,
- jobColour: serverConfig.colour.byName.firefighterRed,
- enabled: true
- },
- {
- name: "Taxi Driver",
- position: new Vec3(1229.2, -740.1, 15.17),
- pickup: false,
- pickupModel: 1361,
- blip: false,
- jobType: AG_JOB_TAXI,
- jobSkin: 8,
- jobColour: 3,
- enabled: true
- },
- {
- name: "Bus Driver",
- position: new Vec3(-57.1661, -334.266, 16.9324),
- pickup: false,
- pickupModel: 1361,
- blip: false,
- jobType: AG_JOB_BUS,
- jobSkin: 121,
- jobColour: 3,
- enabled: true
- },
- ],
- [ // 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
-
- ],
- [ // GTA UG
-
- ],
- [ // GTA IV
-
- ]
-
- //{ name: "Postal Worker" , position: Vector ( ) , pickup: false, pickupModel: 1361, blip: false, jobType: 7 },
- //{ name: "Delivery Worker" , position: Vector ( ) , pickup: false, pickupModel: 1361, blip: false, jobType: 8 },
- //{ name: "Mechanic" , position: Vector ( ) , pickup: false, pickupModel: 1361, blip: false, jobType: 9 },
- ],
- policeJobSkins: [
- false,
- [ // GTA III
- 1, 92,
- ],
- [ // GTA VC
- 1,
- ],
- [ // GTA SA
- 280, 281, 282, 283, 284, 285, 28, 288,
- ],
- [ // GTA UG
-
- ],
- [ // GTA IV
-
- ]
- ],
- medicalJobSkins: [
- false,
- [ // GTA III
- 5, 72, 73
- ],
- [ // GTA VC
- 5,
- ],
- [ // GTA SA
- 274, 275, 276
- ],
- [ // GTA UG
-
- ],
- [ // GTA IV
-
- ]
- ],
- fireJobSkins: [
- false,
- [ // GTA III
- 6
- ],
- [ // GTA VC
- 6,
- ],
- [ // GTA SA
- 277, 278, 279
- ],
- [ // GTA UG
-
- ],
- [ // GTA IV
-
- ]
- ],
- taxiJobSkins: [
- false,
- [ // GTA III
- 8,
- ],
- [ // GTA VC
- 8,
- ],
- [ // GTA SA
- 7, 142
- ],
- [ // GTA UG
-
- ],
- [ // GTA IV
-
- ]
- ],
- busJobSkins: [
- false,
- [ // GTA III
- 8,
- ],
- [ // GTA VC
- 8,
- ],
- [ // GTA SA
- 7, 142
- ],
- [ // GTA UG
-
- ],
- [ // GTA IV
-
- ]
- ],
- garbageJobSkins: [
- false,
- [ // GTA III
- 53, 54,
- ],
- [ // GTA VC
- 53, 54,
- ],
- [ // GTA SA
- 16,
- ],
- [ // GTA UG
-
- ],
- [ // GTA IV
-
- ]
- ],
};
// ----------------------------------------------------------------------------
function initServerData() {
// Pre-allocate translation cache language slots
- global.serverData.translation.cache = new Array(global.serverData.translation.languages.length);
- let translationCacheFrom = new Array(global.serverData.translation.languages.length);
+ global.getServerData().translation.cache = new Array(global.getServerData().translation.languages.length);
+ let translationCacheFrom = new Array(global.getServerData().translation.languages.length);
translationCacheFrom.fill([]);
- global.serverData.translation.cache.fill(translationCacheFrom);
+ global.getServerData().translation.cache.fill(translationCacheFrom);
}
// ----------------------------------------------------------------------------
@@ -1124,9 +620,8 @@ function getServerId() {
// ----------------------------------------------------------------------------
-function getServerGame() {
- return server.game;
+function getServerData() {
+ return serverData;
}
-// ----------------------------------------------------------------------------
-
+// ----------------------------------------------------------------------------
\ No newline at end of file
diff --git a/scripts/server/database.js b/scripts/server/database.js
index d70d7c28..03bd98c1 100644
--- a/scripts/server/database.js
+++ b/scripts/server/database.js
@@ -47,7 +47,7 @@ function connectToDatabase() {
console.log("[Asshat.Database] Initializing database connection ...");
persistentDatabaseConnection = module.mysql.connect(databaseConfig.host, databaseConfig.user, databaseConfig.pass, databaseConfig.name, databaseConfig.port);
if(persistentDatabaseConnection.error) {
- console.warn("[Asshat.Database] Database connection error: " + String(persistentDatabaseConnection.error));
+ console.warn("[Asshat.Database] Database connection error: " + toString(persistentDatabaseConnection.error));
persistentDatabaseConnection = null;
return false;
}
diff --git a/scripts/server/developer.js b/scripts/server/developer.js
index cd6ae8c4..b4999da7 100644
--- a/scripts/server/developer.js
+++ b/scripts/server/developer.js
@@ -85,8 +85,6 @@ function executeClientCodeCommand(command, params, client) {
let targetClient = getClientFromParams(splitParams[0]);
let targetCode = splitParams.slice(1).join(" ");
- console.log(targetCode);
-
if(!targetClient) {
messageClientError(client, "That player was not found!");
return false;
@@ -99,7 +97,7 @@ function executeClientCodeCommand(command, params, client) {
triggerNetworkEvent("ag.runCode", targetClient, targetCode);
- messageClientSuccess(client, "Executing client code for " + String(targetClient.name) + "!");
+ messageClientSuccess(client, "Executing client code for " + toString(targetClient.name) + "!");
messageClientNormal(client, "Code: " + targetCode);
return true;
}
@@ -173,7 +171,7 @@ addNetworkHandler("ag.runCodeFail", function(client, returnTo, code) {
// ---------------------------------------------------------------------------
-addNetworkHandler("ag.runCodeFail", function(client, returnTo, returnVal, code) {
+addNetworkHandler("ag.runCodeSuccess", function(client, returnTo, returnVal, code) {
let returnClient = getClientFromParams(returnTo);
if(!returnClient) {
return false;
@@ -187,20 +185,66 @@ addNetworkHandler("ag.runCodeFail", function(client, returnTo, returnVal, code)
// ---------------------------------------------------------------------------
function submitIdea(client, ideaText) {
+ let position = toVector3(0.0, 0.0, 0.0);
+ let heading = 0.0;
+ let session = 0;
+ let databaseId = 0;
+
+ if(client.getData("ag.position")) {
+ position = client.getData("ag.position");
+ }
+
+ if(client.getData("ag.heading")) {
+ heading = client.getData("ag.heading");
+ }
+
+ if(client.getData("ag.session")) {
+ session = client.getData("ag.session");
+ }
+
+ if(client.console) {
+ databaseId = -1
+ } else {
+ databaseId = getClientData(client).accountData.databaseId;
+ }
+
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")})`)
+ queryDatabase(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}', ${databaseId}, UNIX_TIMESTAMP(), '${safeIdeaMessage}',${position.x}, ${position.y}, ${position.z}, ${heading}, ${serverStartTime}, ${session})`);
}
}
// ---------------------------------------------------------------------------
function submitBugReport(client, bugText) {
+ let position = toVector3(0.0, 0.0, 0.0);
+ let heading = 0.0;
+ let session = 0;
+ let databaseId = 0;
+
+ if(client.getData("ag.position")) {
+ position = client.getData("ag.position");
+ }
+
+ if(client.getData("ag.heading")) {
+ heading = client.getData("ag.heading");
+ }
+
+ if(client.getData("ag.session")) {
+ session = client.getData("ag.session");
+ }
+
+ if(client.console) {
+ databaseId = -1
+ } else {
+ databaseId = getClientData(client).accountData.databaseId;
+ }
+
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")})`)
+ queryDatabase(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}', ${databaseId}, UNIX_TIMESTAMP(), '${safeBugMessage}', ${position.x}, ${position.y}, ${position.z}, ${heading}, ${serverStartTime}, ${session})`);
}
}
diff --git a/scripts/server/event.js b/scripts/server/event.js
index bbad21dc..89f494df 100644
--- a/scripts/server/event.js
+++ b/scripts/server/event.js
@@ -8,6 +8,14 @@
// TYPE: Server (JavaScript)
// ===========================================================================
+// ---------------------------------------------------------------------------
+
+addEventHandler("OnPlayerConnect", function(event, ipAddress, port) {
+ console.log(`[Asshat.Event] Client connecting (IP: ${ipAddress}, Port: ${port})`);
+});
+
+// ---------------------------------------------------------------------------
+
addEventHandler("OnPlayerJoined", function(event, client) {
setTimeout(function() {
initClient(client);
@@ -17,9 +25,11 @@ addEventHandler("OnPlayerJoined", function(event, client) {
// ---------------------------------------------------------------------------
addEventHandler("OnPlayerQuit", function(event, client, quitReasonId) {
+ //console.log(`[Asshat.Event] Client disconnected (Name: ${client.name}, Reason: ${gameData.quitReasons[quitReasonId]})`);
saveClientToDatabase(client);
- serverData.clients[client.index] = null;
+ getServerData().clients[client.index] = null;
+ //message(`${client.name} has left the server (${gameData.quitReasons[quitReasonId]})`);
});
// ---------------------------------------------------------------------------
@@ -27,7 +37,7 @@ addEventHandler("OnPlayerQuit", function(event, client, quitReasonId) {
addEventHandler("OnPedSpawn", function(event, ped) {
if(ped.isType(ELEMENT_PLAYER)) {
let client = getClientFromPlayerElement(ped);
- //triggerNetworkEvent("ag.locations", client, serverData.policeStations[getServerGame()], serverData.fireStations[getServerGame()], serverData.hospitals[getServerGame()], serverData.payAndSprays[getServerGame()], serverData.ammunations[getServerGame()], serverData.jobs[getServerGame()]);
+ //triggerNetworkEvent("ag.locations", client, getServerData().policeStations[getServerGame()], getServerData().fireStations[getServerGame()], getServerData().hospitals[getServerGame()], getServerData().payAndSprays[getServerGame()], getServerData().ammunations[getServerGame()], getServerData().jobs[getServerGame()]);
ped.setData("ag.name", getClientSubAccountName(client), true);
}
});
@@ -35,17 +45,13 @@ addEventHandler("OnPedSpawn", function(event, ped) {
// ---------------------------------------------------------------------------
addEventHandler("OnPedWasted", function(event, wastedPed, killerPed, weaponId, pedPiece) {
- if(ped.isType(ELEMENT_PLAYER)) {
- let closestHospital = getClosestHospital(wastedPed.position);
- let client = getClientFromPedElement(wastedPed);
- client.despawnPlayer();
- if(getClientCurrentSubAccount(client).inJail) {
- let closestJail = getClosestJail(wastedPed.position);
- spawnPlayer(client, closestJail.position, closestJail.heading, getClientCurrentSubAccount(client).skin);
- } else {
- spawnPlayer(client, closestHospital.position, closestHospital.heading, getClientCurrentSubAccount(client).skin);
- }
+ if(!wastedPed) {
+ return false;
}
+
+ //if(wastedPed.isType(ELEMENT_PLAYER)) {
+ // processPlayerDeath(wastedPed);
+ //}
});
// ---------------------------------------------------------------------------
@@ -72,49 +78,32 @@ addEventHandler("onPedEnterVehicle", function(event, ped, vehicle, seat) {
}
let vehicleData = getVehicleData(vehicle);
- if(!vehicleData) {
+ if(vehicleData == null) {
return false;
}
-
-
if(ped.isType(ELEMENT_PLAYER)) {
let client = getClientFromPlayerElement(ped);
- let currentSubAccount = getClientCurrentSubAccount(client);
-
- if(currentSubAccount.isWorking) {
- if(vehicleData.ownerType == AG_VEHOWNER_JOB) {
- if(vehicleData.ownerId == getJobType(currentSubAccount.job)) {
- if(seat == 0) {
- getClientCurrentSubAccount(client).lastJobVehicle = vehicle;
- }
- }
- }
- }
-
- if(vehicleData.buyPrice > 0) {
- messageClientInfo(client, `This vehicle is for sale! Cost $${vehicleData.buyPrice}`);
- messageClientInfo(client, `Use /buycar if you'd like to buy this vehicle.`);
- } else {
- if(vehicleData.rentPrice > 0) {
- messageClientInfo(client, `This vehicle is for rent! Cost: $${vehicleData.rentPrice} per minute`);
- messageClientInfo(client, `Use /rentcar if you'd like to rent this vehicle.`);
- }
- }
+ clientEnteredVehicle(client);
}
});
// ---------------------------------------------------------------------------
-addEventHandler("onEntityProcess", function(event, entity) {
- /*
- if(entity.isType(ELEMENT_PLAYER)) {
- let client = getClientFromPlayerElement(entity);
- if(isNearJobPoint(entity.position) {
- let jobPoint = getNearbyJobPoint(entity);
- }
- }
- */
+addEventHandler("onProcess", function(event, deltaTime) {
+ //if(!isGTAIV()) {
+ // let clients = getClients();
+ // for(let i in clients) {
+ // if(!clients[i].console) {
+ // if(clients[i].getData("ag.isPlaying")) {
+ // if(clients[i].player.health <= 0) {
+ // console.log(clients[i].name + " died");
+ // processPlayerDeath(clients[i]);
+ // }
+ // }
+ // }
+ // }
+ //}
});
// ---------------------------------------------------------------------------
@@ -139,4 +128,32 @@ addEventHandler("OnPedExitVehicle", function(event, ped, vehicle) {
if(!getVehicleData(vehicle)) {
return false;
}
-});
\ No newline at end of file
+});
+
+// ---------------------------------------------------------------------------
+
+function clientEnteredVehicle(client, vehicleData) {
+ let currentSubAccount = getClientCurrentSubAccount(client);
+
+ if(currentSubAccount.isWorking) {
+ if(vehicleData.ownerType == AG_VEHOWNER_JOB) {
+ if(vehicleData.ownerId == getJobType(currentSubAccount.job)) {
+ if(seat == 0) {
+ getClientCurrentSubAccount(client).lastJobVehicle = vehicleData.syncId;
+ }
+ }
+ }
+ }
+
+ if(vehicleData.buyPrice > 0) {
+ messageClientInfo(client, `This vehicle is for sale! Cost $${vehicleData.buyPrice}`);
+ messageClientInfo(client, `Use /vehbuy if you want to buy this vehicle.`);
+ } else {
+ if(vehicleData.rentPrice > 0) {
+ messageClientInfo(client, `This vehicle is for rent! Cost: $${vehicleData.rentPrice} per minute`);
+ messageClientInfo(client, `Use /vehrent if you want to rent this vehicle.`);
+ }
+ }
+}
+
+// ---------------------------------------------------------------------------
\ No newline at end of file
diff --git a/scripts/server/faction.js b/scripts/server/faction.js
index 79ee83ca..0eb5e708 100644
--- a/scripts/server/faction.js
+++ b/scripts/server/faction.js
@@ -8,6 +8,8 @@
// TYPE: Server (JavaScript)
// ===========================================================================
+// This system will probably be removed at some point.
+
function initFactionScript() {
console.log("[Asshat.Faction]: Initializing faction script ...");
addFactionCommandHandlers();
@@ -52,7 +54,7 @@ function loadFactionsFromDatabase() {
dbConnection.close();
}
- console.log("[Asshat.Faction]: " + String(tempFactions.length) + " factions loaded from database successfully!");
+ console.log("[Asshat.Faction]: " + toString(tempFactions.length) + " factions loaded from database successfully!");
return tempFactions;
}
diff --git a/scripts/server/help.js b/scripts/server/help.js
index ef329dfc..b3958ee7 100644
--- a/scripts/server/help.js
+++ b/scripts/server/help.js
@@ -99,7 +99,7 @@ function showAccountHelpMessage(client) {
function showEnteredDriverSeatHelpTip(client) {
if(getClientData(client).accountData.shownTips & !shownTipsFlags.enteredDriverSeat) {
- //messageClientInfo(client, `Press ${serverConfig.keybindText.vehicleEngineKey} for engine, ${serverConfig.keybindText.vehicleLightsKey} for lights, and ${serverConfig.keybindText.vehicleLockKey} for door locks`);
+ messageClientInfo(client, `Press ${getServerConfig().keybindText.vehicleEngineKey} for engine, ${getServerConfig().keybindText.vehicleLightsKey} for lights, and ${getServerConfig().keybindText.vehicleLockKey} for door locks`);
getClientData(client).accountData.shownTips = getClientData(client).accountData.shownTips | shownTipsFlags.enteredDriverSeat;
}
}
@@ -108,7 +108,7 @@ function showEnteredDriverSeatHelpTip(client) {
function showApproachJobWhileUnemployedTip(client) {
if(getClientData(client).accountData.shownTips & !shownTipsFlags.approachJobWhileUnemployed) {
- //messageClientInfo(client, `Approach the icon and press ${serverConfig.keybindText.actionKey} to see info about this job.`);
+ messageClientInfo(client, `Approach the icon and press ${getServerConfig().keybindText.actionKey} to see info about this job.`);
getClientData(client).accountData.shownTips = getClientData(client).accountData.shownTips | shownTipsFlags.approachJobWhileUnemployed;
}
}
@@ -117,7 +117,7 @@ function showApproachJobWhileUnemployedTip(client) {
function showTakeNearbyJobTip(client) {
if(getClientData(client).accountData.shownTips & !shownTipsFlags.takeJobWhileUnemployed) {
- //messageClientInfo(client, `Use /takejob to take this job.`);
+ messageClientInfo(client, `Use /takejob to take this job.`);
getClientData(client).accountData.shownTips = getClientData(client).accountData.shownTips | shownTipsFlags.takeJobWhileUnemployed;
}
}
@@ -126,8 +126,8 @@ function showTakeNearbyJobTip(client) {
function showApproachCurrentJobTip(client) {
if(getClientData(client).accountData.shownTips & !shownTipsFlags.approachCurrentJob) {
- //messageClientInfo(client, `Press ${serverConfig.keybindText.actionKey} to start working, or hold ${serverConfig.keybindText.actionKey} to quit your job.`);
- //messageClientInfo(client, `Use /startwork to start working, or /quitjob to quit your job.`);
+ //messageClientTip(client, `Press ${getServerConfig().keybindText.actionKey} to start working, or hold ${getServerConfig().keybindText.actionKey} to quit your job.`);
+ messageClientTip(client, `Use /startwork to start working, or /quitjob to quit your job.`);
getClientData(client).accountData.shownTips = getClientData(client).accountData.shownTips | shownTipsFlags.approachCurrentJob;
}
}
@@ -136,7 +136,8 @@ function showApproachCurrentJobTip(client) {
function showStartedWorkingTip(client) {
if(getClientData(client).accountData.shownTips & !shownTipsFlags.startedWorking) {
- messageClientInfo(client, `Press ${serverConfig.keybindText.actionKey} to change uniform, or hold ${serverConfig.keybindText.actionKey} to stop working.`);
+ //messageClientTip(client, `Press ${getServerConfig().keybindText.actionKey} to change uniform, or hold ${getServerConfig().keybindText.actionKey} to stop working.`);
+ messageClientTip(client, `Use /uniform to see job skins and /equip to see available jobs tools and weapons.`);
getClientData(client).accountData.shownTips = getClientData(client).accountData.shownTips | shownTipsFlags.startedWorking;
}
}
@@ -145,7 +146,7 @@ function showStartedWorkingTip(client) {
function showApproachOwnedVehicleTip(client) {
if(getClientData(client).accountData.shownTips & !shownTipsFlags.approachOwnedVehicle) {
- messageClientInfo(client, `Press ${serverConfig.keybindText.actionKey} to see vehicle info, or press ${serverConfig.keybindText.vehicleLockKey} to lock and unlock the vehicle.`);
+ messageClientTip(client, `Press ${getServerConfig().keybindText.actionKey} to see vehicle info, or press ${getServerConfig().keybindText.vehicleLockKey} to lock and unlock the vehicle.`);
getClientData(client).accountData.shownTips = getClientData(client).accountData.shownTips | shownTipsFlags.approachOwnedVehicle;
}
}
@@ -154,7 +155,7 @@ function showApproachOwnedVehicleTip(client) {
function showApproachAnyVehicleTip(client) {
if(getClientData(client).accountData.shownTips & !shownTipsFlags.approachAnyVehicle) {
- messageClientInfo(client, `Press ${serverConfig.keybindText.actionKey} to see vehicle info.`);
+ messageClientTip(client, `Press ${getServerConfig().keybindText.actionKey} to see vehicle info.`);
getClientData(client).accountData.shownTips = getClientData(client).accountData.shownTips | shownTipsFlags.approachAnyVehicle;
}
}
diff --git a/scripts/server/house.js b/scripts/server/house.js
index 5be96945..03890b1e 100644
--- a/scripts/server/house.js
+++ b/scripts/server/house.js
@@ -10,7 +10,7 @@
function initHouseScript() {
console.log("[Asshat.House]: Initializing house script ...");
- serverData.houses = loadHousesFromDatabase();
+ getServerData().houses = loadHousesFromDatabase();
createAllHousePickups();
addHouseCommandHandlers();
console.log("[Asshat.House]: House script initialized successfully!");
@@ -35,29 +35,30 @@ function loadHousesFromDatabase() {
console.log("[Asshat.House]: Loading houses from database ...");
let tempHouses = [];
let dbConnection = connectToDatabase();
+ let dbAssoc;
if(dbConnection) {
- let dbQuery = queryDatabase(dbConnection, "SELECT * FROM `house_main` WHERE `house_server` = " + String(serverId))
+ let dbQuery = queryDatabase(dbConnection, "SELECT * FROM `house_main` WHERE `house_server` = " + toString(serverId))
if(dbQuery) {
if(dbQuery.numRows > 0) {
- while(dbFetchAssoc = fetchQueryAssoc(dbQuery)) {
- let tempHouseData = getClasses().houseData(dbFetchAssoc);
+ while(dbAssoc = fetchQueryAssoc(dbQuery)) {
+ let tempHouseData = serverClasses.houseData(dbAssoc);
tempHouses.push(tempHouseData);
- console.log("[Asshat.House]: Houses '" + String(tempHouseData.databaseId) + "' loaded!");
+ console.log("[Asshat.House]: Houses '" + toString(tempHouseData.databaseId) + "' loaded!");
}
}
freeDatabaseQuery(dbQuery);
}
disconnectFromDatabase(dbConnection);
}
- console.log("[Asshat.House]: " + String(tempHouses.length) + " houses loaded from database successfully!");
+ console.log("[Asshat.House]: " + toString(tempHouses.length) + " houses loaded from database successfully!");
return tempHouses;
}
// ---------------------------------------------------------------------------
function getHouseDataFromDatabaseId(databaseId) {
- let matchingHouses = serverData.houses.filter(b => b.databaseId == databaseId)
+ let matchingHouses = getServerData().houses.filter(b => b.databaseId == databaseId)
if(matchingHouses.length == 1) {
return matchingHouses[0];
}
@@ -67,7 +68,7 @@ function getHouseDataFromDatabaseId(databaseId) {
// ---------------------------------------------------------------------------
function getClosestHouseEntrance(position) {
- return serverData.houses.reduce((i, j) => ((i.entrancePosition.distance(position) <= j.entrancePosition.distance(position)) ? i : j));
+ return getServerData().houses.reduce((i, j) => ((i.entrancePosition.distance(position) <= j.entrancePosition.distance(position)) ? i : j));
}
// ---------------------------------------------------------------------------
@@ -99,10 +100,10 @@ function saveAllHousesToDatabase() {
// ---------------------------------------------------------------------------
function createAllHousePickups() {
- for(let i in serverData.houses) {
- serverData.houses.pickup = createPickup(serverConfig.housePickupModel, serverData.houses[i].position);
- serverData.houses[i].pickup.setData("ag.ownerType", AG_PICKUP_HOUSE, true);
- serverData.houses[i].pickup.setData("ag.ownerId", i, true);
+ for(let i in getServerData().houses) {
+ getServerData().houses.pickup = createPickup(getServerConfig().housePickupModel, getServerData().houses[i].position);
+ getServerData().houses[i].pickup.setData("ag.ownerType", AG_PICKUP_HOUSE, true);
+ getServerData().houses[i].pickup.setData("ag.ownerId", i, true);
}
}
diff --git a/scripts/server/job.js b/scripts/server/job.js
index 039249b2..b52536fa 100644
--- a/scripts/server/job.js
+++ b/scripts/server/job.js
@@ -10,7 +10,8 @@
function initJobScript() {
console.log("[Asshat.Job]: Initializing job script ...");
- loadJobsFromDatabase();
+ getServerData().jobs = loadJobsFromDatabase();
+
addJobCommandHandlers();
createAllJobPickups();
createAllJobBlips();
@@ -44,14 +45,14 @@ function loadJobsFromDatabase() {
let dbAssoc;
if(dbConnection) {
- dbQuery = queryDatabase(dbConnection, "SELECT * FROM `job_main` WHERE `job_enabled` = 1 AND `job_server` = " + String(serverId));
+ dbQuery = queryDatabase(dbConnection, "SELECT * FROM `job_main` WHERE `job_enabled` = 1 AND `job_server` = " + toString(serverId));
if(dbQuery) {
if(dbQuery.numRows > 0) {
while(dbAssoc = fetchQueryAssoc(dbQuery)) {
let tempJobData = new serverClasses.jobData(dbAssoc);
+ tempJobData.locations = loadJobLocationsFromDatabase(tempJobData.databaseId);
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!`);
}
@@ -67,6 +68,30 @@ function loadJobsFromDatabase() {
// ---------------------------------------------------------------------------
+function loadAllJobEquipmentFromDatabase() {
+ for(let i in getServerData().jobs) {
+ getServerData().jobs[i].equipment = loadJobEquipmentsFromDatabase(getServerData().jobs[i].databaseId);
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+function loadAllJobUniformsFromDatabase() {
+ for(let i in getServerData().jobs) {
+ getServerData().jobs[i].uniforms = loadJobUniformsFromDatabase(getServerData().jobs[i].databaseId);
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+function loadAllJobLocationsFromDatabase() {
+ for(let i in getServerData().jobs) {
+ getServerData().jobs[i].locations = loadJobLocationsFromDatabase(getServerData().jobs[i].databaseId);
+ }
+}
+
+// ---------------------------------------------------------------------------
+
function loadJobEquipmentsFromDatabase(jobDatabaseId) {
console.log(`[Asshat.Job]: Loading job equipments for job ${jobDatabaseId} from database ...`);
@@ -76,7 +101,7 @@ function loadJobEquipmentsFromDatabase(jobDatabaseId) {
let dbAssoc;
if(dbConnection) {
- dbQuery = queryDatabase(dbConnection, "SELECT * FROM `job_equip` WHERE `job_equip_enabled` = 1 AND `job_equip_job` = " + String(jobDatabaseId));
+ dbQuery = queryDatabase(dbConnection, "SELECT * FROM `job_equip` WHERE `job_equip_enabled` = 1 AND `job_equip_job` = " + toString(jobDatabaseId));
if(dbQuery) {
if(dbQuery.numRows > 0) {
while(dbAssoc = fetchQueryAssoc(dbQuery)) {
@@ -106,7 +131,7 @@ function loadJobLocationsFromDatabase(jobDatabaseId) {
let dbAssoc;
if(dbConnection) {
- dbQuery = queryDatabase(dbConnection, "SELECT * FROM `job_loc` WHERE `job_loc_enabled` = 1 AND `job_loc_job` = " + String(jobDatabaseId));
+ dbQuery = queryDatabase(dbConnection, "SELECT * FROM `job_loc` WHERE `job_loc_enabled` = 1 AND `job_loc_job` = " + toString(jobDatabaseId));
if(dbQuery) {
if(dbQuery.numRows > 0) {
while(dbAssoc = fetchQueryAssoc(dbQuery)) {
@@ -135,7 +160,7 @@ function loadJobUniformsFromDatabase(jobDatabaseId) {
let dbAssoc;
if(dbConnection) {
- dbQuery = queryDatabase(dbConnection, "SELECT * FROM `job_uniform` WHERE `job_uniform_enabled` = 1 AND `job_uniform_job` = " + String(jobDatabaseId));
+ dbQuery = queryDatabase(dbConnection, "SELECT * FROM `job_uniform` WHERE `job_uniform_enabled` = 1 AND `job_uniform_job` = " + toString(jobDatabaseId));
if(dbQuery) {
if(dbQuery.numRows > 0) {
while(dbAssoc = fetchQueryAssoc(dbQuery)) {
@@ -164,7 +189,7 @@ function loadJobEquipmentWeaponsFromDatabase(jobEquipmentDatabaseId) {
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));
+ dbQuery = queryDatabase(dbConnection, "SELECT * FROM `job_equip_wep` WHERE `job_equip_wep_enabled` = 1 AND `job_equip_wep_equip` = " + toString(jobEquipmentDatabaseId));
if(dbQuery) {
if(dbQuery.numRows > 0) {
while(dbAssoc = fetchQueryAssoc(dbQuery)) {
@@ -185,11 +210,12 @@ function loadJobEquipmentWeaponsFromDatabase(jobEquipmentDatabaseId) {
// ---------------------------------------------------------------------------
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] Spawning all job location blips ...`);
+ for(let i in getServerData().jobs) {
+ for(let j in getServerData().jobs[i].locations) {
+ getServerData().jobs[i].locations[j].blip = gta.createBlip((getServerData().jobs[i].blipModel!=0) ? getServerData().jobs[i].blipModel : 0, getServerData().jobs[i].locations[j].position, 2, getColourByName("yellow"));
+ addToWorld(getServerData().jobs[i].locations[j].blip);
+ console.log(`[Asshat.Job] Job '${getServerData().jobs[i].name}' location blip ${j} spawned!`);
}
}
console.log(`[Asshat.Job] All job location blips spawned!`);
@@ -198,18 +224,22 @@ function createAllJobBlips() {
// ---------------------------------------------------------------------------
function createAllJobPickups() {
- 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);
+ console.log(`[Asshat.Job] Spawning all job location pickups ...`);
+ let pickupCount = 0;
+ for(let i in getServerData().jobs) {
+ if(getServerData().jobs[i].pickupModel != 0) {
+ for(let j in getServerData().jobs[i].locations) {
+ pickupCount++;
+ getServerData().jobs[i].locations[j].pickup = gta.createPickup(getServerData().jobs[i].pickupModel, getServerData().jobs[i].locations[j].position);
+ getServerData().jobs[i].locations[j].pickup.setData("ag.ownerType", AG_PICKUP_JOB, true);
+ getServerData().jobs[i].locations[j].pickup.setData("ag.ownerId", i, true);
+ addToWorld(getServerData().jobs[i].locations[j].pickup);
- console.log(`[Asshat.Job] Job '${serverData.jobs[i].name}' location pickup ${j} spawned!`);
+ console.log(`[Asshat.Job] Job '${getServerData().jobs[i].name}' location pickup ${j} spawned!`);
}
}
}
- console.log(`[Asshat.Job] All job location pickups spawned!`);
+ console.log(`[Asshat.Job] All job location pickups (${pickupCount}) spawned!`);
}
// ---------------------------------------------------------------------------
@@ -330,18 +360,18 @@ function takeJobCommand(command, params, client) {
let closestJobLocation = getClosestJobLocation(client.player.position);
let jobData = getJobData(closestJobLocation.job);
- if(closestJobLocation.position.distance(client.player.position) > serverConfig.takeJobDistance) {
+ if(closestJobLocation.position.distance(client.player.position) > getServerConfig().takeJobDistance) {
messageClientError(client, "There are no job points close enough!");
return false;
}
- if(getClientCurrentSubAccount(client).job != AG_JOB_NONE) {
+ if(getClientCurrentSubAccount(client).job > AG_JOB_NONE) {
messageClientError(client, "You already have a job! Use /quitjob to quit your job.");
return false;
}
takeJob(client, closestJobLocation.job);
- messageClientSuccess(client, "You now have the " + String(jobData.name) + " job");
+ messageClientSuccess(client, "You now have the " + toString(jobData.name) + " job");
return true;
}
@@ -374,12 +404,12 @@ function startWorkingCommand(command, params, client) {
let closestJobLocation = getClosestJobLocation(client.player.position);
let jobData = getJobData(closestJobLocation.job);
- if(closestJobLocation.position.distance(client.player.position) > serverConfig.startWorkingDistance) {
+ if(closestJobLocation.position.distance(client.player.position) > getServerConfig().startWorkingDistance) {
messageClientError(client, "There are no job points close enough!");
return false;
- }
+ }
- if(getJobType(getClientCurrentSubAccount(client).job) == AG_JOB_NONE) {
+ if(getClientCurrentSubAccount(client).job == AG_JOB_NONE) {
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;
@@ -392,7 +422,7 @@ function startWorkingCommand(command, params, client) {
}
- messageClientSuccess(client, "You are now working as a " + String(jobData.name));
+ messageClientSuccess(client, "You are now working as a " + toString(jobData.name));
startWorking(client);
//showStartedWorkingTip(client);
return true;
@@ -426,7 +456,7 @@ function stopWorkingCommand(command, params, client) {
let closestJobLocation = getClosestJobLocation(client.player.position);
- if(closestJobLocation.position.distance(client.player.position) > serverConfig.stopWorkingDistance) {
+ if(closestJobLocation.position.distance(client.player.position) > getServerConfig().stopWorkingDistance) {
messageClientError(client, "There are no job locations close enough!");
return false;
}
@@ -494,13 +524,15 @@ function startWorking(client) {
// ---------------------------------------------------------------------------
function givePlayerJobEquipment(client, equipmentId) {
- if(!canClientUseJobs(client)){
+ 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);
+ let equipments = getJobData(jobId).equipment;
+
+ for(let i in equipments[equipmentId].weapons) {
+ triggerNetworkEvent("ag.giveWeapon", client, equipments[equipmentId].weapons[i].weaponId, equipments[equipmentId].weapons[i].ammo, false);
}
}
@@ -595,31 +627,33 @@ function jobUniformCommand(command, params, client) {
return false;
}
- let jobId = getClientCurrentSubAccount(client).job
+ let jobId = getClientCurrentSubAccount(client).job;
+ let uniforms = getJobData(jobId).uniforms;
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})`);
+ messageClientNormal(client, `0: No uniform (sets you back to your main skin)`);
+
+ for(let i in uniforms) {
+ messageClientNormal(client, `${toInteger(i)+1}: ${uniforms[i].name} (Requires rank ${uniforms[i].requiredRank})`);
}
return false;
}
+ let uniformId = toInteger(params) || 1;
if(uniformId == 0) {
- getClientCurrentSubAccount(client).jobUniform = false;
triggerNetworkEvent("ag.skin", client, getClientCurrentSubAccount(client).skin);
messageClientSuccess(client, "You changed your uniform to (none)");
- return;
+ return true;
}
- let uniformId = Number(params) || 1;
- if(uniformId < 1 || uniformId > serverData.jobs[jobId].uniforms.length-1) {
+ if(uniformId < 1 || uniformId > uniforms.length) {
messageClientError(client, "That uniform ID is invalid!");
return false;
}
- triggerNetworkEvent("ag.skin", client, serverData.jobs[jobId].uniforms[uniformId].skin);
+ messageClientSuccess(client, `You put on the ${uniforms[uniformId-1].name} uniform`);
+ triggerNetworkEvent("ag.skin", client, uniforms[uniformId-1].skin);
}
// ---------------------------------------------------------------------------
@@ -644,11 +678,32 @@ function jobEquipmentCommand(command, params, client) {
return false;
}
- let equipmentId = Number(params) || 1;
-
let jobId = getClientCurrentSubAccount(client).job;
-
- givePlayerJobEquipment(client, equipmentId);
+ let equipments = getJobData(jobId).equipment;
+
+ if(areParamsEmpty(params)) {
+ messageClientSyntax(client, getCommandSyntaxText(command));
+ messageClientNormal(client, `0: No equipment`);
+ for(let i in equipments) {
+ messageClientNormal(client, `${toInteger(i)+1}: ${equipments[i].name} (Requires rank ${equipments[i].requiredRank})`);
+ }
+ return false;
+ }
+
+ let equipmentId = toInteger(params) || 1;
+
+ if(equipmentId == 0) {
+ messageClientSuccess(client, "You put your equipment away");
+ return true;
+ }
+
+ if(equipmentId < 1 || equipmentId > equipments.length) {
+ messageClientError(client, "That equipment ID is invalid!");
+ return false;
+ }
+
+ givePlayerJobEquipment(client, equipmentId-1);
+ messageClientSuccess(client, `You have been given the ${equipments[equipmentId-1].name} equipment`);
}
// ---------------------------------------------------------------------------
@@ -749,9 +804,9 @@ function getJobType(jobId) {
// ---------------------------------------------------------------------------
function getJobData(jobId) {
- for(let i in serverData.jobs) {
- if(serverData.jobs[i].databaseId == jobId) {
- return serverData.jobs[i];
+ for(let i in getServerData().jobs) {
+ if(getServerData().jobs[i].databaseId == jobId) {
+ return getServerData().jobs[i];
}
}
return false;
@@ -770,4 +825,41 @@ function takeJob(client, jobId) {
getClientCurrentSubAccount(client).job = jobId;
}
+// ---------------------------------------------------------------------------
+
+function reloadAllJobsCommand(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;
+ }
+
+ for(let i in getServerData().jobs) {
+ for(let j in getServerData().jobs[i].locations) {
+ destroyElement(getServerData().jobs[i].locations[j].blip);
+ destroyElement(getServerData().jobs[i].locations[j].pickup);
+ }
+ }
+
+ getServerData().jobs = null;
+ getServerData().jobs = loadJobsFromDatabase();
+ createAllJobPickups();
+ createAllJobBlips();
+
+ messageAdminAction(`All server jobs have been reloaded by an admin!`);
+}
+
// ---------------------------------------------------------------------------
\ No newline at end of file
diff --git a/scripts/server/job/bus.js b/scripts/server/job/bus.js
index 8577d862..b0126ab1 100644
--- a/scripts/server/job/bus.js
+++ b/scripts/server/job/bus.js
@@ -19,26 +19,26 @@ let busRoutes = [
island: 1,
busColour: toColour(120, 0, 0, 255),
positions: [
- new Vec3(1269, -1056.4, 14.75),
- new Vec3(1088.7, -968.8, 14.91),
- new Vec3(1059.1, -870.9, 14.91),
- new Vec3(917.6, -815.9, 14.91),
- new Vec3(851.1, -766.1, 14.91),
- new Vec3(838.8, -598.7, 14.91),
- new Vec3(959.3, -581.6, 14.91),
- new Vec3(853.1, -485.9, 14.91),
- new Vec3(838.8, -312.68, 6.8),
- new Vec3(913.9, -177.4, 4.91),
- new Vec3(1123.3, -67.74, 7.41),
- new Vec3(1043.6, -191.63, 4.91),
- new Vec3(1213.2, -281.3, 25.76),
- new Vec3(1193.3, -474.3, 24.98),
- new Vec3(1335.4, -499.7, 45.28),
- new Vec3(1220.3, -341.4, 26.38),
- new Vec3(1122.6, -475.6, 19.91),
- new Vec3(1309.2, -642.4, 12.3),
- new Vec3(1350.5, -845, 14.91),
- new Vec3(1322.2, -1025.3, 14.76),
+ toVector3(1269, -1056.4, 14.75),
+ toVector3(1088.7, -968.8, 14.91),
+ toVector3(1059.1, -870.9, 14.91),
+ toVector3(917.6, -815.9, 14.91),
+ toVector3(851.1, -766.1, 14.91),
+ toVector3(838.8, -598.7, 14.91),
+ toVector3(959.3, -581.6, 14.91),
+ toVector3(853.1, -485.9, 14.91),
+ toVector3(838.8, -312.68, 6.8),
+ toVector3(913.9, -177.4, 4.91),
+ toVector3(1123.3, -67.74, 7.41),
+ toVector3(1043.6, -191.63, 4.91),
+ toVector3(1213.2, -281.3, 25.76),
+ toVector3(1193.3, -474.3, 24.98),
+ toVector3(1335.4, -499.7, 45.28),
+ toVector3(1220.3, -341.4, 26.38),
+ toVector3(1122.6, -475.6, 19.91),
+ toVector3(1309.2, -642.4, 12.3),
+ toVector3(1350.5, -845, 14.91),
+ toVector3(1322.2, -1025.3, 14.76),
],
},
@@ -48,32 +48,32 @@ let busRoutes = [
island: 2,
busColour: toColour(120, 0, 0, 255),
positions: [
- new Vec3(-1.11, -388.4, 16.11),
- new Vec3(-15.75, -735.3, 26.15),
- new Vec3(33.63, -1029.4, 26.11),
- new Vec3(-53.92, -1233.4, 26.11),
- new Vec3(126.58, -1323.7, 26.11),
- new Vec3(189.39, -1285.6, 26.11),
- new Vec3(266.9, -1179.1, 26.11),
- new Vec3(283.93, -1370.2, 26.11),
- new Vec3(144.44, -1455.5, 26.11),
- new Vec3(34.5, -1511.7, 26.11),
- new Vec3(325.31, -1579, 26.03),
- new Vec3(302.33, -1417.7, 26.11),
- new Vec3(309.76, -1290, 26.11),
- new Vec3(378.5, -1235.1, 26.11),
- new Vec3(404, -1376.3, 26.11),
- new Vec3(189.07, -1159.3, 26.11),
- new Vec3(189.44, -956.9, 26.11),
- new Vec3(254.18, -722.3, 26.11),
- new Vec3(383.4, -704.2, 26.11),
- new Vec3(429.3, -420.6, 22.04),
- new Vec3(570.9, -336.4, 19.71),
- new Vec3(267.46, 91.12, 15.96),
- new Vec3(99.13, -31.96, 16.11),
- new Vec3(243.94, -187.01, 21.31),
- new Vec3(99.17, -263.44, 16.11),
- new Vec3(-26.92, -283.73, 16.11),
+ toVector3(-1.11, -388.4, 16.11),
+ toVector3(-15.75, -735.3, 26.15),
+ toVector3(33.63, -1029.4, 26.11),
+ toVector3(-53.92, -1233.4, 26.11),
+ toVector3(126.58, -1323.7, 26.11),
+ toVector3(189.39, -1285.6, 26.11),
+ toVector3(266.9, -1179.1, 26.11),
+ toVector3(283.93, -1370.2, 26.11),
+ toVector3(144.44, -1455.5, 26.11),
+ toVector3(34.5, -1511.7, 26.11),
+ toVector3(325.31, -1579, 26.03),
+ toVector3(302.33, -1417.7, 26.11),
+ toVector3(309.76, -1290, 26.11),
+ toVector3(378.5, -1235.1, 26.11),
+ toVector3(404, -1376.3, 26.11),
+ toVector3(189.07, -1159.3, 26.11),
+ toVector3(189.44, -956.9, 26.11),
+ toVector3(254.18, -722.3, 26.11),
+ toVector3(383.4, -704.2, 26.11),
+ toVector3(429.3, -420.6, 22.04),
+ toVector3(570.9, -336.4, 19.71),
+ toVector3(267.46, 91.12, 15.96),
+ toVector3(99.13, -31.96, 16.11),
+ toVector3(243.94, -187.01, 21.31),
+ toVector3(99.17, -263.44, 16.11),
+ toVector3(-26.92, -283.73, 16.11),
],
},
],
@@ -88,10 +88,50 @@ let busRoutes = [
],
- false,
+ // GTA UG
+ [
+
+ ],
// GTA IV
[
],
-];
\ No newline at end of file
+];
+
+// ---------------------------------------------------------------------------
+
+function getNextStopOnBusRoute(client) {
+ if(client.getData("ag.busRoute") && client.getData("ag.lastBusStop")) {
+ if(!isGoingToLastStopOnBusRoute(client)) {
+ return busRoutes[server.game][client.getData("ag.busRoute")][client.getData("ag.lastBusStop")+1];
+ } else {
+ let slot = busRoutes[server.game][client.getData("ag.busRoute")].length-1;
+ return busRoutes[server.game][client.getData("ag.busRoute")][slot];
+ }
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+function isGoingToLastStopOnBusRoute(client) {
+ if(client.getData("ag.busRoute") && client.getData("ag.lastBusStop")) {
+ if(client.getData("ag.lastBusStop")+1 == busRoutes[server.game][client.getData("ag.busRoute")].length-1) {
+ return true;
+ }
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+function freezeBusForStop(client) {
+ triggerNetworkEvent("ag.freeze", client, true);
+}
+
+// ---------------------------------------------------------------------------
+
+function unFreezeBusForStop(client) {
+ triggerNetworkEvent("ag.freeze", client, false);
+}
+
+// ---------------------------------------------------------------------------
\ No newline at end of file
diff --git a/scripts/server/job/garbage.js b/scripts/server/job/garbage.js
index 810faea4..fdbb2a44 100644
--- a/scripts/server/job/garbage.js
+++ b/scripts/server/job/garbage.js
@@ -18,20 +18,20 @@ let garbageRoutes = [
name: "Portland #1",
island: 1,
positions: [
- new Vec3(1169.8, -45.54, 10.4),
- new Vec3(928, -59.1, 8.61),
- new Vec3(935.4, -262.45, 5.52),
- new Vec3(935.4, -262.45, 5.52),
- new Vec3(1042.5, -375.9, 15.4),
- new Vec3(987, -450.5, 15.39),
- new Vec3(871.3, -277.07, 5.4),
- new Vec3(1119.4, -766.7, 15.4),
- new Vec3(1082.3, -990.8, 15.4),
- new Vec3(1166.9, -1046.8, 15.41),
- new Vec3(1310.1, -980.4, 15.46),
- new Vec3(1129.5, -645.3, 15.4),
- new Vec3(1128.9, -446.1, 20.41),
- new Vec3(1226.5, -52.41, 10.42) ,
+ toVector3(1169.8, -45.54, 10.4),
+ toVector3(928, -59.1, 8.61),
+ toVector3(935.4, -262.45, 5.52),
+ toVector3(935.4, -262.45, 5.52),
+ toVector3(1042.5, -375.9, 15.4),
+ toVector3(987, -450.5, 15.39),
+ toVector3(871.3, -277.07, 5.4),
+ toVector3(1119.4, -766.7, 15.4),
+ toVector3(1082.3, -990.8, 15.4),
+ toVector3(1166.9, -1046.8, 15.41),
+ toVector3(1310.1, -980.4, 15.46),
+ toVector3(1129.5, -645.3, 15.4),
+ toVector3(1128.9, -446.1, 20.41),
+ toVector3(1226.5, -52.41, 10.42) ,
],
},
@@ -40,15 +40,15 @@ let garbageRoutes = [
name: "Staunton #1",
island: 2,
positions: [
- new Vec3(49.85, -1539.9, 26.6),
- new Vec3(49.71, -1458.1, 26.6),
- new Vec3(170.78, -1403.8, 26.59),
- new Vec3(183.48, -1485.9, 26.6),
- new Vec3(320.43, -1452.4, 26.6),
- new Vec3(310.13, -1311.8, 26.6),
- new Vec3(134.76, -1097.7, 26.6),
- new Vec3(55.63, -1058.6, 26.6),
- new Vec3(-0.02, -790.9, 26.64),
+ toVector3(49.85, -1539.9, 26.6),
+ toVector3(49.71, -1458.1, 26.6),
+ toVector3(170.78, -1403.8, 26.59),
+ toVector3(183.48, -1485.9, 26.6),
+ toVector3(320.43, -1452.4, 26.6),
+ toVector3(310.13, -1311.8, 26.6),
+ toVector3(134.76, -1097.7, 26.6),
+ toVector3(55.63, -1058.6, 26.6),
+ toVector3(-0.02, -790.9, 26.64),
],
},
],
diff --git a/scripts/server/messaging.js b/scripts/server/messaging.js
index 0438731d..1587dc14 100644
--- a/scripts/server/messaging.js
+++ b/scripts/server/messaging.js
@@ -18,16 +18,26 @@ function messageAdminAction(messageText) {
// ---------------------------------------------------------------------------
function messageClientNormal(client, messageText, colour = COLOUR_WHITE) {
+ if(client.console) {
+ console.log(`${messageText}`);
+ return true;
+ }
+
if(client instanceof Client) {
messageClient(`${messageText}`, client, colour);
} else {
- messageDiscordUser(client, `:no_entry_sign: ${messageText}`);
+ messageDiscordUser(client, `${messageText}`);
}
}
// ---------------------------------------------------------------------------
function messageClientError(client, messageText) {
+ if(client.console) {
+ console.log(`🚫 ${messageText}`);
+ return true;
+ }
+
if(client instanceof Client) {
messageClientNormal(client, `🚫 ${messageText}`, getColourByType("errorMessage"));
} else {
@@ -38,8 +48,13 @@ function messageClientError(client, messageText) {
// ---------------------------------------------------------------------------
function messageClientSyntax(client, messageText) {
+ if(client.console) {
+ console.log(`⌨️ ${messageText}`);
+ return true;
+ }
+
if(client instanceof Client) {
- messageClientNormal(client, `⌨️ [#FFFFFF] ${messageText}`, getColourByType("syntaxMessage"));
+ messageClientNormal(client, `⌨️ USAGE: [#FFFFFF] ${messageText}`, getColourByType("syntaxMessage"));
} else {
messageDiscordUser(client, `:keyboard: ${messageText}`);
}
@@ -48,6 +63,11 @@ function messageClientSyntax(client, messageText) {
// ---------------------------------------------------------------------------
function messageClientAlert(client, messageText) {
+ if(client.console) {
+ console.log(`⚠️ ${messageText}`);
+ return true;
+ }
+
if(client instanceof Client) {
messageClientNormal(client, `⚠️ [#FFFFFF] ${messageText}`, getColourByType("alertMessage"));
} else {
@@ -58,6 +78,11 @@ function messageClientAlert(client, messageText) {
// ---------------------------------------------------------------------------
function messageClientSuccess(client, messageText) {
+ if(client.console) {
+ console.log(`👍 ${messageText}`);
+ return true;
+ }
+
if(client instanceof Client) {
messageClientNormal(client, `👍 [#FFFFFF] ${messageText}`, getColourByType("successMessage"));
} else {
@@ -68,6 +93,11 @@ function messageClientSuccess(client, messageText) {
// ---------------------------------------------------------------------------
function messageClientInfo(client, messageText) {
+ if(client.console) {
+ console.log(`ℹ️ ${messageText}`);
+ return true;
+ }
+
if(client instanceof Client) {
messageClientNormal(client, `ℹ️ [#FFFFFF] ${messageText}`, getColourByType("successMessage"));
} else {
diff --git a/scripts/server/misc.js b/scripts/server/misc.js
index 70474d1c..db31a344 100644
--- a/scripts/server/misc.js
+++ b/scripts/server/misc.js
@@ -31,143 +31,6 @@ function addMiscCommandHandlers() {
// ---------------------------------------------------------------------------
-function setTimeCommand(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 hour = Number(splitParams[0]) || 0;
- let minute = Number(splitParams[1]) || 0;
-
- if(hour > 23 || hour < 0) {
- messageClientError(client, "The hour must be between 0 and 23!");
- return false;
- }
-
- if(minute > 59 || minute < 0) {
- messageClientError(client, "The minute must be between 0 and 59!");
- return false;
- }
-
- gta.time.hour = hour;
- gta.time.minute = minute;
-
- messageAdminAction(`${client.name} set the time to ${makeReadableTime(hour, minute)}`);
- return true;
-}
-
-// ---------------------------------------------------------------------------
-
-function setWeatherCommand(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 weatherId = getWeatherFromParams(splitParams[0]);
-
- if(!weatherId) {
- messageClientError(client, `That weather ID or name is invalid!`);
- return false;
- }
-
- gta.forceWeather(weatherId);
-
- messageAdminAction(`${client.name} set the weather to to ${weatherNames[server.game][weatherId]}`);
- updateServerRules();
- return true;
-}
-
-// ---------------------------------------------------------------------------
-
-function setSnowingCommand(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 fallingSnow = Number(splitParams[0]) || 0;
- let groundSnow = Number(splitParams[1]) || 0;
-
- serverConfig.fallingSnow = 0;
-
- messageAdminAction(`${client.name} turned falling snow ${getOnOffFromBool(intToBool(fallingSnow))} and ground snow ${getOnOffFromBool(intToBool(groundSnow))}`);
- updateServerRules();
- return true;
-}
-
-// ---------------------------------------------------------------------------
-
-function toggleServerLogoCommand(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 logoState = Number(params) || 1;
-
- serverConfig.useLogo = !!logoState;
-
- 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)) {
@@ -204,8 +67,8 @@ function setNewCharacterSpawnPositionCommand(command, params, client) {
}
let position = client.player.position;
- serverConfig.newCharacter.spawnPosition = position;
- serverConfig.newCharacter.spawnHeading = client.player.heading;
+ getServerConfig().newCharacter.spawnPosition = position;
+ getServerConfig().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;
@@ -232,9 +95,9 @@ function setNewCharacterMoneyCommand(command, params, client) {
}
let splitParams = params.split();
- let amount = Number(splitParams[0]) || 1000;
+ let amount = toInteger(splitParams[0]) || 1000;
- serverConfig.newCharacter.cash = skinId;
+ getServerConfig().newCharacter.cash = skinId;
messageClientNormal(client, `The new character money has been set to $${amount}`);
return true;
@@ -262,7 +125,7 @@ function setNewCharacterSkinCommand(command, params, client) {
skinId = getSkinFromParams(params);
}
- serverConfig.newCharacter.skin = skinId;
+ getServerConfig().newCharacter.skin = skinId;
messageClientNormal(client, `The new character skin has been set to ${getSkinNameFromId(skinId)} (ID ${skinId})`);
return true;
@@ -291,7 +154,7 @@ function submitIdeaCommand(command, params, client) {
// ---------------------------------------------------------------------------
-function submitBugCommand(command, params, client) {
+function submitBugReportCommand(command, params, client) {
if(getCommand(command).requireLogin) {
if(!isClientLoggedIn(client)) {
messageClientError(client, "You must be logged in to use this command!");
diff --git a/scripts/server/moderation.js b/scripts/server/moderation.js
index 959113c0..6f1f8ad9 100644
--- a/scripts/server/moderation.js
+++ b/scripts/server/moderation.js
@@ -53,7 +53,7 @@ function kickClientCommand(command, params, client) {
return false;
}
- message("[#996600][ADMIN]: [#FFFFFF]" + String(targetClient.name) + " has been kicked from the server.");
+ message("[#996600][ADMIN]: [#FFFFFF]" + toString(targetClient.name) + " has been kicked from the server.");
targetClient.disconnect();
}
@@ -89,7 +89,7 @@ function muteClientCommand(command, params, client) {
return false;
}
- message("[#996600][ADMIN]: [#FFFFFF]" + String(targetClient.name) + " has been muted!");
+ message("[#996600][ADMIN]: [#FFFFFF]" + toString(targetClient.name) + " has been muted!");
targetClient.setData("ag.muted", true, false);
}
@@ -125,7 +125,7 @@ function unMuteClientCommand(command, params, client) {
return false;
}
- message("[#996600][ADMIN]: [#FFFFFF]" + String(targetClient.name) + " has been unmuted!");
+ message("[#996600][ADMIN]: [#FFFFFF]" + toString(targetClient.name) + " has been unmuted!");
targetClient.removeData("ag.muted");
}
@@ -161,7 +161,7 @@ function freezeClientCommand(command, params, client) {
return false;
}
- message("[#996600][ADMIN]: [#FFFFFF]" + String(targetClient.name) + " has been frozen!");
+ message("[#996600][ADMIN]: [#FFFFFF]" + toString(targetClient.name) + " has been frozen!");
triggerNetworkEvent("ag.frozen", client, true);
}
@@ -197,7 +197,7 @@ function unFreezeClientCommand(command, params, client) {
return false;
}
- message(`[#996600][ADMIN]: [#FFFFFF]${String(targetClient.name)} has been un-frozen!`);
+ message(`[#996600][ADMIN]: [#FFFFFF]${toString(targetClient.name)} has been un-frozen!`);
triggerNetworkEvent("ag.frozen", client, false);
}
@@ -369,10 +369,10 @@ function getStaffFlagsCommand(command, params, client) {
}
let tempStaffFlags = [];
- for(let i in serverData.staffFlagKeys) {
- let tempFlagValue = getStaffFlagValue(serverData.staffFlagKeys[i]);
+ for(let i in getServerData().staffFlagKeys) {
+ let tempFlagValue = getStaffFlagValue(getServerData().staffFlagKeys[i]);
if(doesClientHaveStaffPermission(client, tempFlagValue)) {
- tempStaffFlags.push(serverData.staffFlagKeys[i]);
+ tempStaffFlags.push(getServerData().staffFlagKeys[i]);
}
}
@@ -408,7 +408,7 @@ function allStaffFlagsCommand(command, params, client) {
return false;
}
- messageClientInfo(client, `Staff flags: ${serverData.staffFlagKeys.join(", ")}`);
+ messageClientInfo(client, `Staff flags: ${getServerData().staffFlagKeys.join(", ")}`);
}
// ---------------------------------------------------------------------------
\ No newline at end of file
diff --git a/scripts/server/native.js b/scripts/server/native.js
index 95ff7c01..5e289434 100644
--- a/scripts/server/native.js
+++ b/scripts/server/native.js
@@ -64,4 +64,82 @@ function agSetPedSkin(ped, skinId) {
return ped.modelIndex = skinId;
}
+// ---------------------------------------------------------------------------
+
+function getServerGame() {
+ return server.game;
+}
+
+// ---------------------------------------------------------------------------
+
+function getPlayerPosition(client) {
+ return client.getData("ag.position");
+}
+
+// ---------------------------------------------------------------------------
+
+function getPlayerHeading(client) {
+ return client.getData("ag.heading");
+}
+
+// ---------------------------------------------------------------------------
+
+function getPlayerVehicle(client) {
+ return getVehicleDataFromSyncId(client.getData("ag.vehicle"));
+}
+
+// ---------------------------------------------------------------------------
+
+function isPlayerInAnyVehicle(client) {
+ if(isGTAIV()) {
+ return (client.getData("ag.vehicle") != null);
+ } else {
+ return (client.player.vehicle != null);
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+function getPlayerVehicleSeat(client) {
+ return client.getData("ag.vehicleSeat");
+}
+
+// ---------------------------------------------------------------------------
+
+function isPlayerSpawned(client) {
+ return client.getData("ag.spawned");
+}
+
+// ---------------------------------------------------------------------------
+
+function getVehiclePosition(vehicleData) {
+ return vehicleData.syncPosition;
+}
+
+// ---------------------------------------------------------------------------
+
+function getVehicleHeading(vehicleData) {
+ return vehicleData.syncHeading;
+}
+
+// ---------------------------------------------------------------------------
+
+function getVehicleSyncer(vehicleData) {
+ if(isGTAIV()) {
+ return vehicleData.syncedBy;
+ } else {
+ vehicleData.vehicle.syncer;
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+function getVehicleForNetworkEvent(vehicleData) {
+ if(isGTAIV()) {
+ return vehicleData.syncId;
+ } else {
+ vehicleData.vehicle.syncer;
+ }
+}
+
// ---------------------------------------------------------------------------
\ No newline at end of file
diff --git a/scripts/server/startup.js b/scripts/server/startup.js
index ecac6902..1f8c537b 100644
--- a/scripts/server/startup.js
+++ b/scripts/server/startup.js
@@ -14,25 +14,26 @@ function initServerScripts() {
initClassScript();
initDatabaseScript();
-
+ initBitFlagScript();
initCommandScript();
-
initBusinessScript();
initClanScript();
initHouseScript();
initChatScript();
initModerationScript();
initAccountScript();
+ initSubAccountScript();
initChatScript();
initJobScript();
initVehicleScript();
initDeveloperScript();
+ initConfigScript();
initTimers();
- //gta.time.hour = serverConfig.startup.hour;
- //gta.time.minute = serverConfig.startup.minute;
- //gta.forceWeather(serverConfig.startup.weather);
+ //gta.time.hour = getServerConfig().startup.hour;
+ //gta.time.minute = getServerConfig().startup.minute;
+ //gta.forceWeather(getServerConfig().startup.weather);
initAllClients();
}
diff --git a/scripts/server/subaccount.js b/scripts/server/subaccount.js
new file mode 100644
index 00000000..cccf1e34
--- /dev/null
+++ b/scripts/server/subaccount.js
@@ -0,0 +1,250 @@
+// ===========================================================================
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
+// ---------------------------------------------------------------------------
+// FILE: subaccount.js
+// DESC: Provides subaccount (character) functions and usage
+// TYPE: Server (JavaScript)
+// ===========================================================================
+
+function initSubAccountScript() {
+ console.log("[Asshat.SubAccount]: Initializing account script ...");
+ addSubAccountCommandHandlers();
+ console.log("[Asshat.SubAccount]: Account script initialized!");
+}
+
+// ---------------------------------------------------------------------------
+
+function addSubAccountCommandHandlers() {
+ console.log("[Asshat.SubAccount]: Adding sub account command handlers ...");
+ let subAccountCommands = serverCommands.subAccount;
+ for(let i in subAccountCommands) {
+ addCommandHandler(subAccountCommands[i].command, subAccountCommands[i].handlerFunction);
+ }
+ console.log("[Asshat.SubAccount]: Sub Account command handlers added!");
+}
+
+// ---------------------------------------------------------------------------
+
+function loadSubAccountFromName(firstName, lastName) {
+ let dbConnection = connectToDatabase();
+ if(dbConnection) {
+ firstName = escapeDatabaseString(dbConnection, firstName);
+ lastName = escapeDatabaseString(dbConnection, lastName);
+ let dbQueryString = `SELECT * FROM sacct_main WHERE sacct_name_first = '${firstName}' AND sacct_name_last = '${lastName}' LIMIT 1;`;
+ let dbQuery = queryDatabase(dbConnection, dbQueryString);
+ if(dbQuery) {
+ let dbAssoc = fetchQueryAssoc(dbQuery);
+ freeDatabaseQuery(dbQuery);
+ return new serverClasses.subAccountData(dbAssoc);
+ }
+ disconnectFromDatabase(dbConnection);
+ }
+
+ return false;
+}
+
+// ---------------------------------------------------------------------------
+
+function loadSubAccountFromId(subAccountId) {
+ let dbConnection = connectToDatabase();
+ if(dbConnection) {
+ let dbQueryString = `SELECT * FROM sacct_main WHERE sacct_id = ${subAccountId} LIMIT 1;`;
+ let dbQuery = queryDatabase(dbConnection, dbQueryString);
+ if(dbQuery) {
+ let dbAssoc = fetchQueryAssoc(dbQuery);
+ freeDatabaseQuery(dbQuery);
+ return new serverClasses.subAccountData(dbAssoc);
+ }
+ disconnectFromDatabase(dbConnection);
+ }
+
+ return false;
+}
+
+// ---------------------------------------------------------------------------
+
+function loadSubAccountsFromAccount(accountId) {
+ let tempSubAccounts = [];
+ let dbAssoc = false;
+ if(accountId > 0) {
+ let dbConnection = connectToDatabase();
+ if(dbConnection) {
+ let dbQueryString = `SELECT * FROM sacct_main WHERE sacct_acct = ${accountId} AND sacct_server = ${serverId}`;
+ let dbQuery = queryDatabase(dbConnection, dbQueryString);
+ if(dbQuery) {
+ while(dbAssoc = fetchQueryAssoc(dbQuery)) {
+ let tempSubAccount = new serverClasses.subAccountData(dbAssoc);
+ tempSubAccounts.push(tempSubAccount);
+ }
+ freeDatabaseQuery(dbQuery);
+ }
+ disconnectFromDatabase(dbConnection);
+ }
+ }
+
+ return tempSubAccounts;
+}
+
+// ---------------------------------------------------------------------------
+
+function saveSubAccountToDatabase(subAccountData) {
+ let dbConnection = connectToDatabase();
+
+ if(dbConnection) {
+ let dbQueryString = `UPDATE sacct_main SET sacct_pos_x=${subAccountData.spawnPosition.x}, sacct_pos_y=${subAccountData.spawnPosition.y}, sacct_pos_z=${subAccountData.spawnPosition.z}, sacct_angle=${subAccountData.spawnHeading}, sacct_skin=${subAccountData.skin}, sacct_cash=${subAccountData.cash}, sacct_job=${subAccountData.job} WHERE sacct_id=${subAccountData.databaseId}`;
+ let dbQuery = queryDatabase(dbConnection, dbQueryString);
+ //freeDatabaseQuery(dbQuery);
+ disconnectFromDatabase(dbConnection);
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+function createSubAccount(accountId, firstName, lastName, skinId, dateOfBirth, placeOfOrigin) {
+ console.log(`[Asshat.Account] Attempting to create subaccount ${firstName} ${lastName} in database`);
+ let dbConnection = connectToDatabase();
+
+ if(dbConnection) {
+ let safeFirstName = escapeDatabaseString(dbConnection, firstName);
+ let safeLastName = escapeDatabaseString(dbConnection, lastName);
+ let safePlaceOfOrigin = escapeDatabaseString(dbConnection, placeOfOrigin);
+
+ let dbQuery = queryDatabase(dbConnection, `INSERT INTO sacct_main (sacct_acct, sacct_name_first, sacct_name_last, sacct_skin, sacct_origin, sacct_when_born, sacct_pos_x, sacct_pos_y, sacct_pos_z, sacct_angle, sacct_cash, sacct_server) VALUES (${accountId}, '${safeFirstName}', '${safeLastName}', ${skinId}, '${safePlaceOfOrigin}', '${dateOfBirth}', ${getServerConfig().newCharacter.spawnPosition.x}, ${getServerConfig().newCharacter.spawnPosition.y}, ${getServerConfig().newCharacter.spawnPosition.z}, ${getServerConfig().newCharacter.spawnHeading}, ${getServerConfig().newCharacter.money}, ${serverId})`);
+ if(getDatabaseInsertId(dbConnection) > 0) {
+ return loadSubAccountFromId(getDatabaseInsertId(dbConnection));
+ }
+ disconnectFromDatabase(dbConnection);
+ }
+
+ return false;
+}
+
+// ---------------------------------------------------------------------------
+
+function showCharacterSelectToClient(client) {
+ if(getServerConfig().useGUI) {
+ getClientData(client).currentSubAccount = 0;
+ let tempSubAccount = getClientData(client).subAccounts[0];
+ triggerNetworkEvent("ag.showCharacterSelect", client, tempSubAccount.firstName, tempSubAccount.lastName, tempSubAccount.placeOfOrigin, tempSubAccount.dateOfBirth, tempSubAccount.skin);
+ } else {
+ //let emojiNumbers = ["➊", "➋", "➌", "➍", "➎", "➏", "➐", "➑", "➒"];
+ //let emojiNumbers = ["①", "②", "③", "④", "⑤", "⑥", "⑦", "⑧", "⑨"];
+ messageClientNormal(client, `You have the following characters. Use /usechar to select one:`, getColourByName("teal"));
+ getClientData(client).subAccounts.forEach(function(subAccount, index) {
+ messageClientNormal(client, `${index+1} • [#CCCCCC]${subAccount.firstName} ${subAccount.lastName}`);
+ });
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+function checkNewCharacter(client, firstName, lastName, dateOfBirth, placeOfOrigin, skinId) {
+ if(areParamsEmpty(firstName)) {
+ triggerNetworkEvent("ag.newCharacterFailed", client, "First name cannot be blank!");
+ return false;
+ }
+ firstName = firstName.trim();
+
+ if(areParamsEmpty(lastName)) {
+ triggerNetworkEvent("ag.newCharacterFailed", client, "Last name cannot be blank!");
+ return false;
+ }
+ lastName = lastName.trim();
+
+ if(areParamsEmpty(dateOfBirth)) {
+ triggerNetworkEvent("ag.newCharacterFailed", client, "Date of birth cannot be blank!");
+ return false;
+ }
+
+ if(areParamsEmpty(placeOfOrigin)) {
+ triggerNetworkEvent("ag.newCharacterFailed", client, "Place of origin cannot be blank!");
+ return false;
+ }
+
+ if(areParamsEmpty(skinId)) {
+ triggerNetworkEvent("ag.newCharacterFailed", client, "Invalid skin!");
+ return false;
+ }
+
+ let subAccountData = createSubAccount(getClientData(client).accountData.databaseId, firstName, lastName, skinId, dateOfBirth, placeOfOrigin);
+ if(!subAccountData) {
+ if(getServerConfig().useGUI) {
+ triggerNetworkEvent("ag.newCharacterFailed", client, "Something went wrong. Your character could not be created!");
+ } else {
+ messageClientAlert(client, "Something went wrong. Your character could not be created!");
+ }
+ messageClientAlert(client, "Asshat Gaming staff have been notified of the problem and will fix it shortly.");
+ return false;
+ }
+
+ getClientData(client).subAccounts = loadSubAccountsFromAccount(getClientData(client).accountData.databaseId);
+ getClientData(client).currentSubAccount = 0;
+ let tempSubAccount = getClientData(client).subAccounts[0];
+ showCharacterSelectToClient(client);
+}
+addNetworkHandler("ag.checkNewCharacter", checkNewCharacter);
+
+// ---------------------------------------------------------------------------
+
+addNetworkHandler("ag.previousCharacter", function(client) {
+ if(getClientData(client).subAccounts.length > 1) {
+ if(getClientData(client).currentSubAccount <= 0) {
+ getClientData(client).currentSubAccount = getClientData(client).subAccounts.length-1;
+ } else {
+ getClientData(client).currentSubAccount--;
+ }
+
+ let subAccountId = getClientData(client).currentSubAccount;
+ let tempSubAccount = getClientData(client).subAccounts[subAccountId];
+ triggerNetworkEvent("ag.switchCharacterSelect", client, tempSubAccount.firstName, tempSubAccount.lastName, tempSubAccount.placeOfOrigin, tempSubAccount.dateOfBirth, tempSubAccount.skin);
+ }
+});
+
+// ---------------------------------------------------------------------------
+
+addNetworkHandler("ag.nextCharacter", function(client) {
+ if(getClientData(client).subAccounts.length > 1) {
+ if(getClientData(client).currentSubAccount >= getClientData(client).subAccounts.length-1) {
+ getClientData(client).currentSubAccount = 0;
+ } else {
+ getClientData(client).currentSubAccount++;
+ }
+
+ let subAccountId = getClientData(client).currentSubAccount;
+ let tempSubAccount = getClientData(client).subAccounts[subAccountId];
+ triggerNetworkEvent("ag.switchCharacterSelect", client, tempSubAccount.firstName, tempSubAccount.lastName, tempSubAccount.placeOfOrigin, tempSubAccount.dateOfBirth, tempSubAccount.skin);
+ }
+});
+
+// ---------------------------------------------------------------------------
+
+function selectCharacter(client, characterId = -1) {
+ if(getServerConfig().useGUI) {
+ triggerNetworkEvent("ag.characterSelectSuccess", client);
+ }
+
+ if(characterId != -1) {
+ getClientData(client).currentSubAccount = characterId;
+ }
+
+ let tempSubAccount = getClientCurrentSubAccount(client);
+ spawnPlayer(client, tempSubAccount.spawnPosition, tempSubAccount.spawnHeading, tempSubAccount.skin);
+
+ messageClientAlert(client, `You are now playing as: [#0099FF]${tempSubAccount.firstName} ${tempSubAccount.lastName}`, getColourByName("white"));
+ messageClientNormal(client, "This server is in early development and may restart at any time for updates.", getColourByName("orange"));
+ messageClientNormal(client, "Please report any bugs using /bug and suggestions using /idea", getColourByName("yellow"));
+ triggerNetworkEvent("ag.restoreCamera", client);
+ client.setData("ag.spawned", true, true);
+ client.setData("ag.position", tempSubAccount.spawnPosition, true);
+ client.setData("ag.heading", tempSubAccount.spawnHeading, true);
+ if(isGTAIV()) {
+ triggerNetworkEvent("ag.iv.syncPosition", client, true);
+ }
+
+ if(isGTAIV()) {
+ spawnAllVehicles();
+ }
+}
+addNetworkHandler("ag.selectCharacter", selectCharacter);
\ No newline at end of file
diff --git a/scripts/server/test.005 b/scripts/server/test.005
deleted file mode 100644
index 25358e71..00000000
--- a/scripts/server/test.005
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index e69de29b..00000000
diff --git a/scripts/server/test.txt b/scripts/server/test.txt
deleted file mode 100644
index e69de29b..00000000
diff --git a/scripts/server/timers.js b/scripts/server/timers.js
index bba29d8b..1c85de3e 100644
--- a/scripts/server/timers.js
+++ b/scripts/server/timers.js
@@ -21,10 +21,11 @@ function updateTimeRule() {
function saveAllServerDataToDatabase() {
console.log("[Asshat.Utilities]: Saving all server data to database ...");
saveAllClientsToDatabase();
- saveAllVehiclesToDatabase();;
+ saveAllVehiclesToDatabase();
saveAllHousesToDatabase();
saveAllBusinessesToDatabase();
saveAllClansToDatabase();
+ saveServerConfigToDatabase()
console.log("[Asshat.Utilities]: Saved all server data to database!");
}
@@ -32,5 +33,26 @@ function saveAllServerDataToDatabase() {
function initTimers() {
serverTimers.saveDataIntervalTimer = setInterval(saveAllServerDataToDatabase, 600000);
- serverTimers.updateTimeRuleTimer = setInterval(updateTimeRule, 1000);
-}
\ No newline at end of file
+ serverTimers.updateTimeRuleTimer = setInterval(updateTimeRule, 1000);
+ serverTimers.vehicleRentTimer = setInterval(vehicleRentCheck, 60000);
+}
+
+// ---------------------------------------------------------------------------
+
+function vehicleRentCheck() {
+ for(let i in getServerData().vehicles) {
+ if(getServerData().vehicles[i].rentPrice > 0) {
+ if(getServerData().vehicles[i].rentedBy) {
+ let rentedBy = getServerData().vehicles[i].rentedBy;
+ if(getClientData(rentedBy).cash < getServerData().vehicles[i].rentPrice) {
+ messageClientAlert(rentedBy, `You do not have enough money to continue renting this vehicle!`);
+ stopRentingVehicle(rentedBy);
+ } else {
+ getClientData(rentedBy).cash -= getServerData().vehicles[i].rentPrice;
+ }
+ }
+ }
+ }
+}
+
+// ---------------------------------------------------------------------------
\ No newline at end of file
diff --git a/scripts/server/translate.js b/scripts/server/translate.js
index 32ccd106..4499a5fa 100644
--- a/scripts/server/translate.js
+++ b/scripts/server/translate.js
@@ -18,7 +18,7 @@ function translateMessage(messageText, fromLanguageId, toLanguageId) {
thisTranslationURL,
"",
function(data) {
- data = String(data).substr(0, String(data).lastIndexOf("}")+1);
+ data = toString(data).substr(0, toString(data).lastIndexOf("}")+1);
let translationData = JSON.parse(data);
//this.translatedText = translationData.responseData.translatedText;
addTranslationToCache(messageText, translationData.responseData.translatedText, fromLanguageId, toLanguageId);
@@ -34,32 +34,32 @@ function translateMessage(messageText, fromLanguageId, toLanguageId) {
// ---------------------------------------------------------------------------
function addTranslationToCache(originalText, translatedText, fromLanguageId, toLanguageId) {
- serverData.translation.cache[fromLanguageId][toLanguageId].push([originalText, translatedText]);
+ getServerData().translation.cache[fromLanguageId][toLanguageId].push([originalText, translatedText]);
return true;
}
// ---------------------------------------------------------------------------
function formatTranslationURL(originalText, fromLanguageId, toLanguageId) {
- return serverData.translation.translationBaseURL.format(encodeURI(originalText), getLanguageShortCode(fromLanguageId), getLanguageShortCode(toLanguageId));
+ return getServerData().translation.translationBaseURL.format(encodeURI(originalText), getLanguageShortCode(fromLanguageId), getLanguageShortCode(toLanguageId));
}
// ---------------------------------------------------------------------------
function getLanguageShortCode(languageId) {
- return serverData.translation.languages[languageId][1];
+ return getServerData().translation.languages[languageId][1];
}
// ---------------------------------------------------------------------------
function getLanguageFullName(languageId) {
- return serverData.translation.languages[languageId][0];
+ return getServerData().translation.languages[languageId][0];
}
// ---------------------------------------------------------------------------
function getLanguageIdFromFullName(languageName) {
- let languages = serverData.translation.languages;
+ let languages = getServerData().translation.languages;
for(let i in languages) {
if(languages[i][0] == languageName) {
return i;
@@ -71,7 +71,7 @@ function getLanguageIdFromFullName(languageName) {
// ---------------------------------------------------------------------------
function getLanguageIdFromShortCode(languageShortCode) {
- let languages = serverData.translation.languages;
+ let languages = getServerData().translation.languages;
for(let i in languages) {
if(languages[i][1] == languageShortCode) {
return i;
diff --git a/scripts/server/utilities.js b/scripts/server/utilities.js
index 4c835ed4..ca77acfa 100644
--- a/scripts/server/utilities.js
+++ b/scripts/server/utilities.js
@@ -10,2332 +10,6 @@
// ---------------------------------------------------------------------------
-let gameData = {
- weaponNames: [
- [],
- ["Fist", "Bat", "Pistol", "Uzi", "Shotgun", "AK47", "M16", "Sniper Rifle", "Rocket Launcher", "Flamethrower", "Molotov", "Grenade"],
- ["Fist", "Brass Knuckles", "Screwdriver", "Golf Club", "Nitestick", "Knife", "Baseball Bat", "Hammer", "Meat Cleaver", "Machete", "Katana", "Chainsaw", "Grenade", "Remote Grenade", "Teargas", "Molotov Cocktail", "Missile", "Colt .45", "Python", "Shotgun", "Spaz Shotgun", "Stubby Shotgun", "Tec-9", "Uzi", "Ingram", "MP5", "M4", "Ruger", "Sniper Rifle", "Laser Sniper", "RPG", "Flame Thrower", "M60", "Minigun"],
- ["Fist", "Brass Knuckles", "Golf Club", "Nightstick", "Knife", "Baseball Bat", "Shovel", "Pool Cue", "Katana", "Chainsaw", "Purple Dildo", "Dildo", "Vibrator", "Silver Vibrator", "Flowers", "Cane", "Grenade", "Teargas", "Molotov Cocktail", "Unknown", "Unknown", "Unknown", "9mm", "Silenced 9mm", "Desert Eagle", "Shotgun", "Sawnoff Shotgun", "Combat Shotgun", "Uzi", "MP5", "AK-47", "M4", "Tec-9", "Country Rifle", "Sniper Rifle", "RPG", "HS Rocket", "Flamethrower", "Minigun", "Satchel Charge", "Detonator", "Spraycan", "Fire Extinguisher", "Camera", "Night Vision Goggles", "Thermal Goggles", "Parachute", "Cellphone", "Jetpack", "Skateboard"]
- ],
- gameAnnounceColours: [
- COLOUR_BLACK, // Invalid
- COLOUR_WHITE, // GTA III
- COLOUR_AQUA, // GTA Vice City
- COLOUR_ORANGE, // GTA San Andreas
- COLOUR_ORANGE, // GTA Underground
- //COLOUR_SILVER, // GTA IV
- //COLOUR_SILVER // GTA IV (EFLC)
- ],
- weatherNames: [
- ["Unknown"],
- [ // GTA III
- "Clear",
- "Overcast",
- "Thunderstorm",
- "Fog",
- "Clear",
- "Rainy",
- "Dark/Cloudy",
- "Light/Cloudy",
- "Overcast/Cloudy",
- "Grey/Cloudy"
- ],
- [ // GTA Vice City
- "Clear",
- "Overcast",
- "Thunderstorm",
- "Fog",
- "Clear",
- "Rainy",
- "Dark/Cloudy",
- "Light/Cloudy",
- "Overcast/Cloudy",
- "Grey/Cloudy"
- ],
- [ // GTA San Andreas
- "Blue Skies",
- "Blue Skies",
- "Blue Skies",
- "Blue Skies",
- "Blue Skies",
- "Blue Skies",
- "Blue Skies",
- "Blue Skies",
- "Thunderstorm",
- "Cloudy/Foggy",
- "Clear Blue Skies",
- "Heatwave",
- "Dull/Colorless",
- "Dull/Colorless",
- "Dull/Colorless",
- "Dull/Colorless",
- "Dull/Rainy",
- "Heatwave",
- "Heatwave",
- "Sandstorm",
- "Greenish/Foggy"
- ],
- [ // GTA Underground
- "Blue Skies",
- "Blue Skies",
- "Blue Skies",
- "Blue Skies",
- "Blue Skies",
- "Blue Skies",
- "Blue Skies",
- "Blue Skies",
- "Thunderstorm",
- "Cloudy/Foggy",
- "Clear Blue Skies",
- "Heatwave",
- "Dull/Colorless",
- "Dull/Colorless",
- "Dull/Colorless",
- "Dull/Colorless",
- "Dull/Rainy",
- "Heatwave",
- "Heatwave",
- "Sandstorm",
- "Greenish/Foggy"
- ],
- [ // GTA IV
- "Extra Sunny",
- "Sunny",
- "Sunny/Windy",
- "Cloudy",
- "Rain",
- "Light Rain",
- "Foggy",
- "Thunderstorm",
- "Extra Sunny",
- "Sunny/Windy",
- ],
- ],
- gameNames: [
- "Unknown",
- "GTA III",
- "GTA Vice City",
- "GTA San Andreas",
- "GTA Underground",
- "GTA IV",
- "GTA IV: Episodes from Liberty City",
- ],
- vehicleWheelStateNames: [
- "normal",
- "flat",
- "gone"
- ],
- vehicleDoorStateNames: [
- "closed",
- "closed",
- "swinging",
- "open"
- ],
- vehicleWheelNames: [
- "front left",
- "rear left",
- "front right",
- "rear right"
- ],
- vehicleLightNames: [
- "front left",
- "rear left",
- "front right",
- "rear right"
- ],
- vehicleRadioStationNames: [
- [],
- [ // GTA III
- "Head Radio",
- "Double Cleff FM",
- "Jah Radio",
- "Rise FM",
- "Lips 106",
- "Flashback FM",
- "Chatterbox 109",
- "MP3 Player"
- ],
- [ // GTA Vice City
- "Wildstyle",
- "Flash FM",
- "K CHAT",
- "Fever 105",
- "VROCK",
- "VCPR",
- "Espantoso",
- "Emotion 98.3",
- "Wave 103",
- "MP3 Player"
- ],
- [ // GTA San Andreas
- "KROSE",
- "KDST",
- "Bounce FM",
- "SFUR",
- "Radio Los Santos",
- "Radio X",
- "CSR Radio",
- "KJAH West",
- "Master Sounds",
- "WCTR",
- "User Track Player"
- ]
- ],
- vehicleModelIdStart: [
- 0,
- 90, // GTA III
- 130, // GTA Vice City
- 400, // GTA San Andreas
- 400 // GTA Underground
- ],
- vehicleNames: [
- [],
- [ // GTA III
- "Landstalker",
- "Idaho",
- "Stinger",
- "Linerunner",
- "Perennial",
- "Sentinel",
- "Patriot",
- "Fire Truck",
- "Trashmaster",
- "Stretch",
- "Manana",
- "Infernus",
- "Blista",
- "Pony",
- "Mule",
- "Cheetah",
- "Ambulance",
- "FBI Car",
- "Moonbeam",
- "Esperanto",
- "Taxi",
- "Kuruma",
- "Bobcat",
- "Mr. Whoopee",
- "BF Injection",
- "Manana (Corpse)",
- "Police Car",
- "Enforcer",
- "Securicar",
- "Banshee",
- "Predator",
- "Bus",
- "Rhino",
- "Barracks OL",
- "Train",
- "Police Helicopter",
- "Dodo",
- "Coach",
- "Cabbie",
- "Stallion",
- "Rumpo",
- "RC Bandit",
- "Bellyup",
- "Mr. Wongs",
- "Mafia Sentinel",
- "Yardie Lobo",
- "Yakuza Stinger",
- "Diablo Stallion",
- "Cartel Cruiser",
- "Hoods Rumpo XL",
- "Air Train",
- "Dead Dodo",
- "Speeder",
- "Reefer",
- "Panlantic",
- "Flatbed",
- "Yankee",
- "Escape",
- "Borgnine Taxi",
- "Toyz Van",
- "Ghost"
- ],
- [ // GTA Vice City
- "Landstalker",
- "Idaho",
- "Stinger",
- "Linerunner",
- "Perennial",
- "Sentinel",
- "Rio",
- "Firetruck",
- "Trashmaster",
- "Stretch",
- "Manana",
- "Infernus",
- "Voodoo",
- "Pony",
- "Mule",
- "Cheetah",
- "Ambulance",
- "FBI Washington",
- "Moonbeam",
- "Esperanto",
- "Taxi",
- "Washington",
- "Bobcat",
- "Mr.Whoopee",
- "BF-Injection",
- "Hunter",
- "Police",
- "Enforcer",
- "Securicar",
- "Banshee",
- "Predator",
- "Bus",
- "Rhino",
- "Barracks OL",
- "Cuban Hermes",
- "Helicopter",
- "Angel",
- "Coach",
- "Cabbie",
- "Stallion",
- "Rumpo",
- "RC Bandit",
- "Romero's Hearse",
- "Packer",
- "Sentinel XS",
- "Admiral",
- "Squalo",
- "Sea Sparrow",
- "Pizza Boy",
- "Gang Burrito",
- "Airtrain",
- "Deaddodo",
- "Speeder",
- "Reefer",
- "Tropic",
- "Flatbed",
- "Yankee",
- "Caddy",
- "Zebra Cab",
- "Top Fun",
- "Skimmer",
- "PCJ-600",
- "Faggio",
- "Freeway",
- "Rcbaron",
- "RC Raider",
- "Glendale",
- "Oceanic",
- "Sanchez",
- "Sparrow",
- "Patriot",
- "Love Fist",
- "Coast Guard",
- "Dinghy",
- "Hermes",
- "Sabre",
- "Sabre Turbo",
- "Phoenix",
- "Walton",
- "Regina",
- "Comet",
- "Deluxo",
- "Burrito",
- "Spand Express",
- "Marquis",
- "Baggage Handler",
- "Kaufman Cab",
- "Maverick",
- "VCN Maverick",
- "Rancher",
- "FBI Rancher",
- "Virgo",
- "Greenwood",
- "Cuban Jetmax",
- "Hotring Racer 1",
- "Sandking",
- "Blista Compact",
- "Police Maverick",
- "Boxville",
- "Benson",
- "Mesa Grande",
- "RC Goblin",
- "Hotring Racer 2",
- "Hotring Racer 3",
- "Bloodring Banger 1",
- "Bloodring Banger 2",
- "VCPD Cheetah"
- ],
- [ // GTA San Andreas
- "Landstalker",
- "Bravura",
- "Buffalo",
- "Linerunner",
- "Pereniel",
- "Sentinel",
- "Dumper",
- "Firetruck",
- "Trashmaster",
- "Stretch",
- "Manana",
- "Infernus",
- "Voodoo",
- "Pony",
- "Mule",
- "Cheetah",
- "Ambulance",
- "Leviathan",
- "Moonbeam",
- "Esperanto",
- "Taxi",
- "Washington",
- "Bobcat",
- "Mr Whoopee",
- "BF Injection",
- "Hunter",
- "Premier",
- "Enforcer",
- "Securicar",
- "Banshee",
- "Predator",
- "Bus",
- "Rhino",
- "Barracks",
- "Hotknife",
- "Trailer",
- "Previon",
- "Coach",
- "Cabbie",
- "Stallion",
- "Rumpo",
- "RC Bandit",
- "Romero",
- "Packer",
- "Monster",
- "Admiral",
- "Squalo",
- "Seasparrow",
- "Pizzaboy",
- "Tram",
- "Trailer",
- "Turismo",
- "Speeder",
- "Reefer",
- "Tropic",
- "Flatbed",
- "Yankee",
- "Caddy",
- "Solair",
- "Berkley's RC Van",
- "Skimmer",
- "PCJ-600",
- "Faggio",
- "Freeway",
- "RC Baron",
- "RC Raider",
- "Glendale",
- "Oceanic",
- "Sanchez",
- "Sparrow",
- "Patriot",
- "Quad",
- "Coastguard",
- "Dinghy",
- "Hermes",
- "Sabre",
- "Rustler",
- "ZR-350",
- "Walton",
- "Regina",
- "Comet",
- "BMX",
- "Burrito",
- "Camper",
- "Marquis",
- "Baggage",
- "Dozer",
- "Maverick",
- "News Maverick",
- "Rancher",
- "FBI Rancher",
- "Virgo",
- "Greenwood",
- "Jetmax",
- "Hotring-Racer A",
- "Sandking",
- "Blista",
- "Police Maverick",
- "Boxville",
- "Benson",
- "Mesa",
- "RC Goblin",
- "Hotring-Racer B",
- "Hotring-Racer C",
- "Bloodring-Banger",
- "Rancher",
- "Super-GT",
- "Elegant",
- "Journey",
- "Bike",
- "Mountain Bike",
- "Beagle",
- "Cropdust",
- "Stunt",
- "Tanker",
- "RoadTrain",
- "Nebula",
- "Majestic",
- "Buccaneer",
- "Shamal",
- "Hydra",
- "FCR-900",
- "NRG-500",
- "HPV1000",
- "Cement Truck",
- "Tow Truck",
- "Fortune",
- "Cadrona",
- "FBI Truck",
- "Willard",
- "Forklift",
- "Tractor",
- "Combine",
- "Feltzer",
- "Remington",
- "Slamvan",
- "Blade",
- "Freight",
- "Streak",
- "Vortex",
- "Vincent",
- "Bullet",
- "Clover",
- "Sadler",
- "Firetruck",
- "Hustler",
- "Intruder",
- "Primo",
- "Cargobob",
- "Tampa",
- "Sunrise",
- "Merit",
- "Utility",
- "Nevada",
- "Yosemite",
- "Windsor",
- "Monster Truck A",
- "Monster Truck B",
- "Uranus",
- "Jester",
- "Sultan",
- "Stratum",
- "Elegy",
- "Raindance",
- "RC Tiger",
- "Flash",
- "Tahoma",
- "Savanna",
- "Bandito",
- "Freight",
- "Trailer",
- "Kart",
- "Mower",
- "Duneride",
- "Sweeper",
- "Broadway",
- "Tornado",
- "AT-400",
- "DFT-30",
- "Huntley",
- "Stafford",
- "BF-400",
- "Newsvan",
- "Tug",
- "Trailer",
- "Emperor",
- "Wayfarer",
- "Euros",
- "Hotdog",
- "Club",
- "Trailer",
- "Trailer",
- "Andromada",
- "Dodo",
- "RC Cam",
- "Launch",
- "Police Car",
- "Police Car",
- "Police Car",
- "Police Ranger",
- "Picador",
- "S.W.A.T. Van",
- "Alpha",
- "Phoenix",
- "Broken Glendale",
- "Broken Sadler",
- "Luggage Trailer",
- "Luggage Trailer",
- "Stair Trailer",
- "Boxville",
- "Farm Plow",
- "Utility Trailer"
- ],
- ],
- vehicleColourHex: [
- [],
- [ // GTA III
- "#050505",
- "#F5F5F5",
- "#2A77A1",
- "#B3363A",
- "#263739",
- "#86446E",
- "#F3ED47",
- "#4C75B7",
- "#667292",
- "#5E7072",
- "#352224",
- "#5A2124",
- "#662B2B",
- "#63322E",
- "#842827",
- "#8A3A42",
- "#682731",
- "#8B3C44",
- "#9E2F2B",
- "#A33A2F",
- "#D25633",
- "#925635",
- "#F4723A",
- "#D35733",
- "#E25A59",
- "#772A25",
- "#E17743",
- "#C44636",
- "#E17844",
- "#C35938",
- "#464840",
- "#747761",
- "#757763",
- "#918A3D",
- "#948C66",
- "#998D79",
- "#D8A534",
- "#C9BD7D",
- "#C9C591",
- "#D4C84E",
- "#1A332E",
- "#062505",
- "#1D373F",
- "#3C4A3B",
- "#2D5037",
- "#3A6C60",
- "#3A623C",
- "#7CA282",
- "#4C524E",
- "#56775B",
- "#101450",
- "#485E84",
- "#1C2745",
- "#1F3468",
- "#2B4878",
- "#475C83",
- "#447C92",
- "#3D67AB",
- "#4B7D82",
- "#80B0B7",
- "#3D2333",
- "#1C2948",
- "#343941",
- "#40454C",
- "#4A2D2B",
- "#563E33",
- "#41464C",
- "#672731",
- "#835A75",
- "#868587",
- "#171717",
- "#2E2E2E",
- "#454545",
- "#5C5C5C",
- "#737373",
- "#8A8A8A",
- "#A1A1A1",
- "#B8B8B8",
- "#CFCFCF",
- "#E6E6E6",
- "#AAAFAA",
- "#6A736B",
- "#AAAFAA",
- "#BBBEB5",
- "#BBBEB5",
- "#6A6F70",
- "#60635F",
- "#6A736B",
- "#AAAFAA",
- "#BBBEB5",
- "#21292B",
- "#343842",
- "#414648",
- "#4E5960",
- "#41454C"
- ],
- [ // GTA Vice City
- "#050505",
- "#F5F5F5",
- "#2A77A1",
- "#B3363A",
- "#263739",
- "#86446E",
- "#F3ED47",
- "#4C75B7",
- "#667292",
- "#5E7072",
- "#352224",
- "#5A2124",
- "#662B2B",
- "#63322E",
- "#842827",
- "#8A3A42",
- "#682731",
- "#8B3C44",
- "#9E2F2B",
- "#A33A2F",
- "#D25633",
- "#925635",
- "#F4723A",
- "#D35733",
- "#E25A59",
- "#772A25",
- "#E17743",
- "#C44636",
- "#E17844",
- "#C35938",
- "#464840",
- "#747761",
- "#757763",
- "#918A3D",
- "#948C66",
- "#998D79",
- "#D8A534",
- "#C9BD7D",
- "#C9C591",
- "#D4C84E",
- "#1A332E",
- "#062505",
- "#1D373F",
- "#3C4A3B",
- "#2D5037",
- "#3A6C60",
- "#3A623C",
- "#7CA282",
- "#4C524E",
- "#56775B",
- "#101450",
- "#485E84",
- "#1C2745",
- "#1F3468",
- "#2B4878",
- "#475C83",
- "#447C92",
- "#3D67AB",
- "#4B7D82",
- "#80B0B7",
- "#3D2333",
- "#1C2948",
- "#343941",
- "#40454C",
- "#4A2D2B",
- "#563E33",
- "#41464C",
- "#672731",
- "#835A75",
- "#868587",
- "#171717",
- "#2E2E2E",
- "#454545",
- "#5C5C5C",
- "#737373",
- "#8A8A8A",
- "#A1A1A1",
- "#B8B8B8",
- "#CFCFCF",
- "#E6E6E6",
- "#AAAFAA",
- "#6A736B",
- "#AAAFAA",
- "#BBBEB5",
- "#BBBEB5",
- "#6A6F70",
- "#60635F",
- "#6A736B",
- "#AAAFAA",
- "#BBBEB5",
- "#21292B",
- "#343842",
- "#414648",
- "#4E5960",
- "#41454C"
- ],
- [ // GTA San Andreas
- "#000000",
- "#F5F5F5",
- "#2A77A1",
- "#840410",
- "#263739",
- "#86446E",
- "#D78E10",
- "#4C75B7",
- "#BDBEC6",
- "#5E7072",
- "#46597A",
- "#656A79",
- "#5D7E8D",
- "#58595A",
- "#D6DAD6",
- "#9CA1A3",
- "#335F3F",
- "#730E1A",
- "#7B0A2A",
- "#9F9D94",
- "#3B4E78",
- "#732E3E",
- "#691E3B",
- "#96918C",
- "#515459",
- "#3F3E45",
- "#A5A9A7",
- "#635C5A",
- "#3D4A68",
- "#979592",
- "#421F21",
- "#5F272B",
- "#8494AB",
- "#767B7C",
- "#646464",
- "#5A5752",
- "#252527",
- "#2D3A35",
- "#93A396",
- "#6D7A88",
- "#221918",
- "#6F675F",
- "#7C1C2A",
- "#5F0A15",
- "#193826",
- "#5D1B20",
- "#9D9872",
- "#7A7560",
- "#989586",
- "#ADB0B0",
- "#848988",
- "#304F45",
- "#4D6268",
- "#162248",
- "#272F4B",
- "#7D6256",
- "#9EA4AB",
- "#9C8D71",
- "#6D1822",
- "#4E6881",
- "#9C9C98",
- "#917347",
- "#661C26",
- "#949D9F",
- "#A4A7A5",
- "#8E8C46",
- "#341A1E",
- "#6A7A8C",
- "#AAAD8E",
- "#AB988F",
- "#851F2E",
- "#6F8297",
- "#585853",
- "#9AA790",
- "#601A23",
- "#20202C",
- "#A4A096",
- "#AA9D84",
- "#78222B",
- "#0E316D",
- "#722A3F",
- "#7B715E",
- "#741D28",
- "#1E2E32",
- "#4D322F",
- "#7C1B44",
- "#2E5B20",
- "#395A83",
- "#6D2837",
- "#A7A28F",
- "#AFB1B1",
- "#364155",
- "#6D6C6E",
- "#0F6A89",
- "#204B6B",
- "#2B3E57",
- "#9B9F9D",
- "#6C8495",
- "#4D8495",
- "#AE9B7F",
- "#406C8F",
- "#1F253B",
- "#AB9276",
- "#134573",
- "#96816C",
- "#64686A",
- "#105082",
- "#A19983",
- "#385694",
- "#525661",
- "#7F6956",
- "#8C929A",
- "#596E87",
- "#473532",
- "#44624F",
- "#730A27",
- "#223457",
- "#640D1B",
- "#A3ADC6",
- "#695853",
- "#9B8B80",
- "#620B1C",
- "#5B5D5E",
- "#624428",
- "#731827",
- "#1B376D",
- "#EC6AAE",
- "#000000"
- ],
- [ // GTA Underground
- "#000000",
- "#F5F5F5",
- "#2A77A1",
- "#840410",
- "#263739",
- "#86446E",
- "#D78E10",
- "#4C75B7",
- "#BDBEC6",
- "#5E7072",
- "#46597A",
- "#656A79",
- "#5D7E8D",
- "#58595A",
- "#D6DAD6",
- "#9CA1A3",
- "#335F3F",
- "#730E1A",
- "#7B0A2A",
- "#9F9D94",
- "#3B4E78",
- "#732E3E",
- "#691E3B",
- "#96918C",
- "#515459",
- "#3F3E45",
- "#A5A9A7",
- "#635C5A",
- "#3D4A68",
- "#979592",
- "#421F21",
- "#5F272B",
- "#8494AB",
- "#767B7C",
- "#646464",
- "#5A5752",
- "#252527",
- "#2D3A35",
- "#93A396",
- "#6D7A88",
- "#221918",
- "#6F675F",
- "#7C1C2A",
- "#5F0A15",
- "#193826",
- "#5D1B20",
- "#9D9872",
- "#7A7560",
- "#989586",
- "#ADB0B0",
- "#848988",
- "#304F45",
- "#4D6268",
- "#162248",
- "#272F4B",
- "#7D6256",
- "#9EA4AB",
- "#9C8D71",
- "#6D1822",
- "#4E6881",
- "#9C9C98",
- "#917347",
- "#661C26",
- "#949D9F",
- "#A4A7A5",
- "#8E8C46",
- "#341A1E",
- "#6A7A8C",
- "#AAAD8E",
- "#AB988F",
- "#851F2E",
- "#6F8297",
- "#585853",
- "#9AA790",
- "#601A23",
- "#20202C",
- "#A4A096",
- "#AA9D84",
- "#78222B",
- "#0E316D",
- "#722A3F",
- "#7B715E",
- "#741D28",
- "#1E2E32",
- "#4D322F",
- "#7C1B44",
- "#2E5B20",
- "#395A83",
- "#6D2837",
- "#A7A28F",
- "#AFB1B1",
- "#364155",
- "#6D6C6E",
- "#0F6A89",
- "#204B6B",
- "#2B3E57",
- "#9B9F9D",
- "#6C8495",
- "#4D8495",
- "#AE9B7F",
- "#406C8F",
- "#1F253B",
- "#AB9276",
- "#134573",
- "#96816C",
- "#64686A",
- "#105082",
- "#A19983",
- "#385694",
- "#525661",
- "#7F6956",
- "#8C929A",
- "#596E87",
- "#473532",
- "#44624F",
- "#730A27",
- "#223457",
- "#640D1B",
- "#A3ADC6",
- "#695853",
- "#9B8B80",
- "#620B1C",
- "#5B5D5E",
- "#624428",
- "#731827",
- "#1B376D",
- "#EC6AAE",
- "#000000"
- ],
- ],
- skinNames: [
- [],
- [ // GTA III
- "Claude",
- "Police Officer",
- "SWAT Officer",
- "FBI Agent",
- "Army Soldier",
- "Paramedic",
- "Firefighter",
- "Wise Guy",
- "Taxi Driver",
- "Pimp",
- "Mafia Member",
- "Mafia Member",
- "Triad Member",
- "Triad Member",
- "Diablo Member",
- "Diablo Member",
- "Yakuza Member",
- "Yakuza Member",
- "Yardie Member",
- "Yardie Member",
- "Cartel Soldier",
- "Cartel Soldier",
- "Red Jacks Thug",
- "Purple Nines Thug",
- "Street Criminal",
- "Street Criminal",
- "INVALID",
- "INVALID",
- "INVALID",
- "INVALID",
- "Male Client",
- "Random Guy",
- "Vacationist",
- "Dj",
- "Young Woman",
- "Young Woman",
- "Business Woman",
- "Elder Woman",
- "Elder Woman",
- "Prostitute",
- "Prostitute",
- "Random Guy",
- "Diseased Man",
- "Deseased Woman",
- "Young Woman",
- "Old Man",
- "Random Guy",
- "Old Woman",
- "Old Woman",
- "Old Man",
- "Random Guy",
- "Old Woman",
- "Young Woman",
- "Docks Worker",
- "Docks Worker",
- "Male Street Bum",
- "Female Street Bum",
- "Delivery Guy",
- "Delivery Guy",
- "Business Man",
- "Marty Chonks",
- "Cia Agent",
- "Female Client",
- "Young Woman",
- "Business Woman",
- "Business Man",
- "Female Client",
- "Male Steward",
- "Female Steward",
- "Male Cocks Fan",
- "Male Cocks Fan",
- "Female Cocks Fan",
- "Male Paramedics Assistant",
- "Female Paramedics Assistant",
- "Construction Worker",
- "Construction Worker",
- "Zip Customer",
- "Party Woman",
- "Party Woman",
- "Male College Student",
- "Female College Student",
- "Old Man",
- "Female Jogger",
- "Asuka Kasen",
- "Spank Suicide Bomber",
- "Salvatore's Butler",
- "Catalina",
- "Lee Chong",
- "Colombian Cartel Member",
- "Colombian Cartel Member",
- "Colombian Cartel Member",
- "Colombian Cartel Member",
- "Police Officer",
- "Curly Bob",
- "Phil Cassidy",
- "Detective",
- "8-Ball",
- "8-Ball",
- "Salvatore Leone",
- "Mafia Member",
- "Joey Leone",
- "Joey Leone",
- "Bar Owner",
- "Kenji Kasen",
- "Mike Forelli",
- "Donald Love",
- "Donald Love",
- "Luigi Goterelli",
- "Maria Latore",
- "Mickey Hamfists",
- "Miguel",
- "Misty",
- "Old Oriental Gentleman",
- "Old Oriental Gentleman",
- "Old Oriental Gentleman",
- "Ray Machowski",
- "Mafia Member",
- "Ammu-Nation Clerk",
- "Tanner",
- "Toni Cipriani",
- "Darkel",
- "Chuff Security Officer",
- "Claude"
- ],
- [ // GTA Vice City
- "Tommy Vercetti",
- "Police Officer",
- "SWAT Officer",
- "FBI Agent",
- "Army Soldier",
- "Paramedic",
- "Fireman",
- "Golfer",
- "INVALID",
- "Random Lady",
- "Bum",
- "Greaser",
- "Random Guy",
- "Random Guy",
- "Random Lady",
- "Random Guy",
- "Random Guy",
- "Beach Girl",
- "Fat Beach Lady",
- "Beach Guy",
- "Fat Beach Guy",
- "Random Lady",
- "Random Lady",
- "Random Lady",
- "Prostitute",
- "Bum",
- "Bum",
- "Random Guy",
- "Taxi Driver",
- "Haitian",
- "Criminal",
- "Random Lady",
- "Random Lady",
- "Random Guy",
- "Random Guy",
- "Random Lady",
- "Random Lady",
- "Random Guy",
- "Beach Lady",
- "Beach Guy",
- "Beach Lady",
- "Beach Guy",
- "Random Guy",
- "Prostitute",
- "Bum",
- "Bum",
- "Random Guy",
- "Random Guy",
- "Punk",
- "Prostitute",
- "Random Old Lady",
- "Punk",
- "Random Guy",
- "Random Lady",
- "Random Lady",
- "Random Guy",
- "Random Guy",
- "Beach Lady",
- "Beach Guy",
- "Beach Lady",
- "Beach Guy",
- "Construction Worker",
- "Golfer",
- "Golfer",
- "Golfer",
- "Beach Lady",
- "Beach Guy",
- "Random Lady",
- "Random Guy",
- "Random Guy",
- "Prostitute",
- "Bum Lady",
- "Random Guy",
- "Random Guy",
- "Taxi Driver",
- "Random Woman",
- "Skater Guy",
- "Beach Lady",
- "Skater Guy",
- "Young Woman Shopper",
- "Old Women Shopper",
- "Tourist",
- "Tourist",
- "Cuban",
- "Cuban",
- "Haitian",
- "Haitian",
- "Shark",
- "Shark",
- "Diaz Guy",
- "Diaz Guy",
- "Security Guard",
- "Security Guard",
- "Biker",
- "Biker",
- "Vercetti Guy",
- "Vercetti Guy",
- "Undercover Cop",
- "Undercover Cop",
- "Undercover Cop",
- "Undercover Cop ",
- "Undercover Cop",
- "Undercover Cop",
- "Random Guy",
- "Bodyguard",
- "Prostitute",
- "Prostitute",
- "Love Fist Guy",
- "Ken Rosenburg",
- "Candy Suxx",
- "Hilary",
- "Love Fist",
- "Phil",
- "Rockstar Guy",
- "Sonny",
- "Lance",
- "Mercades",
- "Love Fist",
- "Alex Scrub",
- "Lance Vance",
- "Lance Vance",
- "Cpt. Cortez",
- "Love Fist",
- "Columbian",
- "Hilary",
- "Mercades",
- "Cam",
- "Cam",
- "Phil",
- "Phil",
- "Bodyguard",
- "Pizza Worker",
- "Taxi Driver",
- "Taxi Driver",
- "Sailor",
- "Sailor",
- "Sailor",
- "Chef",
- "Criminal",
- "French Guy",
- "Worker",
- "Hatian",
- "Waitress",
- "Forelli Member",
- "Forelli Member",
- "Forelli Member",
- "Columbian",
- "Random Guy",
- "Beach Guy",
- "Random Guy",
- "Random Guy",
- "Random Guy",
- "Drag Queen",
- "Diaz Traitor",
- "Random Guy",
- "Random Guy",
- "Stripper",
- "Stripper",
- "Stripper",
- "Store Clerk"
- ],
- [ // GTA San Andreas
- "Carl 'CJ' Johnson",
- "The Truth",
- "Maccer",
- "Andre",
- "Barry 'Big Bear' Thorne",
- "Emmet",
- "Taxi Driver/Train Driver",
- "Janitor",
- "Normal Ped",
- "Old Woman",
- "Casino Croupier",
- "Rich Woman",
- "Street Girl",
- "Normal Ped",
- "Mr.Whittaker (Rs Haul Owner)",
- "Airport Ground Worker",
- "Businessman",
- "Beach Visitor",
- "DJ",
- "Rich Guy (Madd Dogg's Manager)",
- "Normal Ped",
- "Normal Ped",
- "Bmxer",
- "Madd Dogg Bodyguard",
- "Madd Dogg Bodyguard",
- "Backpacker",
- "Construction Worker",
- "Drug Dealer",
- "Drug Dealer",
- "Drug Dealer",
- "Farm-Town Inhabitant",
- "Farm-Town Inhabitant",
- "Farm-Town Inhabitant",
- "Farm-Town Inhabitant",
- "Gardener",
- "Golfer",
- "Golfer",
- "Normal Ped",
- "Normal Ped",
- "Normal Ped",
- "Normal Ped",
- "Jethro",
- "Normal Ped",
- "Normal Ped",
- "Beach Visitor",
- "Normal Ped",
- "Normal Ped",
- "Normal Ped",
- "Snakehead (Da Nang)",
- "Mechanic",
- "Mountain Biker",
- "Mountain Biker",
- "Unknown",
- "Normal Ped",
- "Normal Ped",
- "Normal Ped",
- "Oriental Ped",
- "Oriental Ped",
- "Normal Ped",
- "Normal Ped",
- "Pilot",
- "Colonel Fuhrberger",
- "Prostitute",
- "Prostitute",
- "Kendl Johnson",
- "Pool Player",
- "Pool Player",
- "Priest/Preacher",
- "Normal Ped",
- "Scientist",
- "Security Guard",
- "Hippy",
- "Hippy",
- "Prostitute",
- "Stewardess",
- "Homeless",
- "Homeless",
- "Homeless",
- "Boxer",
- "Boxer",
- "Black Elvis",
- "White Elvis",
- "Blue Elvis",
- "Prostitute",
- "Ryder With Robbery Mask",
- "Stripper",
- "Normal Ped",
- "Normal Ped",
- "Jogger",
- "Rich Woman",
- "Rollerskater",
- "Normal Ped",
- "Normal Ped",
- "Normal Ped",
- "Jogger",
- "Lifeguard",
- "Normal Ped",
- "Rollerskater",
- "Biker",
- "Normal Ped",
- "Balla",
- "Balla",
- "Balla",
- "Grove Street Families",
- "Grove Street Families",
- "Grove Street Families",
- "Los Santos Vagos",
- "Los Santos Vagos",
- "Los Santos Vagos",
- "The Russian Mafia",
- "The Russian Mafia",
- "The Russian Mafia",
- "Varios Los Aztecas",
- "Varios Los Aztecas",
- "Varios Los Aztecas",
- "Triad",
- "Triad",
- "Johhny Sindacco",
- "Triad Boss",
- "Da Nang Boy",
- "Da Nang Boy",
- "Da Nang Boy",
- "The Mafia",
- "The Mafia",
- "The Mafia",
- "The Mafia",
- "Farm Inhabitant",
- "Farm Inhabitant",
- "Farm Inhabitant",
- "Farm Inhabitant",
- "Farm Inhabitant",
- "Farm Inhabitant",
- "Homeless",
- "Homeless",
- "Normal Ped",
- "Homeless",
- "Beach Visitor",
- "Beach Visitor",
- "Beach Visitor",
- "Businesswoman",
- "Taxi Driver",
- "Crack Maker",
- "Crack Maker",
- "Crack Maker",
- "Crack Maker",
- "Businessman",
- "Businesswoman",
- "Big Smoke Armored",
- "Businesswoman",
- "Normal Ped",
- "Prostitute",
- "Construction Worker",
- "Beach Visitor",
- "Well Stacked Pizza Worker",
- "Barber",
- "Hillbilly",
- "Farmer",
- "Hillbilly",
- "Hillbilly",
- "Farmer",
- "Hillbilly",
- "Black Bouncer",
- "White Bouncer",
- "White Mib Agent",
- "Black Mib Agent",
- "Cluckin' Bell Worker",
- "Hotdog/Chilli Dog Vendor",
- "Normal Ped",
- "Normal Ped",
- "Blackjack Dealer",
- "Casino Croupier",
- "San Fierro Rifa",
- "San Fierro Rifa",
- "San Fierro Rifa",
- "Barber",
- "Barber",
- "Whore",
- "Ammunation Salesman",
- "Tattoo Artist",
- "Punk",
- "Cab Driver",
- "Normal Ped",
- "Normal Ped",
- "Normal Ped",
- "Normal Ped",
- "Businessman",
- "Normal Ped",
- "Valet",
- "Barbara Schternvart",
- "Helena Wankstein",
- "Michelle Cannes",
- "Katie Zhan",
- "Millie Perkins",
- "Denise Robinson",
- "Farm-Town Inhabitant",
- "Hillbilly",
- "Farm-Town Inhabitant",
- "Farm-Town Inhabitant",
- "Hillbilly",
- "Farmer",
- "Farmer",
- "Karate Teacher",
- "Karate Teacher",
- "Burger Shot Cashier",
- "Cab Driver",
- "Prostitute",
- "Su Xi Mu (Suzie)",
- "Oriental Noodle Stand Vendor",
- "Oriental Boating School Instructor",
- "Clothes Shop Staff",
- "Homeless",
- "Weird Old Man",
- "Waitress (Maria Latore)",
- "Normal Ped",
- "Normal Ped",
- "Clothes Shop Staff",
- "Normal Ped",
- "Rich Woman",
- "Cab Driver",
- "Normal Ped",
- "Normal Ped",
- "Normal Ped",
- "Normal Ped",
- "Normal Ped",
- "Normal Ped",
- "Oriental Businessman",
- "Oriental Ped",
- "Oriental Ped",
- "Homeless",
- "Normal Ped",
- "Normal Ped",
- "Normal Ped",
- "Cab Driver",
- "Normal Ped",
- "Normal Ped",
- "Prostitute",
- "Prostitute",
- "Homeless",
- "The D.A",
- "Afro-American",
- "Mexican",
- "Prostitute",
- "Stripper",
- "Prostitute",
- "Stripper",
- "Biker",
- "Biker",
- "Pimp",
- "Normal Ped",
- "Lifeguard",
- "Naked Valet",
- "Bus Driver",
- "Biker Drug Dealer",
- "Chauffeur (Limo Driver)",
- "Stripper",
- "Stripper",
- "Heckler",
- "Heckler",
- "Construction Worker",
- "Cab Driver",
- "Cab Driver",
- "Normal Ped",
- "Clown (Ice-Cream Van Driver)",
- "Officer Frank Tenpenny",
- "Officer Eddie Pulaski",
- "Officer Jimmy Hernandez",
- "Dwaine/Dwayne",
- "Melvin 'Big Smoke' Harris (Mission)",
- "Sean 'Sweet' Johnson",
- "Lance 'Ryder' Wilson",
- "Mafia Boss",
- "T-Bone Mendez",
- "Paramedic",
- "Paramedic",
- "Paramedic",
- "Firefighter",
- "Firefighter",
- "Firefighter",
- "Los Santos Police Officer",
- "San Fierro Police Officer",
- "Las Venturas Police Officer",
- "County Sheriff",
- "Motorbike Cop",
- "S.W.A.T.",
- "Federal Agent",
- "Army Soldier",
- "Desert Sheriff",
- "Zero",
- "Ken Rosenberg",
- "Kent Paul",
- "Cesar Vialpando",
- "Jeffery 'Og Loc' Martin/Cross",
- "Wu Zi Mu (Woozie)",
- "Michael Toreno",
- "Jizzy B.",
- "Madd Dogg",
- "Catalina",
- "Claude Speed"
- ],
- ],
- weaponModels: [
- [],
- [ // GTA III
- 0, // Fist
- 172, // Baseball Bat
- 173, // Colt 45
- 178, // Uzi
- 176, // Shotgun
- 171, // AK-47
- 180, // M16
- 177, // Sniper Rifle
- 175, // Rocket Launcher
- 181, // Flamethrower
- 174, // Molotov Cocktail
- 170 // Grenade
- ],
- [ // GTA Vice City
- 0,
- 259,
- 260,
- 261,
- 262,
- 263,
- 264,
- 265,
- 266,
- 267,
- 268,
- 269,
- 270,
- 291,
- 271,
- 272,
- 273,
- 274,
- 275,
- 277,
- 278,
- 279,
- 281,
- 282,
- 283,
- 284,
- 280,
- 276,
- 285,
- 286,
- 287,
- 288,
- 289,
- 290,
- -1,
- -1,
- 292
- ],
- [ // GTA San Andreas
-
- ],
- ],
- locations: [
- [],
-
- [ // GTA III
- // Police Stations
- ["Portland Police Station", [1143.875, -675.1875, 14.97], 0.0],
- ["Staunton Island Police Station", [340.25, -1123.375, 25.98], 0.0],
- ["Shoreside Vale Police Station", [-1253.0, -138.1875, 58.75], 0.0],
-
- // Hospitals
- ["Portland Hospital", [1144.25, -596.875, 14.97], 0.0],
- ["Staunton Island Hospital", [183.5, -17.75, 16.21], 0.0],
- ["Shoreside Vale Hospital", [-1259.5, -44.5, 58.89], 0.0],
-
- // Fire Stations
- ["Portland Fire Station", [1103.70, -52.45, 7.49], 0.0],
- ["Staunton Island Fire Station", [-78.48, -436.80, 16.17], 0.0],
- ["Shoreside Vale Fire Station", [-1202.10, -14.67, 53.20], 0.0],
-
- // Pay and Sprays
- ["Portland Pay and Spray", [925.4, -360.3, 10.83], 0.0],
- ["Staunton Island Pay and Spray", [381.8, -493.8, 25.95], 0.0],
- ["Shoreside Vale Pay and Spray", [-1142.4, 35.01, 58.61], 0.0],
-
- // Ammunations
- ["Portland Ammunation", [1068.3, -400.9, 15.24], 0.0],
- ["Staunton Island Ammunation", [348.2, -717.9, 26.43], 0.0],
-
- // Train Stations
- ["Bedford Point Train Station", [178.52, -1551.40, 26.162], -3.105],
- ["Francis International Airport Train Station", [-633.42, -760.06, 18.919], 1.586],
- ["Rockford Train Station", [225.66, -69.07, 20.998], -3.115],
- ["Saint Marks Train Station", [1306.69, -512.38, 40.078], -2.458],
- ["Hepburn Heights Train Station", [1029.07, -164.18, 4.972], 0.005],
- ["Chinatown Train Station", [775.27, -622.28, 14.747], 0.006],
-
- // Safehouses
- ["Portland Safehouse", [885.52, -308.47, 8.615], -1.532],
-
- // Other
- ["St Mathias College", [201.59, -281.42, 15.779], -0.005],
- ["Newport Parking Garage", [294.22, -547.87, 25.780], 3.119],
- ["City Hall", [96.60, -951.61, 26.168], 3.138],
- ["Belleville Park East", [109.15, -695.76, 26.168], 1.594],
- ["Belleville Park Bathroom", [38.69, -724.96, 22.756], -3.104],
- ["Belleville Park West", [0.40, -773.05, 26.056], -1.476],
- ["Stadium Entrance", [-18.65, -231.80, 29.861], 0.002],
- ["Kenji's Casino", [454.10, -1421.26, 26.124], -0.769],
- ["Saint Marks Bistro", [1345.48, -457.41, 49.549], 1.537],
- ["Leone Mansion", [1417.94, -194.18, 49.905], -1.570],
- ["Ciprianis Ristorante", [1202.50, -320.78, 24.973], -1.553],
- ["Luigi's Club", [904.82, -425.37, 14.929], 1.602],
- ["Portland Fuel Station", [1157.34, -75.45, 7.065], -0.027],
- ["Easy Credit Autos", [1217.81, -113.87, 14.973], -3.051],
- ["Head Radio Headquarters", [986.40, -46.40, 7.473], -1.615],
- ["Borgnine Taxi Headquarters", [929.36, -48.59, 7.473], -2.935],
- ["Fuzz Ball", [1000.03, -877.82, 14.547], -3.136],
- ["Portland Docks Entrance", [1360.55, -818.08, 14.415], -1.574],
- ["Punk Noodle Diner", [1040.10, -653.10, 14.973], 1.551],
- ["Greasy Joe's Diner", [864.45, -999.86, 4.646], -0.020],
- ],
-
- [ // GTA VC
- // Police Stations
- ["Washington Beach Police Station", [399.77, -468.90, 11.73], 0.0],
- ["Vice Point Police Station", [508.96, 512.07, 12.10], 0.0],
- ["Downtown Police Station", [-657.43, 762.31, 11.59], 0.0],
- ["Little Havana Police Station", [-885.08, -470.44, 13.11], 0.0],
-
- // Hospitals
- ["Downtown Hospital", [-822.57, 1152.82, 12.41], 0.0],
- ["Little Havana Medical Center", [-885.08, -470.44, 13.11], 0.0],
- ["Ocean Beach Hospital", [-133.19, -980.76, 10.46], 0.0],
- ],
-
- [ // GTA SA
- // Coming Soon!
- ],
-
- [ // GTA UG
- // Coming Soon!
- ],
-
- [ // GTA IV
- // Police Stations
- ["Broker Police Station", [894.99, -357.39, 18.185], 2.923],
- ["South Bohan Police Station", [435.40, 1592.29, 17.353], 3.087],
- ["Northern Gardens Police Station", [974.93, 1870.45, 23.073], -1.621],
- ["South Slopes Police Station", [1233.25, -89.13, 28.034], 1.568],
- ["Middle Part East Police Station", [50.12, 679.88, 15.316], 1.569],
- ["East Holland Police Station", [85.21, 1189.82, 14.755], 3.127],
- ["Francis International Airport Police Station", [2170.87, 448.87, 6.085], 1.501],
- ["Chinatown Police Station", [213.12, -211.70, 10.752], 0.200],
- ["Acter Police Station", [-1714.95, 276.31, 22.134], 1.127],
- ["Port Tudor Police Station", [-1220.73, -231.53, 3.024], 2.210],
- ["Leftwood Police Station", [-927.66, 1263.63, 24.587], -0.913],
-
- // Fire Stations
- ["Broker Fire Station", [953.13, 95.90, 35.004], 1.595],
- ["Northwood Fire Station", [-271.02, 1542.15, 20.420], -1.160],
- ["Northern Gardens Fire Station", [1120.47, 1712.36, 10.534], -0.682],
- ["Francis International Airport Fire Station", [2364.87, 166.83, 5.813], 0.156],
- ["Chinatown Fire Station", [295.40, -336.88, 4.963], 2.887],
- ["Berchem Fire Station", [-1574.90, 546.54, 25.449], -0.509],
- ["Tudor Fire Station", [-2144.97, 164.15, 12.051], -2.149],
-
- // Safehouses
- ["Hove Beach Safehouse Parking", [904.27, -498.00, 14.522], 3.127],
- ["South Bohan Safehouse", [589.42, 1402.15, 10.364], 0.007],
-
- // Hospitals
- ["Schottler Medical Center", [1199.59, 196.78, 33.554], 1.633],
- ["Northern Gardens Medical Center", [980.71, 1831.61, 23.898], -0.049],
- ["Leftwood Hospital", [-1317.27, 1277.20, 22.370], 2.246],
- ["Acter Medical Center", [-1538.43, 344.58, 20.943], -0.156],
-
- // Fuel Stations
- ["Hove Beach Fuel Station", [1128.51, -359.55, 18.441], -0.052],
- ["Lancaster Fuel Station", [108.37, 1135.13, 13.975], 0.007],
- ["The Meat Quarter Fuel Station", [-434.30, -19.47, 9.864], 1.469],
- ["Cerveza Heights Fuel Station", [1123.50, 328.84, 29.245], -0.154],
- ["Tudor Fuel Station", [-1389.91, 29.19, 6.875], 0.982],
-
- // Restaurants
- ["Star Junction Burger Shot", [-174.00, 276.96, 14.818], -0.029],
- ["South Bohan Burger Shot", [441.95, 1516.64, 16.289], -2.682],
- ["Industrial Burger Shot", [1096.93, 1598.33, 16.721], -2.289],
-
- // Night Clubs/Strip Clubs/Bars
- ["Perestroika Club", [957.58, -292.58, 19.644], -0.009],
- ["Triangle Club", [1210.90, 1718.18, 16.667], 1.819],
-
- // TW@ Cafes
- ["Outlook Internet Cafe", [977.42, -169.11, 24.013], 1.844],
- ["Berchem Internet Cafe", [-1584.46, 466.05, 25.398], -2.441],
-
- // Pay-n-Sprays
- ["Hove Beach Pay-n-Spray", [1058.57, -282.58, 20.760], -3.135],
- ["Leftwood Pay-n-Spray", [-1148.69, 1171.52, 16.457], -0.059],
-
- // Clothes Shops
- ["Hove Beach Russian Clothes Shop", [896.31, -442.59, 15.888], 1.500],
-
- // Car Wash
- ["Willis Car Wash", [1831.02, 360.20, 22.061], -1.515],
- ["Tudor Car Wash", [-1371.68, 35.13, 7.028], 1.029],
-
- // Gun Shops
- ["Downtown Broker Gun Shop", [1054.11, 86.84, 33.408], -1.574],
- ["Chinatown Gun Shop", [65.43, -342.36, 14.767], -1.589],
- ["Port Tudor Gun Shop", [-1338.77, 307.61, 13.378], -1.530],
-
- // Train Stations
- ["Hove Beach Train Station", [1000.41, -544.82, 14.854], -1.576],
- ["Schottler Train Station", [1303.93, -37.75, 28.377], 3.065],
- ["Cerveza Heights Train Station", [1386.87, 374.13, 23.063], 3.111],
- ["Lynch Street Train Station", [1594.73, 364.80, 25.226], -0.965],
- ["East Park Train Station", [-35.78, 634.79, 14.663], -0.050],
- ["West Park Train Station", [-377.13, 677.05, 14.679], -0.069],
- ["North Park Train Station", [-135.08, 1153.95, 14.773], -1.567],
- ["Vespucci Circus Train Station", [-85.11, 1427.04, 20.421], 1.501],
- ["Frankfort Low Train Station", [-331.94, 1427.05, 12.617], 1.541],
- ["Frankfort High Train Station", [-343.79, 1433.12, 12.283], 0.113],
- ["Vauxite Train Station", [-483.38, 1333.91, 17.481], 1.509],
- ["Quartz Street West Train Station", [-545.54, 926.22, 9.945], -1.524],
- ["Manganese West Train Station", [-461.60, 530.56, 9.857], 3.091],
- ["Frankfort Ave Train Station", [-377.52, 371.91, 14.762], -3.125],
- ["Suffolk Train Station", [-252.77, -171.83, 14.447], 1.594],
- ["Feldspar Train Station", [-350.62, -335.35, 4.909], -2.287],
- ["City Hall Train Station", [-115.31, -501.22, 14.755], -1.365],
- ["Castle Gardens Train Station", [82.95, -757.81, 4.965], -1.006],
- ["Emerald Train Station", [116.57, -318.15, 14.768], 1.499],
- ["Easton Train Station", [-35.76, -18.50, 14.769], 3.137],
- ["Manganese East Train Station", [131.46, 522.74, 14.661], 0.005],
- ["Quartz Street East Train Station", [134.35, 910.15, 14.717], -0.112],
- ["San Quentin Ave Train Station", [373.12, 1625.93, 16.347], -2.249],
- ["Windmill Street Train Station", [749.97, 1447.44, 14.252], -0.120],
- ["Francis International Airport Train Station", [2297.57, 474.62, 6.086], 0.066],
-
- // Misc
- ["Hove Beach Laundromat", [1011.74, -325.33, 20.339], -1.402],
- ["The Exchange Docks", [-354.68, -661.62, 4.791], 2.066],
- ["Firefly Island Bowling", [1198.99, -681.49, 16.445], -0.017],
- ["Broker Bus Depot", [1004.15, 279.19, 31.512], -2.193],
- ["The Lost MC Clubhouse", [-1713.29, 358.25, 25.449], 2.566],
- ["Alderney State Correctional Facility", [-1155.21, -374.34, 2.885], -1.680],
- ["Chinatown Bank of Liberty", [-34.92, -466.80, 14.75], -1.52],
- ["Suffolk Church", [-274.30, -281.63, 14.36], 1.56],
-
- // More will be added soon!
- ],
-
- [ // GTA EFLC
- // Police Stations
- ["Broker Police Station", [894.99, -357.39, 18.185], 2.923],
- ["South Bohan Police Station", [435.40, 1592.29, 17.353], 3.087],
- ["Northern Gardens Police Station", [974.93, 1870.45, 23.073], -1.621],
- ["South Slopes Police Station", [1233.25, -89.13, 28.034], 1.568],
- ["Middle Part East Police Station", [50.12, 679.88, 15.316], 1.569],
- ["East Holland Police Station", [85.21, 1189.82, 14.755], 3.127],
- ["Francis International Airport Police Station", [2170.87, 448.87, 6.085], 1.501],
- ["Chinatown Police Station", [213.12, -211.70, 10.752], 0.200],
- ["Acter Police Station", [-1714.95, 276.31, 22.134], 1.127],
- ["Port Tudor Police Station", [-1220.73, -231.53, 3.024], 2.210],
- ["Leftwood Police Station", [-927.66, 1263.63, 24.587], -0.913],
-
- // Fire Stations
- ["Broker Fire Station", [953.13, 95.90, 35.004], 1.595],
- ["Northwood Fire Station", [-271.02, 1542.15, 20.420], -1.160],
- ["Northern Gardens Fire Station", [1120.47, 1712.36, 10.534], -0.682],
- ["Francis International Airport FIre Station", [2364.87, 166.83, 5.813], 0.156],
- ["Chinatown Fire Station", [295.40, -336.88, 4.963], 2.887],
- ["Berchem Fire Station", [-1574.90, 546.54, 25.449], -0.509],
- ["Tudor Fire Station", [-2144.97, 164.15, 12.051], -2.149],
-
- // Safehouses
- ["Hove Beach Safehouse Parking", [904.27, -498.00, 14.522], 3.127],
- ["South Bohan Safehouse", [589.42, 1402.15, 10.364], 0.007],
-
- // Hospitals
- ["Schottler Medical Center", [1199.59, 196.78, 33.554], 1.633],
- ["Northern Gardens Medical Center", [980.71, 1831.61, 23.898], -0.049],
- ["Leftwood Hospital", [-1317.27, 1277.20, 22.370], 2.246],
- ["Acter Medical Center", [-1538.43, 344.58, 20.943], -0.156],
-
- // Fuel Stations
- ["Hove Beach Fuel Station", [1128.51, -359.55, 18.441], -0.052],
- ["Lancaster Fuel Station", [108.37, 1135.13, 13.975], 0.007],
- ["The Meat Quarter Fuel Station", [-434.30, -19.47, 9.864], 1.469],
- ["Cerveza Heights Fuel Station", [1123.50, 328.84, 29.245], -0.154],
- ["Tudor Fuel Station", [-1389.91, 29.19, 6.875], 0.982],
-
- // Restaurants
- ["Star Junction Burger Shot", [-174.00, 276.96, 14.818], -0.029],
- ["South Bohan Burger Shot", [441.95, 1516.64, 16.289], -2.682],
- ["Industrial Burger Shot", [1096.93, 1598.33, 16.721], -2.289],
-
- // Night Clubs/Strip Clubs/Bars
- ["Perestroika Club", [957.58, -292.58, 19.644], -0.009],
- ["Triangle Club", [1210.90, 1718.18, 16.667], 1.819],
-
- // TW@ Cafes
- ["Outlook Internet Cafe", [977.42, -169.11, 24.013], 1.844],
- ["Berchem Internet Cafe", [-1584.46, 466.05, 25.398], -2.441],
-
- // Pay-n-Sprays
- ["Hove Beach Pay-n-Spray", [1058.57, -282.58, 20.760], -3.135],
- ["Leftwood Pay-n-Spray", [-1148.69, 1171.52, 16.457], -0.059],
-
- // Clothes Shops
- ["Hove Beach Russian Clothes Shop", [896.31, -442.59, 15.888], 1.500],
-
- // Car Wash
- ["Willis Car Wash", [1831.02, 360.20, 22.061], -1.515],
- ["Tudor Car Wash", [-1371.68, 35.13, 7.028], 1.029],
-
- // Gun Shops
- ["Downtown Broker Gun Shop", [1054.11, 86.84, 33.408], -1.574],
- ["Chinatown Gun Shop", [65.43, -342.36, 14.767], -1.589],
- ["Port Tudor Gun Shop", [-1338.77, 307.61, 13.378], -1.530],
-
- // Train Stations
- ["Hove Beach Train Station", [1000.41, -544.82, 14.854], -1.576],
- ["Schottler Train Station", [1303.93, -37.75, 28.377], 3.065],
- ["Cerveza Heights Train Station", [1386.87, 374.13, 23.063], 3.111],
- ["Lynch Street Train Station", [1594.73, 364.80, 25.226], -0.965],
- ["East Park Train Station", [-35.78, 634.79, 14.663], -0.050],
- ["West Park Train Station", [-377.13, 677.05, 14.679], -0.069],
- ["North Park Train Station", [-135.08, 1153.95, 14.773], -1.567],
- ["Vespucci Circus Train Station", [-85.11, 1427.04, 20.421], 1.501],
- ["Frankfort Low Train Station", [-331.94, 1427.05, 12.617], 1.541],
- ["Frankfort High Train Station", [-343.79, 1433.12, 12.283], 0.113],
- ["Vauxite Train Station", [-483.38, 1333.91, 17.481], 1.509],
- ["Quartz Street West Train Station", [-545.54, 926.22, 9.945], -1.524],
- ["Manganese West Train Station", [-461.60, 530.56, 9.857], 3.091],
- ["Frankfort Ave Train Station", [-377.52, 371.91, 14.762], -3.125],
- ["Suffolk Train Station", [-252.77, -171.83, 14.447], 1.594],
- ["Feldspar Train Station", [-350.62, -335.35, 4.909], -2.287],
- ["City Hall Train Station", [-115.31, -501.22, 14.755], -1.365],
- ["Castle Gardens Train Station", [82.95, -757.81, 4.965], -1.006],
- ["Emerald Train Station", [116.57, -318.15, 14.768], 1.499],
- ["Easton Train Station", [-35.76, -18.50, 14.769], 3.137],
- ["Manganese East Train Station", [131.46, 522.74, 14.661], 0.005],
- ["Quartz Street East Train Station", [134.35, 910.15, 14.717], -0.112],
- ["San Quentin Ave Train Station", [373.12, 1625.93, 16.347], -2.249],
- ["Windmill Street Train Station", [749.97, 1447.44, 14.252], -0.120],
- ["Francis International Airport Train Station", [2297.57, 474.62, 6.086], 0.066],
-
- // Misc
- ["Hove Beach Laundromat", [1011.74, -325.33, 20.339], -1.402],
- ["The Exchange Docks", [-354.68, -661.62, 4.791], 2.066],
- ["Firefly Island Bowling", [1198.99, -681.49, 16.445], -0.017],
- ["Broker Bus Depot", [1004.15, 279.19, 31.512], -2.193],
- ["The Lost MC Clubhouse", [-1713.29, 358.25, 25.449], 2.566],
- ["Alderney State Correctional Facility", [-1155.21, -374.34, 2.885], -1.680],
- ["Chinatown Bank of Liberty", [-34.92, -466.80, 14.75], -1.52],
- ["Suffolk Church", [-274.30, -281.63, 14.36], 1.56],
-
- // More will be added soon!
- ],
- ],
- gtaivSkinModels: [
- //["Nico Bellic", 1862763509],
- ["Male Multiplayer", -2020305438],
- ["Female Multiplayer", -641875910],
- ["MODEL_SUPERLOD", -1370810922],
- ["Anna", 1853617247],
- ["Anthony", -1646893330],
- ["Badman", 1495769888],
- ["Bernie Crane", 1500493064],
- ["Bledar", 1731510984],
- ["Brian", 422305098],
- ["Brucie", -1729980128],
- ["Bulgarin", 237511807],
- ["Charise", 88667657],
- ["Charlie Undercover", -1328445565],
- ["Clarence", 1343144208],
- ["Dardan", 1468450703],
- ["Darko", 386513184],
- ["Derric", 1169442297],
- ["Dmitri", 237497537],
- ["Dwayne", -617264103],
- ["Eddie", -1600585231],
- ["Faustin", 57218969],
- ["Francis", 1710545037],
- ["French Tom", 1424670436],
- ["Gordon", 2129490787],
- ["Gracie", -357652594],
- ["Hossan", 980768434],
- ["Ilyena", -835225126],
- ["Issac", -479595866],
- ["Ivan", 1166762483],
- ["Jay", 364686627],
- ["Jason", 170756246],
- ["Jeff", 390357829],
- ["Jimmy", -366421228],
- ["Johnny Klebitz", -911507684],
- ["Kate", -773750838],
- ["Kenny", 995576506],
- ["Lil Jacob", 1487004273],
- ["Lil Jacob 2", -1275031987],
- ["Luca", -681942840],
- ["Luis", -492470690],
- ["Mallorie", -1040287406],
- ["Mam", -322700377],
- ["Manny", 1445589009],
- ["Marnie", 411185872],
- ["Mel", -807339118],
- ["Michael", 735211577],
- ["Michelle", -1080659212],
- ["Mickey", -636669566],
- ["Packie", 1690783035],
- ["Pathos", -165448092],
- ["Petrovic", -1947682830],
- ["Phil Bell", -1826458934],
- ["Playboy X", 1794146792],
- ["Ray Boccino", 954215094],
- ["Ricky", -587324132],
- ["Roman", -1992728631],
- ["Roman 2", 558221221],
- ["Sarah", -17823883],
- ["Tuna", 1384833284],
- ["Vinny Spaz", -1014976873],
- ["Vlad", 896408642],
- ["Black Street Thug 1", -301223260],
- ["Black Street Thug 2", -1143910864],
- ["Black Street OG 1", 869501081],
- ["Black Street OG 1", 632613980],
- ["Albanian Thug 1", -503930010],
- ["Albanian Thug 2", -235584669],
- ["Albanian Thug 3", 207714363],
- ["Albanian Thug 4", 514268366],
- ["Biker 1", 43005364],
- ["Biker 2", 1346668127],
- ["Biker 3", -1677255197],
- ["Biker 4", -1461281345],
- ["Biker 5", 1574850459],
- ["Biker 6", -1953289472],
- ["Irish Man 1", 280474699],
- ["Irish Man 2", -19263344],
- ["Irish Man 3", 1844702918],
- ["Jamaican OG 1", 1609755055],
- ["Jamaican OG 2", -330497431],
- ["Jamaican OG 3", 1117105909],
- ["Jamaican Thug 1", -1500397869],
- ["Jamaican Thug 2", -881358690],
- ["Asian Man 1", 1540383669],
- ["Asian Man 2", 764249904],
- ["Hispanic Man 1", 492147228],
- ["Hispanic Man 2", -1926041127],
- ["Hispanic Man 3", 1168388225],
- ["Hispanic Man 4", -1746774780],
- ["Fat Italian Mafia Boss", -302362397],
- ["Italian Mafia Boss", -1616890832],
- ["Italian Mafia Associate", 64730935],
- ["Fat Italian Mafia Associate", 510389335],
- ["Russian Thug 1", -1836006237],
- ["Russian Thug 2", -2088164056],
- ["Russian Thug 3", 1976502708],
- ["Russian Thug 4", 1543404628],
- ["Russian Thug 5", 1865532596],
- ["Russian Thug 6", 431692232],
- ["Russian Thug 7", 1724587620],
- ["Russian Thug 8", -1180674815],
- ["Triad Boss 1", 871281791],
- ["Triad Boss 2", 683712035],
- ["Triad Member 3", -1084007777],
- ["Triad Member 4", -164935626],
- ["Female Maid", -751071255],
- ["Female Binco Worker", -109247258],
- ["Female Bank Teller", 1366257926],
- ["Female Doctor", 346338575],
- ["Female Gym Worker", 1350216795],
- ["Female Burger Shot Worker", 924926104],
- ["Female Cluckin Bell Worker", -346378101],
- ["Female Rockstar Cafe Worker", -2104311883],
- ["Female TW@ Cafe Worker", 212900845],
- ["Female Well Stacked Pizza Worker", -290070895],
- ["Hooker", 552542187],
- ["Hooker 2", 996267216],
- ["Nurse", -1193778389],
- ["Stripper 1", 1113677074],
- ["Stripper 2", 1353709999],
- ["Waitress", 24233425],
- ["Alcoholic Man", -1761003415],
- ["Armoured Truck Driver", 1075583233],
- ["Bus Driver", 134077503],
- ["Generic Asian Man", 757349871],
- ["Black Crackhead", -1827421800],
- ["Doctor (Scrubs)", 219393781],
- ["Doctor", -1186940778],
- ["Doctor (Blood Covered Coat)", 375732086],
- ["Cook", 2105015949],
- ["Italian Mob Enforcer", -200234085],
- ["Factory Worker", 800131009],
- ["FIB Agent", -999506922],
- ["Fat Delivery Driver", -1993909080],
- ["Fire Chief", 610888851],
- ["Mercenary Soldier", 486302863],
- ["Helicopter Pilot", -778316080],
- ["Hotel Doorman", 624314380],
- ["Korean Cook", -1784833142],
- ["Lawyer 1", -1852976689],
- ["Lawyer 2", -1134712978],
- ["Loony Black Man", 379171768],
- ["Pilot", -1945168882],
- ["Generic Man", 807236245],
- ["Postal Worker", -284362863],
- ["Saxophone Player", -1188246269],
- ["Security Guard", -1870989171],
- ["Stadium Food Vendor", 420915580],
- ["Stadium Food Cook", 1878085135],
- ["Street Food Vendor", 142730876],
- ["Street Sweeper Driver", -690681764],
- ["Taxi Driver", 8772846],
- ["Telephone Company Worker", 1186270890],
- ["Tennis Player", -379234846],
- ["Train Conductor", 1159759556],
- ["Homeless Black Man", -142386662],
- ["Trucker", -46564867],
- ["Janitor", -1284047560],
- ["Hotel Doorman 2", 22944263],
- ["Mob Boss", 1178487645],
- ["Airport Worker", -1464712858],
- ["Bartender", -2139064254],
- ["Biker Bouncer", -1780698891],
- ["High End Club Bouncer", -409283472],
- ["Bowling Alley Worker", -799229885],
- ["Bowling Alley Worker 2", -434183225],
- ["Chinese Food Vendor", 768442188],
- ["Club Security", 676448572],
- ["Construction Worker", -722019798],
- ["Construction Worker 2", -1015957728],
- ["Construction Worker 3", -714220780],
- ["Police Officer", -183203150],
- ["Traffic Officer", -1518937979],
- ["Fat Police Officer", -370395528],
- ["Courier", -1371133859],
- ["Cowboy 1", -573788283],
- ["Drug Dealer 1", -1283406538],
- ["Drug Dealer 2", 1448755353],
- ["Male Burger Shot Worker", 989485],
- ["Male Cluckin Bell Worker", -1011530423],
- ["Male Rockstar Cafe Worker", 1979561477],
- ["Male TW@ Cafe Worker", -786449781],
- ["Male Well Stacked Pizza Worker", 206941425],
- ["Firefighter", -610224615],
- ["Garbage Collector", 1136499716],
- ["Goon", 897868981],
- ["Male Gym Worker", -1902758612],
- ["Mechanic 2", -356904519],
- ["Male Modo Worker", -1056268969],
- ["Helicopter Pilot", 1201610759],
- ["Perseus", -151000142],
- ["Generic Male 1", 501136335],
- ["Generic Male 2", 186619473],
- ["Generic Male 3", -111611196],
- ["Paramedic", -1175077216],
- ["Prisoner", -1676937780],
- ["Prisoner 2", 215190023],
- ["Roman's Taxi Service Driver", 1552970117],
- ["Male Runner", -1481923910],
- ["Male Shop Assistant 1", 357919731],
- ["State Trooper", -89302119],
- ["SWAT", -1004762946],
- ["Sword Swallower", -64233032],
- ["Thief", -1292254815],
- ["Valet", 271284208],
- ["Vendor", -186113957],
- ["French Tom", -2015686009],
- ["Jim Fitz", 1977784957],
- ["East European Woman", -203833294],
- ["East European Woman 2", 189853472],
- ["Woman", -349043578],
- ["Jersey Woman", -114937692],
- ["Oriental Woman", -1697333660],
- ["Rich Woman", 100706569],
- ["Business Woman 1", 155063868],
- ["Business Woman 2", 394310337],
- ["Chinatown Woman", 1375728805],
- ["Business Woman 3", -284229525],
- ["East European Woman 3", 677687516],
- ["Fat Black Woman", -1188238883],
- ["Jersey Woman 1", -2075220936],
- ["Jersey Woman 2", -1356924456],
- ["Fat Hispanic Woman 1", 812112483],
- ["Fat Hispanic Woman 2", -129242580],
- ["White Manhattan Woman", 852423121],
- ["Black Manhattan Woman", 76551508],
- ["Old Asian Woman", -2118501976],
- ["Old Rich Woman", 1616769823],
- ["Business Woman 4", 453889158],
- ["Asian Woman in Dress", 824245375],
- ["Fat Black Bronx Woman", -1362442041],
- ["Random White Woman", -1788328884],
- ["Random Hispanic Woman", -1523915823],
- ["Random Eastern European Woman", -949987237],
- ["Random Black Woman", -1926577323],
- ["Black Harlem Woman 1", 168065679],
- ["Fat Jersey Woman 1", 441464],
- ["Fat Hispanic Woman 3", 54114008],
- ["Hispanic Woman 1", -292713088],
- ["Hispanic Woman 2", 1743814728],
- ["Manhattan Woman 1", 1670568326],
- ["Manhattan Woman 2", 1354281938],
- ["Manhattan Woman 1", 1056837725],
- ["Asian Woman 1", -1193633577],
- ["Black Woman 2", 713691120],
- ["Rich White Woman 1", -1780385799],
- ["Asian Woman", -952185135],
- ["Female Shopper 1", 1586287288],
- ["Female Shopper 2", 1848013291],
- ["Female Shopper 3", -1702036227],
- ["Female Socialite 1", 1182843182],
- ["Street Woman 1", -900623157],
- ["Street Woman 2", 286007875],
- ["Street Woman 3", 1473654742],
- ["Street Woman 4", -1850743775],
- ["Street Woman 5", 1290755317],
- ["Street Woman 6", 1872110126],
- ["Tourist Woman 1", 1754440500],
- ["MODEL_F_Y_VILLBO_01", 761763258],
- ["Business Man 1", -636579119],
- ["Business Man 2", -1754526315],
- ["Street Criminal 1", -1516474414],
- ["Street Criminal 2", -1821258883],
- ["Obese Mafia Thug", 1952671026],
- ["Gay Man 1", -1991603022],
- ["Homeless Bum 1", -1080673049],
- ["Loony White Man 1", 495499562],
- ["MODEL_M_M_MIDTOWN_01", -1984134881],
- ["Business Man 2", 1063816580],
- ["Eastern European Man 1", 208763854],
- ["Fat Black Man 2", -1020237172],
- ["MODEL_M_M_PINDUS_02", 1782277836],
- ["Fat Italian Man 1", -1402442039],
- ["Italian Man 2", -1628417063],
- ["Hispanic Man 1", 1158569407],
- ["Hispanic Man 2", 1969438324],
- ["Hispanic Man 3", 1621955848],
- ["Tourist Man 1", -657489059],
- ["Black Business Man 1", -1307068958],
- ["Asian Man 3", 734334931],
- ["MODEL_M_M_PRICH_01", 1865082075],
- ["MODEL_M_O_EASTEURO_01", -432593815],
- ["Hasidic Jewish Man 1", -1639359785],
- ["Old Man 1", 1656087115],
- ["MODEL_M_O_PEASTEURO_02", 2034185905],
- ["MODEL_M_O_PHARBRON_01", 1316404726],
- ["MODEL_M_O_PJERSEY_01", 980990533],
- ["MODEL_M_O_STREET_01", -1298691925],
- ["Old Business Man", 243672348],
- ["MODEL_M_Y_BOHO_01", 2085884255],
- ["MODEL_M_Y_BOHOGUY_01", 221246143],
- ["MODEL_M_Y_BRONX_01", 52357603],
- ["Black Business Man 2", 1530937394],
- ["Black Business Man 3", 690281432],
- ["Asian Man 4", -1149743642],
- ["Chopshop Mechanic 1", -314369597],
- ["Chopshop Mechanic 2", -552829610],
- ["MODEL_M_Y_DODGY_01", -1097188138],
- ["MODEL_M_Y_DORK_02", -1775659292],
- ["MODEL_M_Y_DOWNTOWN_01", 1207402441],
- ["MODEL_M_Y_DOWNTOWN_02", 1500619449],
- ["MODEL_M_Y_DOWNTOWN_03", 594261682],
- ["MODEL_M_Y_GAYYOUNG", -747824291],
- ["MODEL_M_Y_GENSTREET_11", -677160979],
- ["MODEL_M_Y_GENSTREET_16", -1678614360],
- ["MODEL_M_Y_GENSTREET_20", 989044076],
- ["MODEL_M_Y_GENSTREET_34", 1180218190],
- ["MODEL_M_Y_HARDMAN_01", -1420592428],
- ["MODEL_M_Y_HARLEM_01", -1222963415],
- ["MODEL_M_Y_HARLEM_02", -1746153269],
- ["MODEL_M_Y_HARLEM_04", 2104499156],
- ["Hasidic Jewish Man 2", -1874580889],
- ["MODEL_M_Y_LEASTSIDE_01", -1055386282],
- ["MODEL_M_Y_PBRONX_01", 575808580],
- ["MODEL_M_Y_PCOOL_01", -71980543],
- ["MODEL_M_Y_PCOOL_02", -195159218],
- ["MODEL_M_Y_PEASTEURO_01", 697247370],
- ["MODEL_M_Y_PHARBRON_01", 670406267],
- ["MODEL_M_Y_PHARLEM_01", 26615298],
- ["MODEL_M_Y_PJERSEY_01", 1542927558],
- ["MODEL_M_Y_PLATIN_01", -1806886352],
- ["MODEL_M_Y_PLATIN_02", -1022920796],
- ["MODEL_M_Y_PLATIN_03", -1326394505],
- ["MODEL_M_Y_PMANHAT_01", 607901190],
- ["MODEL_M_Y_PMANHAT_02", 1968470106],
- ["MODEL_M_Y_PORIENT_01", -344136289],
- ["MODEL_M_Y_PQUEENS_01", 560413584],
- ["MODEL_M_Y_PRICH_01", 1352017873],
- ["MODEL_M_Y_PVILLBO_01", 223726252],
- ["MODEL_M_Y_PVILLBO_02", -1252681043],
- ["MODEL_M_Y_PVILLBO_03", -1562020391],
- ["MODEL_M_Y_QUEENSBRIDGE", 1223224881],
- ["MODEL_M_Y_SHADY_02", -1220737489],
- ["MODEL_M_Y_SKATEBIKE_01", 1755322862],
- ["MODEL_M_Y_SOHO_01", 386690478],
- ["MODEL_M_Y_STREET_01", 62496225],
- ["MODEL_M_Y_STREET_03", 523785438],
- ["MODEL_M_Y_STREET_04", 813889395],
- ["MODEL_M_Y_STREETBLK_02", -1552214124],
- ["MODEL_M_Y_STREETBLK_03", -650575089],
- ["Street Punk 1", -740078918],
- ["Street Punk 2", -1927496394],
- ["Street Punk 3", 1374242512],
- ["Tough Guy", -1139941790],
- ["Male Tourist", 809067472],
- ],
-};
-
-// ---------------------------------------------------------------------------
-
let policeStations = [
[],
[ // GTA III
@@ -2643,7 +317,7 @@ function closeAllGarages() {
// ---------------------------------------------------------------------------
-function replaceEmojiInString(message) {
+function replaceEmojiIntoString(message) {
for(let i in emojiReplaceString) {
message = message.replace(emojiReplaceString[i][0], emojiReplaceString[i][1]);
}
@@ -2653,27 +327,27 @@ function replaceEmojiInString(message) {
// ---------------------------------------------------------------------------
function makeReadableTime(hour, minute) {
- let hourStr = String(hour);
- let minuteStr = String(minute);
+ let hourStr = toString(hour);
+ let minuteStr = toString(minute);
let meridianStr = "AM";
if(hour < 10) {
- hourStr = "0" + String(hour);
+ hourStr = "0" + toString(hour);
meridianStr = "AM";
}
if(hour > 12) {
let actualHour = hour-12;
if(actualHour < 10) {
- hourStr = "0" + String(hour-12);
+ hourStr = "0" + toString(hour-12);
} else {
- hourStr = String(hour-12);
+ hourStr = toString(hour-12);
}
meridianStr = "PM";
}
if(minute < 10) {
- minuteStr = "0" + String(minute);
+ minuteStr = "0" + toString(minute);
}
return hourStr + ":" + minuteStr + " " + meridianStr;
@@ -2685,7 +359,7 @@ function getPosToRightOfPos(pos, angle, distance) {
let x = (pos.x+((Math.cos((-angle+1.57)+(Math.PI/2)))*distance));
let y = (pos.y+((Math.sin((-angle+1.57)+(Math.PI/2)))*distance));
- let rightPos = new Vec3(x, y, pos.z);
+ let rightPos = toVector3(x, y, pos.z);
return rightPos;
}
@@ -2696,7 +370,7 @@ function getPosToLeftOfPos(pos, angle, distance) {
let x = (pos.x+((Math.cos((angle+1.57)+(Math.PI/2)))*distance));
let y = (pos.y+((Math.sin((angle+1.57)+(Math.PI/2)))*distance));
- let leftPos = new Vec3(x, y, pos.z);
+ let leftPos = toVector3(x, y, pos.z);
return leftPos;
}
@@ -2708,7 +382,7 @@ function getPosInFrontOfPos(pos, angle, distance) {
let y = (pos.y+((Math.sin(angle+(Math.PI/2)))*distance));
let z = pos.z;
- return new Vec3(x, y, z);
+ return toVector3(x, y, z);
}
// ---------------------------------------------------------------------------
@@ -2718,7 +392,7 @@ function getPosBehindPos(pos, angle, distance) {
let y = (pos.y+((Math.sin(angle-(Math.PI/2)))*distance));
let z = pos.z;
- return new Vec3(x,y,z);
+ return toVector3(x,y,z);
}
// ---------------------------------------------------------------------------
@@ -2726,7 +400,7 @@ function getPosBehindPos(pos, angle, distance) {
function getPosAbovePos(pos, distance) {
let z = pos.z+distance;
- return new Vec3(pos.x, pos.y, z);
+ return toVector3(pos.x, pos.y, z);
}
// ---------------------------------------------------------------------------
@@ -2734,7 +408,7 @@ function getPosAbovePos(pos, distance) {
function getPosBelowPos(pos, distance) {
let z = pos.z-distance;
- return new Vec3(pos.x, pos.y, z);
+ return toVector3(pos.x, pos.y, z);
}
// ---------------------------------------------------------------------------
@@ -2782,7 +456,14 @@ function getAngleInCircleFromCenter(center, total, current) {
// ---------------------------------------------------------------------------
function getClosestVehicle(position) {
- return getElementsByType(ELEMENT_VEHICLE).reduce((i, j) => ((i.position.distance(position) <= j.position.distance(position)) ? i : j));
+ let vehicles = getServerData().vehicles;
+ let closest = 0;
+ for(let i in vehicles) {
+ if(vehicles[i].syncPosition.distance(position) < vehicles[closest].syncPosition.distance(position)) {
+ closest = i;
+ }
+ }
+ return vehicles[closest];
}
// ---------------------------------------------------------------------------
@@ -2793,8 +474,18 @@ function getClosestCivilian(position) {
// ---------------------------------------------------------------------------
-function getClosestClient(position) {
- return getClients().reduce((i, j) => ((i.player.position.distance(position) <= j.player.position.distance(position)) ? i : j));
+function getClosestPlayer(position) {
+ let clients = getClients();
+ let closest = 0;
+ for(let i in clients) {
+ if(clients[i].getData("ag.position") != null) {
+ if(clients[i].getData("ag.position").distance(position) < clients[closest].getData("ag.position").distance(position)) {
+ closest = i;
+ }
+ }
+
+ }
+ return clients[closest];
}
// ---------------------------------------------------------------------------
@@ -2805,28 +496,22 @@ function getClosestElementByType(elementType, position) {
// ---------------------------------------------------------------------------
-function getClosestJobPoint(position) {
- return serverData.jobs[getServerGame()].reduce((i, j) => ((i.position.distance(position) <= j.position.distance(position)) ? i : j));
-}
-
-// ---------------------------------------------------------------------------
-
-function getClosestJobLocationId(position) {
- let closestJob = 0;
- 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;
+function getClosestJobLocation(position) {
+ let closestJobLocation = false;
+ for(let i in getServerData().jobs) {
+ for(let j in getServerData().jobs[i].locations) {
+ if(!closestJobLocation || getServerData().jobs[i].locations[j].position.distance(position) < closestJobLocation.position.distance(position)) {
+ closestJobLocation = getServerData().jobs[i].locations[j];
}
}
}
- return closestJob;
+ return closestJobLocation;
}
// ---------------------------------------------------------------------------
function getJobIndex(jobData) {
- return serverData.jobs.indexOf(jobData);
+ return getServerData().jobs.indexOf(jobData);
}
// ---------------------------------------------------------------------------
@@ -2858,7 +543,7 @@ function getElementsByTypeInRange(elementType, position, distance) {
// ---------------------------------------------------------------------------
function getJobPointsInRange(position, distance) {
- return serverData.jobs[getServerGame()].filter(x => x.position.distance(position) <= distance);
+ return getServerData().jobs[getServerGame()].filter(x => x.position.distance(position) <= distance);
}
// ---------------------------------------------------------------------------
@@ -2870,13 +555,13 @@ function getWeaponName(weapon) {
// ---------------------------------------------------------------------------
function vec3ToVec2(pos) {
- return new Vec2(pos[0], pos[1]);
+ return toVector2(pos[0], pos[1]);
}
// ---------------------------------------------------------------------------
function vec3ToVec3(pos, z) {
- return new Vec3(pos[0], pos[1], z);
+ return toVector3(pos[0], pos[1], z);
}
// ---------------------------------------------------------------------------
@@ -2937,14 +622,14 @@ function getVehicleModelIdFromParams(params) {
return false;
}
- if(isValidVehicleModel(Number(modelId))) {
- return Number(modelId);
+ if(isValidVehicleModel(toInteger(modelId))) {
+ return toInteger(modelId);
}
return false;
} else {
- if(isValidVehicleModel(Number(params))) {
- return Number(params);
+ if(isValidVehicleModel(toInteger(params))) {
+ return toInteger(params);
}
return false;
@@ -2956,19 +641,28 @@ function getVehicleModelIdFromParams(params) {
// ---------------------------------------------------------------------------
function getVehicleModelIdFromName(params) {
- for(let i in gameData.vehicleNames[getServerGame()]) {
- if(gameData.vehicleNames[getServerGame()][i].toLowerCase().indexOf(params.toLowerCase()) != -1) {
- return Number(i)+Number(gameData.vehicleModelIdStart[getServerGame()]);
- }
- }
-
+ if(isGTAIV()) {
+ for(let i in getGameData().gtaivVehicleModels) {
+ if(toLowerCase(getGameData().gtaivVehicleModels[i][0]).indexOf(toLowerCase(params)) != -1) {
+ return getGameData().gtaivVehicleModels[i][1];
+ }
+ }
+ } else {
+ let vehicleNames = getGameData().vehicleNames[getServerGame()];
+ for(let i in vehicleNames) {
+ if(toLowerCase(vehicleNames[i]).indexOf(toLowerCase(params)) != -1) {
+ return toInteger(i)+toInteger(getGameData().vehicleModelIdStart[getServerGame()]);
+ }
+ }
+ }
+
return false;
}
// ---------------------------------------------------------------------------
function doesWordStartWithVowel(word) {
- switch(word.substr(0,1).toLowerCase()) {
+ switch(toLowerCase(word.substr(0,1))) {
case "a":
case "e":
case "i":
@@ -2986,13 +680,22 @@ function doesWordStartWithVowel(word) {
// ---------------------------------------------------------------------------
function getVehicleNameFromModelId(modelId) {
- let modelIndex = modelId-gameData.vehicleModelIdStart[getServerGame()];
- return gameData.vehicleNames[getServerGame()][modelIndex];
+ console.log(modelId);
+ if(isGTAIV()) {
+ for(let i in getGameData().gtaivVehicleModels) {
+ if(getGameData().gtaivVehicleModels[i][1] == modelId) {
+ return getGameData().gtaivVehicleModels[i][0];
+ }
+ }
+ } else {
+ let modelIndex = modelId-getGameData().vehicleModelIdStart[getServerGame()];
+ return getGameData().vehicleNames[getServerGame()][modelIndex];
+ }
}
// ---------------------------------------------------------------------------
-function replaceEmojiInString(message) {
+function replaceEmojiIntoString(message) {
for(let i in emojiReplaceString) {
while(message.indexOf(emojiReplaceString[i][0]) != -1) {
message = message.replace(emojiReplaceString[i][0], emojiReplaceString[i][1]);
@@ -3013,7 +716,7 @@ function getSyncerFromId(syncerId) {
function getClientFromName(clientName) {
let clients = getClients();
for(let i in clients) {
- if(clients[i].name.toLowerCase().indexOf(clientName.toLowerCase()) != -1) {
+ if(toLowerCase(clients[i].name).indexOf(toLowerCase(clientName)) != -1) {
return clients[i];
}
}
@@ -3040,12 +743,12 @@ function getPlayerFromParams(params, isServer) {
let clients = getClients();
if(isNaN(params)) {
for(let i in clients) {
- if(clients[i].name.toLowerCase().indexOf(params.toLowerCase()) != -1) {
+ if(toLowerCase(clients[i].name).indexOf(toLowerCase(params)) != -1) {
return clients[i].player;
}
}
} else {
- let playerId = Number(params) || 0;
+ let playerId = toInteger(params) || 0;
if(typeof clients[playerId] != "undefined") {
return clients[playerId].player;
}
@@ -3058,24 +761,18 @@ function getPlayerFromParams(params, isServer) {
// ---------------------------------------------------------------------------
function getClientFromParams(checkParams) {
- console.log(checkParams);
let clients = getClients();
if(isNaN(checkParams)) {
- console.log(`Checking string name`);
- checkParams = checkParams.toLowerCase();
+ checkParams = toLowerCase(checkParams);
for(let i in clients) {
- let clientName = clients[i].name.toLowerCase();
- console.log(`Checking ${clientName}`);
+ let clientName = toLowerCase(clients[i].name);
if(clientName.indexOf(checkParams) != -1) {
- console.log(`Found ${clients[i].name}`);
return clients[i];
}
}
} else {
- console.log(`Checking int ID`);
- let clientId = Number(checkParams) || 0;
+ let clientId = toInteger(checkParams) || 0;
if(typeof clients[clientId] != "undefined") {
- console.log(`Found ${clients[i].name}`);
return clients[clientId];
}
}
@@ -3118,7 +815,7 @@ function packData(...args) {
// ---------------------------------------------------------------------------
function combine(a, b, c) {
- return Number((a << 20) | (b << 10) | c);
+ return toInteger((a << 20) | (b << 10) | c);
}
// ---------------------------------------------------------------------------
@@ -3226,13 +923,13 @@ function getTimeDifferenceDisplay(unixTimeOne, unixTimeTwo) {
if(hours == 1) {
hourString = "1 hour";
} else {
- hourString = String(hours) + " hours";
+ hourString = toString(hours) + " hours";
}
if(minutes == 1) {
minuteString = "1 minute";
} else {
- minuteString = String(minutes) + " minute";
+ minuteString = toString(minutes) + " minute";
}
return hourString + " and " + minuteString;
@@ -3447,8 +1144,7 @@ function getGameAreas(gameId) {
// ---------------------------------------------------------------------------
function getClientData(client) {
- console.log(serverData.clients[client.index]);
- return serverData.clients[client.index];
+ return getServerData().clients[client.index];
}
// ---------------------------------------------------------------------------
@@ -3479,9 +1175,9 @@ function createAllLocationBlips() {
// ---------------------------------------------------------------------------
function createAllPoliceStationBlips() {
- if(serverConfig.blipSprites[getServerGame()].policeStation != -1) {
- for(let i in serverData.policeStations[getServerGame()]) {
- serverData.policeStations[getServerGame()][i].blip = createBlip(serverConfig.blipSprites[getServerGame()].policeStation, serverData.policeStations[getServerGame()][i].position);
+ if(getServerConfig().blipSprites[getServerGame()].policeStation != -1) {
+ for(let i in getServerData().policeStations[getServerGame()]) {
+ getServerData().policeStations[getServerGame()][i].blip = createBlip(getServerConfig().blipSprites[getServerGame()].policeStation, getServerData().policeStations[getServerGame()][i].position);
}
}
}
@@ -3489,9 +1185,9 @@ function createAllPoliceStationBlips() {
// ---------------------------------------------------------------------------
function createAllFireStationBlips() {
- if(serverConfig.blipSprites[getServerGame()].fireStation != -1) {
- for(let i in serverData.fireStations[getServerGame()]) {
- serverData.fireStations[getServerGame()][i].blip = createBlip(serverConfig.blipSprites[getServerGame()].fireStation, serverData.fireStations[getServerGame()][i].position);
+ if(getServerConfig().blipSprites[getServerGame()].fireStation != -1) {
+ for(let i in getServerData().fireStations[getServerGame()]) {
+ getServerData().fireStations[getServerGame()][i].blip = createBlip(getServerConfig().blipSprites[getServerGame()].fireStation, getServerData().fireStations[getServerGame()][i].position);
}
}
}
@@ -3499,9 +1195,9 @@ function createAllFireStationBlips() {
// ---------------------------------------------------------------------------
function createAllHospitalBlips() {
- if(serverConfig.blipSprites[getServerGame()].hospital != -1) {
- for(let i in serverData.hospitals[getServerGame()]) {
- serverData.hospitals[getServerGame()][i].blip = createBlip(serverConfig.blipSprites[getServerGame()].hospital, serverData.hospitals[getServerGame()][i].position);
+ if(getServerConfig().blipSprites[getServerGame()].hospital != -1) {
+ for(let i in getServerData().hospitals[getServerGame()]) {
+ getServerData().hospitals[getServerGame()][i].blip = createBlip(getServerConfig().blipSprites[getServerGame()].hospital, getServerData().hospitals[getServerGame()][i].position);
}
}
}
@@ -3509,9 +1205,9 @@ function createAllHospitalBlips() {
// ---------------------------------------------------------------------------
function createAllAmmunationBlips() {
- if(serverConfig.blipSprites[getServerGame()].ammunation != -1) {
- for(let i in serverData.ammunations[getServerGame()]) {
- serverData.ammunations[getServerGame()][i].blip = createBlip(serverConfig.blipSprites[getServerGame()].ammunation, serverData.ammunations[getServerGame()][i].position);
+ if(getServerConfig().blipSprites[getServerGame()].ammunation != -1) {
+ for(let i in getServerData().ammunations[getServerGame()]) {
+ getServerData().ammunations[getServerGame()][i].blip = createBlip(getServerConfig().blipSprites[getServerGame()].ammunation, getServerData().ammunations[getServerGame()][i].position);
}
}
}
@@ -3519,10 +1215,9 @@ function createAllAmmunationBlips() {
// ---------------------------------------------------------------------------
function createAllPayAndSprayBlips() {
- if(serverConfig.blipSprites[getServerGame()].payAndSpray != -1) {
- for(let i in serverData.payAndSprays[getServerGame()]) {
-
- serverData.payAndSprays[getServerGame()][i].blip = createBlip(serverConfig.blipSprites[getServerGame()].payAndSpray, serverData.payAndSprays[getServerGame()][i].position);
+ if(getServerConfig().blipSprites[getServerGame()].payAndSpray != -1) {
+ for(let i in getServerData().payAndSprays[getServerGame()]) {
+ getServerData().payAndSprays[getServerGame()][i].blip = createBlip(getServerConfig().blipSprites[getServerGame()].payAndSpray, getServerData().payAndSprays[getServerGame()][i].position);
}
}
}
@@ -3530,9 +1225,9 @@ function createAllPayAndSprayBlips() {
// ---------------------------------------------------------------------------
function createAllFuelStationBlips() {
- if(serverConfig.blipSprites[getServerGame()].fuelStation != -1) {
- for(let i in serverData.fuelStations[getServerGame()]) {
- serverData.fuelStations[getServerGame()][i].blip = createBlip(serverConfig.blipSprites[getServerGame()].fuelStation, serverData.fuelStations[getServerGame()][i].position, 2, serverConfig.colour.byName.burntOrange);
+ if(getServerConfig().blipSprites[getServerGame()].fuelStation != -1) {
+ for(let i in getServerData().fuelStations[getServerGame()]) {
+ getServerData().fuelStations[getServerGame()][i].blip = createBlip(getServerConfig().blipSprites[getServerGame()].fuelStation, getServerData().fuelStations[getServerGame()][i].position, 2, getColourByName("burntOrange"));
}
}
}
@@ -3540,16 +1235,16 @@ function createAllFuelStationBlips() {
// ---------------------------------------------------------------------------
function sendAllPoliceStationBlips(client) {
- if(serverConfig.blipSprites[getServerGame()].policeStation != -1) {
+ if(getServerConfig().blipSprites[getServerGame()].policeStation != -1) {
let tempBlips = [];
- for(let i in serverData.policeStations[getServerGame()]) {
+ for(let i in getServerData().policeStations[getServerGame()]) {
tempBlips.push([
- serverConfig.blipSprites[getServerGame()].policeStation,
- serverData.policeStations[getServerGame()][i].position.x,
- serverData.policeStations[getServerGame()][i].position.y,
- serverData.policeStations[getServerGame()][i].position.z,
+ getServerConfig().blipSprites[getServerGame()].policeStation,
+ getServerData().policeStations[getServerGame()][i].position.x,
+ getServerData().policeStations[getServerGame()][i].position.y,
+ getServerData().policeStations[getServerGame()][i].position.z,
3,
- serverConfig.colour.byName.policeBlue,
+ getColourByName("policeBlue"),
]);
}
triggerNetworkEvent("ag.blips", client, tempBlips);
@@ -3559,16 +1254,16 @@ function sendAllPoliceStationBlips(client) {
// ---------------------------------------------------------------------------
function sendAllFireStationBlips(client) {
- if(serverConfig.blipSprites[getServerGame()].fireStation != -1) {
+ if(getServerConfig().blipSprites[getServerGame()].fireStation != -1) {
let tempBlips = [];
- for(let i in serverData.fireStations[getServerGame()]) {
+ for(let i in getServerData().fireStations[getServerGame()]) {
tempBlips.push([
- serverConfig.blipSprites[getServerGame()].fireStation,
- serverData.fireStations[getServerGame()][i].position.x,
- serverData.fireStations[getServerGame()][i].position.y,
- serverData.fireStations[getServerGame()][i].position.z,
+ getServerConfig().blipSprites[getServerGame()].fireStation,
+ getServerData().fireStations[getServerGame()][i].position.x,
+ getServerData().fireStations[getServerGame()][i].position.y,
+ getServerData().fireStations[getServerGame()][i].position.z,
3,
- serverConfig.colour.byName.firefighterRed,
+ getColourByName("firefighterRed"),
]);
}
triggerNetworkEvent("ag.blips", client, tempBlips);
@@ -3578,16 +1273,16 @@ function sendAllFireStationBlips(client) {
// ---------------------------------------------------------------------------
function sendAllHospitalBlips(client) {
- if(serverConfig.blipSprites[getServerGame()].hospital != -1) {
+ if(getServerConfig().blipSprites[getServerGame()].hospital != -1) {
let tempBlips = [];
- for(let i in serverData.hospitals[getServerGame()]) {
+ for(let i in getServerData().hospitals[getServerGame()]) {
tempBlips.push([
- serverConfig.blipSprites[getServerGame()].hospital,
- serverData.hospitals[getServerGame()][i].position.x,
- serverData.hospitals[getServerGame()][i].position.y,
- serverData.hospitals[getServerGame()][i].position.z,
+ getServerConfig().blipSprites[getServerGame()].hospital,
+ getServerData().hospitals[getServerGame()][i].position.x,
+ getServerData().hospitals[getServerGame()][i].position.y,
+ getServerData().hospitals[getServerGame()][i].position.z,
3,
- serverConfig.colour.byName.medicPink,
+ getColourByName("medicPink"),
]);
}
triggerNetworkEvent("ag.blips", client, tempBlips);
@@ -3597,14 +1292,14 @@ function sendAllHospitalBlips(client) {
// ---------------------------------------------------------------------------
function sendAllAmmunationBlips(client) {
- if(serverConfig.blipSprites[getServerGame()].ammunation != -1) {
+ if(getServerConfig().blipSprites[getServerGame()].ammunation != -1) {
let tempBlips = [];
- for(let i in serverData.ammunations[getServerGame()]) {
+ for(let i in getServerData().ammunations[getServerGame()]) {
tempBlips.push([
- serverConfig.blipSprites[getServerGame()].ammunation,
- serverData.ammunations[getServerGame()][i].position.x,
- serverData.ammunations[getServerGame()][i].position.y,
- serverData.ammunations[getServerGame()][i].position.z,
+ getServerConfig().blipSprites[getServerGame()].ammunation,
+ getServerData().ammunations[getServerGame()][i].position.x,
+ getServerData().ammunations[getServerGame()][i].position.y,
+ getServerData().ammunations[getServerGame()][i].position.z,
3,
0
]);
@@ -3616,14 +1311,14 @@ function sendAllAmmunationBlips(client) {
// ---------------------------------------------------------------------------
function sendAllPayAndSprayBlips(client) {
- if(serverConfig.blipSprites[getServerGame()].payAndSpray != -1) {
+ if(getServerConfig().blipSprites[getServerGame()].payAndSpray != -1) {
let tempBlips = [];
- for(let i in serverData.payAndSprays[getServerGame()]) {
+ for(let i in getServerData().payAndSprays[getServerGame()]) {
tempBlips.push([
- serverConfig.blipSprites[getServerGame()].payAndSpray,
- serverData.payAndSprays[getServerGame()][i].position.x,
- serverData.payAndSprays[getServerGame()][i].position.y,
- serverData.payAndSprays[getServerGame()][i].position.z,
+ getServerConfig().blipSprites[getServerGame()].payAndSpray,
+ getServerData().payAndSprays[getServerGame()][i].position.x,
+ getServerData().payAndSprays[getServerGame()][i].position.y,
+ getServerData().payAndSprays[getServerGame()][i].position.z,
3,
0
]);
@@ -3635,16 +1330,16 @@ function sendAllPayAndSprayBlips(client) {
// ---------------------------------------------------------------------------
function sendAllFuelStationBlips(client) {
- if(serverConfig.blipSprites[getServerGame()].fuelStation != -1) {
+ if(getServerConfig().blipSprites[getServerGame()].fuelStation != -1) {
let tempBlips = [];
- for(let i in serverData.fuelStations[getServerGame()]) {
+ for(let i in getServerData().fuelStations[getServerGame()]) {
tempBlips.push([
- serverConfig.blipSprites[getServerGame()].fuelStation,
- serverData.fuelStations[getServerGame()][i].position.x,
- serverData.fuelStations[getServerGame()][i].position.y,
- serverData.fuelStations[getServerGame()][i].position.z,
+ getServerConfig().blipSprites[getServerGame()].fuelStation,
+ getServerData().fuelStations[getServerGame()][i].position.x,
+ getServerData().fuelStations[getServerGame()][i].position.y,
+ getServerData().fuelStations[getServerGame()][i].position.z,
3,
- serverConfig.colour.byName.burntOrange,
+ getColourByName("burntOrange"),
]);
}
triggerNetworkEvent("ag.blips", client, tempBlips);
@@ -3666,7 +1361,7 @@ function getPickupOwnerId(pickup) {
// ---------------------------------------------------------------------------
function canClientUseJobs(client) {
- if(getClientData(client).accountData.flags.moderation & serverData.moderationFlags.jobBanned) {
+ if(getClientData(client).accountData.flags.moderation & getServerData().moderationFlags.jobBanned) {
return false;
}
@@ -3676,7 +1371,7 @@ function canClientUseJobs(client) {
// ---------------------------------------------------------------------------
function canClientUsePoliceJob(client) {
- if(getClientData(client).accountData.flags.moderation & serverData.moderationFlags.policeBanned) {
+ if(getClientData(client).accountData.flags.moderation & getServerData().moderationFlags.policeBanned) {
return false;
}
@@ -3686,7 +1381,7 @@ function canClientUsePoliceJob(client) {
// ---------------------------------------------------------------------------
function canClientUseFireJob(client) {
- if(getClientData(client).accountData.flags.moderation & serverData.moderationFlags.fireBanned) {
+ if(getClientData(client).accountData.flags.moderation & getServerData().moderationFlags.fireBanned) {
return false;
}
@@ -3696,7 +1391,7 @@ function canClientUseFireJob(client) {
// ---------------------------------------------------------------------------
function canClientUseAmmunations(client) {
- if(getClientData(client).accountData.flags.moderation & serverData.moderationFlags.ammuBanned) {
+ if(getClientData(client).accountData.flags.moderation & getServerData().moderationFlags.ammuBanned) {
return false;
}
@@ -3706,17 +1401,13 @@ function canClientUseAmmunations(client) {
// ---------------------------------------------------------------------------
function canClientUseGuns(client) {
- if(getClientData(client).accountData.flags.moderation & serverData.moderationFlags.gunBanned) {
+ if(getClientData(client).accountData.flags.moderation & getServerData().moderationFlags.gunBanned) {
return false;
}
return true;
}
-// ---------------------------------------------------------------------------
-
-
-
// ---------------------------------------------------------------------------
function intToBool(intVal) {
@@ -3752,15 +1443,15 @@ function processHoldActionKey(client) {
if(getClientCurrentSubAccount(client).job == AG_JOB_NONE) {
- if(jobData.position.distance(client.player.position) <= serverConfig.takeJobDistance) {
+ if(jobData.position.distance(client.player.position) <= getServerConfig().takeJobDistance) {
takeJob(client, closestJobId);
- messageClientSuccess(client, "You now have the " + String(jobData.name) + " job");
+ messageClientSuccess(client, "You now have the " + toString(jobData.name) + " job");
}
} else {
if(jobData.jobType == getClientCurrentSubAccount(client).job) {
- if(jobData.position.distance(client.player.position) <= serverConfig.startWorkDistance) {
+ if(jobData.position.distance(client.player.position) <= getServerConfig().startWorkDistance) {
startWorking(client);
- messageClientSuccess(client, "You are now working as a " + String(jobData.name));
+ messageClientSuccess(client, "You are now working as a " + toString(jobData.name));
showStartedWorkingTip(client);
return true;
}
@@ -3778,7 +1469,7 @@ function processPressActionKey(client) {
let closestJob = getClosestJob(client.player.position);
if(getClientCurrentSubAccount(client).job == AG_JOB_NONE) {
- if(closestJob.position.distance(client.player.position) <= serverConfig.takeJobDistance) {
+ if(closestJob.position.distance(client.player.position) <= getServerConfig().takeJobDistance) {
}
}
@@ -3817,7 +1508,7 @@ function getClientChatColour(client) {
// ---------------------------------------------------------------------------
function showConnectCameraToPlayer(client) {
- triggerNetworkEvent("ag.connectCamera", client, serverConfig.connectCameraPosition, serverConfig.connectCameraLookAt);
+ triggerNetworkEvent("ag.connectCamera", client, getServerConfig().connectCameraPosition, getServerConfig().connectCameraLookAt);
//triggerNetworkEvent("ag.showCharacterSelect", client, tempSubAccount.firstName, tempSubAccount.lastName, tempSubAccount.placeOfOrigin, tempSubAccount.dateOfBirth, tempSubAccount.skin);
}
@@ -3850,23 +1541,23 @@ function getEnabledDisabledFromBool(boolVal) {
// ---------------------------------------------------------------------------
function updateServerRules() {
- server.setRule("Time", makeReadableTime(serverConfig.hour, serverConfig.minute));
- server.setRule("Weather", gameData.weatherNames[server.game][serverConfig.weather]);
- server.setRule("Snowing", getYesNoFromBool(serverConfig.fallingSnow));
+ server.setRule("Time", makeReadableTime(getServerConfig().hour, getServerConfig().minute));
+ server.setRule("Weather", getGameData().weatherNames[getServerGame()][getServerConfig().weather]);
+ server.setRule("Snowing", getYesNoFromBool(getServerConfig().fallingSnow));
}
// ---------------------------------------------------------------------------
function getWeatherFromParams(params) {
if(isNaN(params)) {
- for(let i in weatherNames[server.game]) {
- if(weatherNames[server.game][i].toLowerCase().indexOf(params.toLowerCase()) != -1) {
+ for(let i in getGameData().weatherNames[getServerGame()]) {
+ if(toLowerCase(weatherNames[getServerGame()][i]).indexOf(toLowerCase(params)) != -1) {
return i;
}
}
return false;
} else {
- if(typeof weatherNames[server.game][i] != "undefined") {
+ if(typeof getGameData().weatherNames[getServerGame()][i] != "undefined") {
return i;
}
return false;
@@ -3891,13 +1582,13 @@ function clearChatBox(client) {
// ---------------------------------------------------------------------------
-function getSkinIdFromParams(params, gameId = server.game) {
+function getSkinIdFromParams(params, gameId = getServerGame()) {
if(isNaN(params)) {
return getSkinIdFromName(params, gameId);
} else {
- params = Number(params);
+ params = toInteger(params);
if(gameId == GAME_GTA_IV || gameId == GAME_GTA_IV_EFLC) {
- return gameData.gtaivSkinModels[params][1];
+ return getGameData().gtaivSkinModels[params][1];
} else {
return params;
}
@@ -3908,31 +1599,31 @@ function getSkinIdFromParams(params, gameId = server.game) {
// ---------------------------------------------------------------------------
-function getSkinNameFromId(modelId, gameId = server.game) {
+function getSkinNameFromId(modelId, gameId = getServerGame()) {
if(gameId >= GAME_GTA_IV) {
- for(let i in gameData.gtaivSkinModels) {
- if(gameData.gtaivSkinModels[i][1] == modelId) {
- return gameData.gtaivSkinModels[i][0];
+ for(let i in getGameData().gtaivSkinModels) {
+ if(getGameData().gtaivSkinModels[i][1] == modelId) {
+ return getGameData().gtaivSkinModels[i][0];
}
}
} else {
let modelIndex = modelId;
- return gameData.skinNames[gameId][modelIndex];
+ return getGameData().skinNames[gameId][modelIndex];
}
}
// ---------------------------------------------------------------------------
-function getSkinIdFromName(params, gameId = server.game) {
+function getSkinIdFromName(params, gameId = getServerGame()) {
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
+ if(toLowerCase(getGameData().gtaivSkinModels[i][0]).indexOf(toLowerCase(params)) != -1) {
+ return getGameData().gtaivSkinModels[i][1];
}
}
} else {
- for(let i in gameData.skinNames[gameId]) {
- if(gameData.skinNames[gameId][i].toLowerCase().indexOf(params.toLowerCase()) != -1) {
+ for(let i in getGameData().skinNames[gameId]) {
+ if(toLowerCase(getGameData().skinNames[gameId][i]).indexOf(toLowerCase(params)) != -1) {
return i;
}
}
@@ -3941,4 +1632,87 @@ function getSkinIdFromName(params, gameId = server.game) {
return false;
}
-// ---------------------------------------------------------------------------
\ No newline at end of file
+// ---------------------------------------------------------------------------
+
+function getClosestHospital(position) {
+ let closest = 0;
+ for(let i in getServerData().hospitals[getServerGame()]) {
+ if(getServerData().hospitals[getServerGame()][i].position.distance(position) < getServerData().hospitals[getServerGame()][closest].position) {
+ closest = i;
+ }
+ }
+
+ return getServerData().hospitals[getServerGame()][closest];
+}
+
+// ---------------------------------------------------------------------------
+
+function getClosestPoliceStation(position) {
+ let closest = 0;
+ for(let i in getServerData().policeStations[getServerGame()]) {
+ if(getServerData().policeStations[getServerGame()][i].position.distance(position) < getServerData().policeStations[getServerGame()][closest].position) {
+ closest = i;
+ }
+ }
+
+ return getServerData().policeStations[getServerGame()][closest];
+}
+
+// ----------------------------------------------------------------------------
+
+function processPlayerDeath(client) {
+ client.removeData("ag.spawned", true);
+
+ if(isGTAIV()) {
+ triggerNetworkEvent("ag.iv.syncPosition", client, false);
+ }
+
+ let closestHospital = getClosestHospital(getPlayerPosition(client));
+ triggerNetworkEvent("ag.control", client, false);
+ setTimeout(function() {
+ triggerNetworkEvent("ag.fadeCamera", client, false, 1.0);
+ setTimeout(function() {
+ if(!isGTAIV()) {
+ client.despawnPlayer();
+ }
+ if(getClientCurrentSubAccount(client).inJail) {
+ let closestJail = getClosestJail(getPlayerPosition(client));
+ spawnPlayer(client, closestJail.position, closestJail.heading, getClientCurrentSubAccount(client).skin);
+ } else {
+ spawnPlayer(client, closestHospital.position, closestHospital.heading, getClientCurrentSubAccount(client).skin);
+ }
+ client.getData("ag.spawned", true, true);
+ setTimeout(function() {
+ triggerNetworkEvent("ag.fadeCamera", client, true, 1.0);
+ triggerNetworkEvent("ag.control", client, true);
+ if(isGTAIV()) {
+ triggerNetworkEvent("ag.iv.syncPosition", client, true);
+ }
+ }, 1000);
+ }, 2000);
+ }, 1000);
+}
+
+// ----------------------------------------------------------------------------
+
+function isPlayerInAnyVehicle(client) {
+ if(client.player.vehicle) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+function isGTAIV() {
+ return (getServerGame() == GAME_GTA_IV);
+}
+
+// ----------------------------------------------------------------------------
+
+function arrayBufferToString(arrayBuffer) {
+ return String.fromCharCode.apply(null, new Uint8Array(arrayBuffer));
+}
+
+// ----------------------------------------------------------------------------
\ No newline at end of file
diff --git a/scripts/server/vehicle.js b/scripts/server/vehicle.js
index 1da6eaae..dae92af0 100644
--- a/scripts/server/vehicle.js
+++ b/scripts/server/vehicle.js
@@ -11,7 +11,7 @@
function initVehicleScript() {
console.log("[Asshat.Vehicle]: Initializing vehicle script ...");
- serverData.vehicles = loadVehiclesFromDatabase();
+ getServerData().vehicles = loadVehiclesFromDatabase();
spawnAllVehicles();
addVehicleCommandHandlers();
console.log("[Asshat.Vehicle]: Vehicle script initialized successfully!");
@@ -58,7 +58,7 @@ function loadVehiclesFromDatabase() {
function saveAllVehiclesToDatabase() {
console.log("[Asshat.Vehicle]: Saving all vehicles to database ...");
- let vehicles = serverData.vehicles;
+ let vehicles = getServerData().vehicles;
for(let i in vehicles) {
saveVehicleToDatabase(vehicles[i]);
}
@@ -70,17 +70,22 @@ function saveAllVehiclesToDatabase() {
// ---------------------------------------------------------------------------
function saveVehicleToDatabase(vehicleData) {
- console.log(`[Asshat.Vehicle]: Saving vehicles ${vehicleData.vehicle.id} to database ...`);
+ console.log(`[Asshat.Vehicle]: Saving vehicle ${vehicleData.vehicle.id} to database ...`);
let dbConnection = connectToDatabase();
if(dbConnection) {
if(!vehicleData.spawnLocked) {
- vehicleData.spawnPosition = vehicle.position;
- vehicleData.spawnRotation = vehicle.heading;
+ if(!isGTAIV()) {
+ vehicleData.spawnPosition = vehicleData.vehicle.position;
+ vehicleData.spawnRotation = vehicleData.vehicle.heading;
+ } else {
+ vehicleData.spawnPosition = vehicleData.syncPosition;
+ vehicleData.spawnRotation = vehicleData.syncHeading;
+ }
}
// 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})`;
+ 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, veh_spawn_lock, veh_buy_price, veh_rent_price) 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}, ${boolToInt(vehicleData.spawnLocked)}, ${vehicleData.buyPrice}, ${vehicleData.rentPrice})`;
queryDatabase(dbConnection, dbQueryString);
getVehicleData(vehicleData.vehicle).databaseId = getDatabaseInsertId(dbConnection);
} else {
@@ -98,37 +103,19 @@ function saveVehicleToDatabase(vehicleData) {
// ---------------------------------------------------------------------------
function spawnAllVehicles() {
- //if(gta.game == GAME_GTA_IV) {
- // return false;
- //}
-
- for(let i in serverData.vehicles) {
- let vehicle = gta.createVehicle(serverData.vehicles[i].model, serverData.vehicles[i].spawnPosition, serverData.vehicles[i].spawnRotation);
- addToWorld(vehicle);
-
- if(serverData.vehicles[i].colour1IsRGBA && serverData.vehicles[i].colour2IsRGBA) {
- vehicle.setRGBColours(serverData.vehicles[i].colour1RGBA, serverData.vehicles[i].colour2RGBA);
+ let vehicles = getServerData().vehicles;
+ for(let i in vehicles) {
+ if(isGTAIV()) {
+ if(!vehicles[i].syncedBy) {
+ let closestClient = getClosestPlayer(vehicles[i].spawnPosition);
+ triggerNetworkEvent("ag.vehicle", closestClient, i, vehicles[i].modelIndex, vehicles[i].spawnPosition, vehicles[i].spawnRotation, vehicles[i].colour1, vehicles[i].colour2, vehicles[i].locked, vehicles[i].lights);
+ vehicles[i].syncedBy = closestClient;
+ }
} else {
- vehicle.colour1 = serverData.vehicles[i].colour1;
- vehicle.colour2 = serverData.vehicles[i].colour2;
- vehicle.colour3 = serverData.vehicles[i].colour3;
- vehicle.colour4 = serverData.vehicles[i].colour4;
+ let vehicle = spawnVehicle(vehicles[i]);
+ vehicles[i].vehicle = vehicle;
+ vehicle.setData("ag.dataSlot", i, false);
}
-
- vehicle.engine = intToBool(serverData.vehicles[i].engine);
- //vehicle.lights = intToBool(serverData.vehicles[i].lights);
- //vehicle.health = serverData.vehicles[i].health;
-
- //vehicle.position = serverData.vehicles[i].spawnPosition;
- vehicle.heading = serverData.vehicles[i].spawnRotation;
-
- vehicle.locked = intToBool(serverData.vehicles[i].locked);
- vehicle.setData("ag.siren", intToBool(serverData.vehicles[i].siren), true);
- vehicle.setData("ag.engine", intToBool(serverData.vehicles[i].engine), true);
- vehicle.setData("ag.lights", intToBool(serverData.vehicles[i].lights), true);
-
- serverData.vehicles[i].vehicle = vehicle;
- vehicle.setData("ag.dataSlot", i, false);
}
}
@@ -136,8 +123,8 @@ function spawnAllVehicles() {
function getVehicleData(vehicle) {
let dataIndex = vehicle.getData("ag.dataSlot");
- if(typeof serverData.vehicles[dataIndex] != "undefined") {
- return serverData.vehicles[dataIndex];
+ if(typeof getServerData().vehicles[dataIndex] != "undefined") {
+ return getServerData().vehicles[dataIndex];
}
return false;
}
@@ -156,7 +143,7 @@ function createVehicleCommand(command, params, client) {
if(!isCommandAllowedOnDiscord(command)) {
messageClientError(client, "That command isn't available on discord!");
return false;
- }
+ }
}
if(!doesClientHaveStaffPermission(client, getCommandRequiredPermissions(command))) {
@@ -171,16 +158,22 @@ function createVehicleCommand(command, params, client) {
return false;
}
- let frontPos = getPosInFrontOfPos(client.player.position, client.player.heading, serverConfig.spawnCarDistance);
+ let tempVehicleData = new serverClasses.vehicleData(false, false);
+ let frontPos = getPosInFrontOfPos(getPlayerPosition(client), getPlayerHeading(client), getServerConfig().spawnCarDistance);
+ getServerData().vehicles.push(tempVehicleData);
+ let vehicleDataSlot = getServerData().vehicles.length-1;
+ getServerData().vehicles[vehicleDataSlot].syncId = vehicleDataSlot;
+
+ if(isGTAIV()) {
+ triggerNetworkEvent("ag.vehicle", getClosestPlayer(frontPos), vehicleDataSlot, modelId, frontPos, getPlayerHeading(client), 133, 133, 0, false);
+ } else {
+ let vehicle = spawnVehicle(tempVehicleData);
+ tempVehicleData.vehicle = vehicle;
+ vehicle.heading = getPlayerHeading(client);
+ vehicle.setData("ag.dataSlot", vehicleDataSlot, false);
+ }
- let vehicle = gta.createVehicle(modelId, frontPos, client.player.heading);
- vehicle.heading = client.player.heading;
-
- let tempVehicleData = new serverClasses.vehicleData(false, vehicle);
- let vehiclesLength = serverData.vehicles.push(tempVehicleData);
- vehicle.setData("ag.dataSlot", vehiclesLength-1, false);
-
- messageClientSuccess(client, `You created a ${getVehicleName(vehicle)}!`);
+ messageClientSuccess(client, `You created a ${getVehicleName(tempVehicleData.model)}!`);
}
// ---------------------------------------------------------------------------
@@ -205,32 +198,32 @@ function vehicleLockCommand(command, params, client) {
return false;
}
- let vehicle = getClosestVehicle(client.player.position);
- if(!client.player.vehicle && vehicle.position.distance(client.player.position) > serverConfig.vehicleLockDistance) {
+ let vehicleData = getClosestVehicle(getPlayerPosition(client));
+ if(!getPlayerVehicle(client) && getVehiclePosition(vehicleData).distance(getPlayerPosition(client)) > getServerConfig().vehicleLockDistance) {
messageClientError(client, "You need to be in or near a vehicle!");
return false;
}
- if(client.player.vehicle) {
- vehicle = client.player.vehicle;
+ if(getPlayerVehicle(client)) {
+ vehicleData = getPlayerVehicle(client);
} else {
- if(!doesClientHaveVehicleKeys(client, vehicle)) {
+ if(!doesClientHaveVehicleKeys(client, vehicleData)) {
messageClientError(client, "You don't have keys to this vehicle!");
return false;
}
}
- if(getVehicleData(vehicle).locked) {
+ if(vehicleData.locked) {
vehicle.locked = false;
- getVehicleData(vehicle).locked = false;
+ vehicleData.locked = false;
} else {
vehicle.locked = true;
- getVehicleData(vehicle).locked = true;
+ vehicleData.locked = true;
}
- let lockText = (vehicle.locked) ? "locked" : "unlocked";
+ let lockText = (vehicleData.locked) ? "locked" : "unlocked";
- meActionToNearbyPlayers(client, lockText + " the " + getVehicleName(vehicle));
+ meActionToNearbyPlayers(client, lockText + " the " + getVehicleName(vehicleData.modelIndex));
}
// ---------------------------------------------------------------------------
@@ -255,30 +248,23 @@ function vehicleLightsCommand(command, params, client) {
return false;
}
- if(!client.player.vehicle) {
+ if(!getPlayerVehicle(client)) {
messageClientError(client, "You need to be in a vehicle!");
return false;
}
- if(client.player.getData("ag.vehSeat") > 1) {
+ let vehicleData = getPlayerVehicle(client);
+
+ if(getPlayerVehicleSeat(client) > 1) {
messageClientError(client, "You need to be in the front seat!");
return false;
}
- let vehicle = client.player.vehicle;
+ triggerNetworkEvent("ag.veh.lights", getVehicleSyncer(vehicleData), vehicleData.syncId, lights);
+
+ vehicleData.lights = !vehicleData.lights;
- if(getVehicleData(vehicle).lights) {
- vehicle.setData("ag.lights", false, true);
- triggerNetworkEvent("ag.veh.sync", null, vehicle);
- getVehicleData(vehicle).lights = false;
- } else {
- vehicle.setData("ag.lights", true, true);
- triggerNetworkEvent("ag.veh.sync", null, vehicle);
- getVehicleData(vehicle).lights = true;
- }
-
- let lightsText = (getVehicleData(vehicle).lights) ? "on" : "off";
- meActionToNearbyPlayers(client, `turned the ${getVehicleName(vehicle)}'s lights ${lightsText}`);
+ meActionToNearbyPlayers(client, `turned the ${getVehicleName(vehicleData.modelIndex)}'s lights ${getOnOffFromBool(vehicleData.lights)}`);
}
// ---------------------------------------------------------------------------
@@ -303,35 +289,28 @@ function vehicleEngineCommand(command, params, client) {
return false;
}
- if(!client.player.vehicle) {
+ if(!getPlayerVehicle(client)) {
messageClientError(client, "You need to be in a vehicle!");
return false;
}
- if(client.player.getData("ag.vehSeat") > 0) {
+ if(getPlayerVehicleSeat(client) > 0) {
messageClientError(client, "You need to be the driver!");
return false;
}
- let vehicle = client.player.vehicle;
+ let vehicleData = getPlayerVehicle(client);
- if(!doesClientHaveVehicleKeys(client, vehicle)) {
+ if(!doesClientHaveVehicleKeys(client, vehicleData)) {
messageClientError(client, "You don't have keys to this vehicle!");
return false;
}
- if(getVehicleData(vehicle).engine) {
- vehicle.setData("ag.engine", false, true);
- triggerNetworkEvent("ag.veh.sync", null, vehicle);
- getVehicleData(vehicle).engine = false;
- } else {
- vehicle.setData("ag.engine", true, true);
- triggerNetworkEvent("ag.veh.sync", null, vehicle);
- getVehicleData(vehicle).engine = true;
- }
- let engineText = (getVehicleData(vehicle).engine) ? "on" : "off";
+ vehicleData.engine = !vehicleData.engine;
- meActionToNearbyPlayers(client, `turned the ${getVehicleName(vehicle)}'s engine ${engineText}`);
+ triggerNetworkEvent("ag.veh.engine", getVehicleSyncer(vehicleData), vehicleData.syncId, engine);
+
+ meActionToNearbyPlayers(client, `turned the ${getVehicleName(vehicleData.modelIndex)}'s engine ${getOnOffFromBool(vehicleData.engine)}`);
}
// ---------------------------------------------------------------------------
@@ -356,37 +335,252 @@ function vehicleSirenCommand(command, params, client) {
return false;
}
- if(!client.player.vehicle) {
+ if(!getPlayerVehicle(client)) {
messageClientError(client, "You need to be in a vehicle!");
return false;
}
- if(client.player.getData("ag.vehSeat") > 1) {
+ if(getPlayerVehicleSeat(client) > 1) {
messageClientError(client, "You need to be in the front seat!");
return false;
}
- let vehicle = client.player.vehicle;
+ let vehicleData = getPlayerVehicle(client);
- if(getVehicleData(vehicle).siren) {
- vehicle.setData("ag.siren", false, true);
- triggerNetworkEvent("ag.veh.sync", null, vehicle);
- getVehicleData(vehicle).siren = false;
- } else {
- vehicle.setData("ag.siren", true, true);
- triggerNetworkEvent("ag.veh.sync", null, vehicle);
- getVehicleData(vehicle).siren = true;
+ if(!doesClientHaveVehicleKeys(client, vehicleData)) {
+ messageClientError(client, "You don't have keys to this vehicle!");
+ return false;
}
- let sirenText = (getVehicleData(vehicle).siren) ? "on" : "off";
- meActionToNearbyPlayers(client, `turns the ${getVehicleName(vehicle)}'s siren ${sirenText}`);
+ vehicleData.siren = !vehicleData.siren;
+
+ meActionToNearbyPlayers(client, `turns the ${getVehicleName(vehicleData.modelIndex)}'s siren ${getOnOffFromBool(siren)}`);
}
// ---------------------------------------------------------------------------
-function doesClientHaveVehicleKeys(client, vehicle) {
- let vehicleData = getVehicleData(vehicle);
+function setVehicleColourCommand(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(!getPlayerVehicle(client)) {
+ messageClientError(client, "You need to be in a vehicle!");
+ return false;
+ }
+
+ let vehicle = getPlayerVehicle(client);
+
+ if(!isVehicleAtPayAndSpray(vehicle)) {
+ if(!doesClientHaveStaffPermission(client, getStaffFlagValue("manageVehicles"))) {
+ messageClientError(client, "You need to be at a pay-n-spray!");
+ return false;
+ }
+ }
+
+ if(getClientCurrentSubAccount(client).cash < getServerConfig().resprayVehicleCost) {
+ messageClientError(client, `You don't have enough money to respray the vehicle (need $${getServerConfig().resprayVehicleCost-getClientCurrentSubAccount(client).cash} more!)`);
+ return false;
+ }
+
+ let splitParams = params.split(" ");
+ let colour1 = toInteger(splitParams[0]) || 0;
+ let colour2 = toInteger(splitParams[1]) || 0;
+
+ getClientCurrentSubAccount(client).cash -= getServerConfig().resprayVehicleCost;
+ if(server.game == GAME_GTA_IV) {
+ triggerNetworkEvent("ag.veh.colour", getVehicleData(vehicle).syncedBy, getVehicleData(vehicle).syncId, colour1, colour2)
+ } else {
+ vehicle.colour1 = colour1;
+ vehicle.colour2 = colour2;
+ getVehicleData(vehicle).colour1 = colour1;
+ getVehicleData(vehicle).colour2 = colour1;
+ }
+
+ meActionToNearbyPlayers(client, `resprays the ${getVehicleName(vehicle)}'s colours`);
+}
+
+// ---------------------------------------------------------------------------
+
+function vehicleRepairCommand(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(!isPlayerInAnyVehicle(client)) {
+ messageClientError(client, "You need to be in a vehicle!");
+ return false;
+ }
+
+ let vehicleData = getPlayerVehicle(client);
+
+ if(!isAtPayAndSpray(vehicleData.syncPosition)) {
+ if(!doesClientHaveStaffPermission(client, getStaffFlagValue("manageVehicles"))) {
+ messageClientError(client, "You need to be at a pay-n-spray!");
+ return false;
+ }
+ }
+
+ if(getClientCurrentSubAccount(client).cash < getServerConfig().repairVehicleCost) {
+ messageClientError(client, `You don't have enough money to repair the vehicle (need $${getServerConfig().resprayVehicleCost-getClientCurrentSubAccount(client).cash} more!)`);
+ return false;
+ }
+
+
+ getClientCurrentSubAccount(client).cash -= getServerConfig().repairVehicleCost;
+ repairVehicle(vehicleData);
+
+ meActionToNearbyPlayers(client, `repairs the ${getVehicleName(vehicleData.modelIndex)}!`);
+}
+
+// ---------------------------------------------------------------------------
+
+function buyVehicleCommand(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(!isPlayerInAnyVehicle(client)) {
+ messageClientError(client, "You need to be in a vehicle!");
+ return false;
+ }
+
+ let vehicleData = getPlayerVehicle(client);
+
+ if(!isAtPayAndSpray(vehicleData.syncPosition)) {
+ if(!doesClientHaveStaffPermission(client, getStaffFlagValue("manageVehicles"))) {
+ messageClientError(client, "You need to be at a pay-n-spray!");
+ return false;
+ }
+ }
+
+ if(getClientCurrentSubAccount(client).cash < vehicleData.buyPrice) {
+ messageClientError(client, `You don't have enough money to buy this vehicle (need $${vehicleData.buyPrice-getClientCurrentSubAccount(client).cash} more!)`);
+ return false;
+ }
+
+
+ getClientCurrentSubAccount(client).cash -= vehicleData.buyPrice;
+ setVehicleOwner(AG_VEHOWNER_PLAYER, getClientCurrentSubAccount(client).databaseId);
+
+ meActionToNearbyPlayers(client, `buys the ${getVehicleName(vehicleData.modelIndex)} and receives a set of vehicle keys!`);
+}
+
+// ---------------------------------------------------------------------------
+
+function rentVehicleCommand(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(!isPlayerInAnyVehicle(client)) {
+ messageClientError(client, "You need to be in a vehicle!");
+ return false;
+ }
+
+ let vehicleData = getPlayerVehicle(client);
+
+ vehicleData.rentedBy = client;
+ getClientCurrentSubAccount(client).rentingVehicle = vehicleData;
+ vehicleData.rentStart = new Date().getTime();
+
+ meActionToNearbyPlayers(client, `rents the ${getVehicleName(vehicleData.modelIndex)} and receives a set of vehicle keys!`);
+ messageClientAlert(client, `You will be charged ${vehicleData.rentPrice} per minute to use this vehicle. To stop renting this vehicle, use /vehrent again.`);
+}
+
+// ---------------------------------------------------------------------------
+
+function stopRentingVehicleCommand(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;
+ }
+
+ //getClientCurrentSubAccount(client).cash -= getVehicleData(vehicle).rentPrice;
+ let vehicleData = getClientCurrentSubAccount(client).rentingVehicle;
+ stopRentingVehicle(client);
+
+ messageClientAlert(client, `You are no longer renting the ${getVehicleName(vehicleData.modelIndex)}`);
+}
+
+// ---------------------------------------------------------------------------
+
+function doesClientHaveVehicleKeys(client, vehicleData) {
if(doesClientHaveStaffPermission(client, getStaffFlagValue("manageVehicles"))) {
return true;
}
@@ -428,9 +622,32 @@ function doesClientHaveVehicleKeys(client, vehicle) {
// ---------------------------------------------------------------------------
-function getVehicleName(vehicle) {
- let vehicleName = getVehicleNameFromModelId(vehicle.modelIndex);
- return vehicleName;
+function doesClientOwnVehicle(client, vehicleData) {
+ if(doesClientHaveStaffPermission(client, getStaffFlagValue("manageVehicles"))) {
+ return true;
+ }
+
+ if(vehicleData.ownerType == AG_VEHOWNER_PLAYER) {
+ if(vehicleData.ownerId == getClientData(client).accountData.databaseId) {
+ return true;
+ }
+ }
+
+ if(vehicleData.ownerType == AG_VEHOWNER_CLAN) {
+ if(vehicleData.ownerId == getClientCurrentSubAccount(client).clan) {
+ if(doesClientHaveClanPermission(client, "manageVehicles") || doesClientHaveClanPermission(client, "owner")) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+// ---------------------------------------------------------------------------
+
+function getVehicleName(modelId) {
+ return getVehicleNameFromModelId(modelId) || "Unknown";
}
// ---------------------------------------------------------------------------
@@ -461,7 +678,9 @@ function setVehicleJobCommand(command, params, client) {
}
let vehicle = client.player.vehicle;
- let jobId = getClosestJobPointId(vehicle.position);
+ let closestJobLocation = getClosestJobLocation(vehicle.position);
+ let jobId = closestJobLocation.job;
+
if(!areParamsEmpty(params)) {
jobId = getJobIdFromParams(params);
}
@@ -562,6 +781,86 @@ function setVehicleOwnerCommand(command, params, client) {
// ---------------------------------------------------------------------------
+function setVehicleRentPriceCommand(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;
+ }
+
+ if(!doesClientOwnVehicle(client, vehicle)) {
+ if(!doesClientHaveStaffPermission(client, getStaffFlagValue("manageVehicles"))) {
+ messageClientError(client, "You can't set the rent price for this vehicle!");
+ }
+ }
+
+ let amount = toInteger(params) || 0;
+
+ getVehicleData(vehicle).rentPrice = amount;
+
+ messageClientSuccess(client, `You set the ${getVehicleName(vehicle)}'s rent price to $${amount}!`);
+}
+
+// ---------------------------------------------------------------------------
+
+function setVehicleBuyPriceCommand(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;
+ }
+
+ if(!doesClientOwnVehicle(client, vehicle)) {
+ if(!doesClientHaveStaffPermission(client, getStaffFlagValue("manageVehicles"))) {
+ messageClientError(client, "You can't set the buy price for this vehicle!");
+ }
+ }
+
+ let amount = toInteger(params) || 0;
+
+ getVehicleData(vehicle).buyPrice = amount;
+
+ messageClientSuccess(client, `You set the ${getVehicleName(vehicle)}'s buy price to $${amount}!`);
+}
+
+// ---------------------------------------------------------------------------
+
function removeVehicleOwnerCommand(command, params, client) {
if(getCommand(command).requireLogin) {
if(!isClientLoggedIn(client)) {
@@ -753,19 +1052,14 @@ function reloadAllVehiclesCommand(command, params, client) {
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);
+ for(let i in getServerData().vehicles) {
+ if(getServerData().vehicles[i].vehicle) {
+ destroyElement(getServerData().vehicles[i].vehicle);
}
}
- serverData.vehicles = null;
- serverData.vehicles = loadVehiclesFromDatabase();
+ getServerData().vehicles = null;
+ getServerData().vehicles = loadVehiclesFromDatabase();
spawnAllVehicles();
messageAdminAction(`All server vehicles have been reloaded by an admin!`);
@@ -793,15 +1087,10 @@ function respawnAllVehiclesCommand(command, params, client) {
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;
+ for(let i in getServerData().vehicles) {
+ if(getServerData().vehicles[i].vehicle) {
+ destroyElement(getServerData().vehicles[i].vehicle);
+ getServerData().vehicles[i].vehicle = null;
}
}
@@ -815,8 +1104,8 @@ function respawnAllVehiclesCommand(command, params, client) {
function sendAllVehiclesToClient(client) {
/*
let tempVehicles = [];
- for(let i in serverData.vehicles) {
- let thisVehicle = serverData.vehicles[i];
+ for(let i in getServerData().vehicles) {
+ let thisVehicle = getServerData().vehicles[i];
tempVehicles.push({
model: thisVehicle.model,
@@ -832,13 +1121,149 @@ 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];
+ for(let i in getServerData().vehicles) {
+ if(getServerData().vehicles[i].ivSyncId != -1) {
+ if(getServerData().vehicles[i].ivSyncId == syncId) {
+ return getServerData().vehicles[i];
}
}
}
}
-// ---------------------------------------------------------------------------
\ No newline at end of file
+// ---------------------------------------------------------------------------
+
+function stopRentingVehicle(client) {
+ let vehicleData = getClientData(client).rentingVehicle;
+ getClientData(client).rentingVehicle = false;
+ vehicleData.rentedBy = false;
+ respawnVehicle(vehicleData);
+}
+
+// ---------------------------------------------------------------------------
+
+function respawnVehicle(vehicleData) {
+ let vehicles = getServerData().vehicles;
+ for(let i in vehicles) {
+ if(vehicleData == vehicles[i]) {
+ if(!isGTAIV()) {
+ destroyElement(vehicle);
+ let vehicle = spawnVehicle(vehicles[i]);
+ vehicles[i].vehicle = vehicle;
+ vehicle.setData("ag.dataSlot", i, false);
+ } else {
+ triggerNetworkEvent("ag.vehicle", getClosestPlayer(vehicleData.spawnPosition), i, vehicleData.modelIndex, vehicleData.spawnPosition, vehicleData.spawnRotation, vehicleData.colour1, vehicleData.colour2, vehicleData.locked, vehicleData.lights);
+ }
+ }
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+function spawnVehicle(vehicleData) {
+ let vehicle = gta.createVehicle(vehicleData.model, vehicleData.spawnPosition, vehicleData.spawnRotation);
+ addToWorld(vehicle);
+
+ if(vehicleData.colour1IsRGBA && vehicleData.colour2IsRGBA) {
+ vehicle.setRGBColours(vehicleData.colour1RGBA, vehicleData.colour2RGBA);
+ } else {
+ vehicle.colour1 = vehicleData.colour1;
+ vehicle.colour2 = vehicleData.colour2;
+ vehicle.colour3 = vehicleData.colour3;
+ vehicle.colour4 = vehicleData.colour4;
+ }
+
+ vehicle.engine = intToBool(vehicleData.engine);
+ //vehicle.lights = intToBool(vehicleData.lights);
+ //vehicle.health = vehicleData.health;
+
+ //vehicle.position = vehicleData.spawnPosition;
+ vehicle.heading = vehicleData.spawnRotation;
+
+ vehicle.locked = intToBool(vehicleData.locked);
+ vehicle.setData("ag.siren", intToBool(vehicleData.siren), true);
+ vehicle.setData("ag.engine", intToBool(vehicleData.engine), true);
+ vehicle.setData("ag.lights", intToBool(vehicleData.lights), true);
+
+ return vehicle;
+}
+
+// ---------------------------------------------------------------------------
+
+function isVehicleAtPayAndSpray(vehicle) {
+ for(let i in getServerData().payAndSprays[server.game]) {
+ if(vehicle.position.distance(getServerData().payAndSprays[server.game][i].position) <= getServerConfig().payAndSprayDistance) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// ---------------------------------------------------------------------------
+
+function repairVehicle(vehicleData) {
+ if(isGTAIV()) {
+ triggerNetworkEvent("ag.veh.fix", vehicleData.syncedBy, vehicleData.syncId);
+ } else {
+ vehicleData.vehicle.fix();
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+function setVehicleColours(vehicleData, colour1, colour2) {
+ if(isGTAIV()) {
+ triggerNetworkEvent("ag.veh.colour", vehicleData.syncedBy, vehicleData.syncId, colour1, colour2);
+ } else {
+ vehicleData.vehicle.colour1 = colour1;
+ vehicleData.vehicle.colour2 = colour2;
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+function setVehicleLights(vehicleData, lights) {
+ if(isGTAIV()) {
+ triggerNetworkEvent("ag.veh.lights", vehicleData.syncedBy, vehicleData.syncId, lights);
+ } else {
+ triggerNetworkEvent("ag.veh.lights", null, vehicleData.vehicle, lights);
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+function setVehicleEngine(vehicleData, engine) {
+ if(isGTAIV()) {
+ triggerNetworkEvent("ag.veh.engine", vehicleData.syncedBy, vehicleData.syncId, engine);
+ } else {
+ triggerNetworkEvent("ag.veh.engine", null, vehicleData.vehicle, engine);
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+function setVehicleLocked(vehicleData, locked) {
+ if(isGTAIV()) {
+ triggerNetworkEvent("ag.veh.locked", vehicleData.syncedBy, vehicleData.syncId, locked);
+ } else {
+ triggerNetworkEvent("ag.veh.locked", null, vehicleData.vehicle, locked);
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+function getVehicleDataFromSyncId(syncId) {
+ let vehicles = getServerData().vehicles;
+ for(let i in vehicles) {
+ if(vehicles[i].syncId == syncId) {
+ return vehicles[i];
+ }
+ }
+
+ return false;
+}
+
+// ----------------------------------------------------------------------------
+
+function transferVehicleSyncToAnotherClient(vehicleData) {
+ let closestClient = getClosestPlayer(vehicleData.syncPosition);
+}
\ No newline at end of file
diff --git a/scripts/shared/game-data.js b/scripts/shared/game-data.js
new file mode 100644
index 00000000..84d17a91
--- /dev/null
+++ b/scripts/shared/game-data.js
@@ -0,0 +1,2723 @@
+// ===========================================================================
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
+// ---------------------------------------------------------------------------
+// FILE: game-data.js
+// DESC: Provides coords, ids, names, and other data for the games
+// TYPE: Shared (JavaScript)
+// ===========================================================================
+
+let gameData = {
+ weaponNames: [
+ ["Unknown"], // Game 0 is invalid (GTA 3 is the first game, and is ID 1)
+
+ [ // GTA III
+ "Fist",
+ "Bat",
+ "Pistol",
+ "Uzi",
+ "Shotgun",
+ "AK47",
+ "M16",
+ "Sniper Rifle",
+ "Rocket Launcher",
+ "Flamethrower",
+ "Molotov",
+ "Grenade"
+ ],
+
+ [ // GTA VC
+ "Fist",
+ "Brass Knuckles",
+ "Screwdriver",
+ "Golf Club",
+ "Nitestick",
+ "Knife",
+ "Baseball Bat",
+ "Hammer",
+ "Meat Cleaver",
+ "Machete",
+ "Katana",
+ "Chainsaw",
+ "Grenade",
+ "Remote Grenade",
+ "Teargas",
+ "Molotov Cocktail",
+ "Missile",
+ "Colt .45",
+ "Python",
+ "Shotgun",
+ "Spaz Shotgun",
+ "Stubby Shotgun",
+ "Tec-9",
+ "Uzi",
+ "Ingram",
+ "MP5",
+ "M4",
+ "Ruger",
+ "Sniper Rifle",
+ "Laser Sniper",
+ "RPG",
+ "Flame Thrower",
+ "M60",
+ "Minigun"
+ ],
+
+ [ // GTA San Andreas
+ "Fist",
+ "Brass Knuckles",
+ "Golf Club",
+ "Nightstick",
+ "Knife",
+ "Baseball Bat",
+ "Shovel",
+ "Pool Cue",
+ "Katana",
+ "Chainsaw",
+ "Purple Dildo",
+ "Dildo",
+ "Vibrator",
+ "Silver Vibrator",
+ "Flowers",
+ "Cane",
+ "Grenade",
+ "Teargas",
+ "Molotov Cocktail",
+ "Unknown",
+ "Unknown",
+ "Unknown",
+ "9mm",
+ "Silenced 9mm",
+ "Desert Eagle",
+ "Shotgun",
+ "Sawnoff Shotgun",
+ "Combat Shotgun",
+ "Uzi",
+ "MP5",
+ "AK-47",
+ "M4",
+ "Tec-9",
+ "Country Rifle",
+ "Sniper Rifle",
+ "RPG",
+ "HS Rocket",
+ "Flamethrower",
+ "Minigun",
+ "Satchel Charge",
+ "Detonator",
+ "Spraycan",
+ "Fire Extinguisher",
+ "Camera",
+ "Night Vision Goggles",
+ "Thermal Goggles",
+ "Parachute",
+ "Cellphone",
+ "Jetpack",
+ "Skateboard"
+ ],
+
+ [ // GTA Underground
+ "Fist",
+ "Brass Knuckles",
+ "Golf Club",
+ "Nightstick",
+ "Knife",
+ "Baseball Bat",
+ "Shovel",
+ "Pool Cue",
+ "Katana",
+ "Chainsaw",
+ "Purple Dildo",
+ "Dildo",
+ "Vibrator",
+ "Silver Vibrator",
+ "Flowers",
+ "Cane",
+ "Grenade",
+ "Teargas",
+ "Molotov Cocktail",
+ "Unknown",
+ "Unknown",
+ "Unknown",
+ "9mm",
+ "Silenced 9mm",
+ "Desert Eagle",
+ "Shotgun",
+ "Sawnoff Shotgun",
+ "Combat Shotgun",
+ "Uzi",
+ "MP5",
+ "AK-47",
+ "M4",
+ "Tec-9",
+ "Country Rifle",
+ "Sniper Rifle",
+ "RPG",
+ "HS Rocket",
+ "Flamethrower",
+ "Minigun",
+ "Satchel Charge",
+ "Detonator",
+ "Spraycan",
+ "Fire Extinguisher",
+ "Camera",
+ "Night Vision Goggles",
+ "Thermal Goggles",
+ "Parachute",
+ "Cellphone",
+ "Jetpack",
+ "Skateboard",
+ ],
+
+ [ // GTA IV
+ "Fist",
+ "Bat",
+ "Pool Cue",
+ "Knife",
+ "Grenade",
+ "Molotov",
+ "Rocket",
+ "Pistol",
+ "UNUSED",
+ "Desert Eagle",
+ "Stubby Shotgun",
+ "Baretta Shotgun",
+ "Micro Uzi",
+ "MP5",
+ "AK-47",
+ "M4",
+ "Combat Sniper",
+ "M40A1",
+ "RPG",
+ "Flamethrower",
+ "Minigun",
+ "EFLC Weapon 1",
+ "EFLC Weapon 2",
+ "EFLC Weapon 3",
+ "EFLC Weapon 4",
+ "EFLC Weapon 5",
+ "EFLC Weapon 6",
+ "EFLC Weapon 7",
+ "EFLC Weapon 8",
+ "EFLC Weapon 9",
+ "EFLC Weapon 10",
+ "EFLC Weapon 11",
+ "EFLC Weapon 12",
+ "EFLC Weapon 13",
+ "EFLC Weapon 14",
+ "EFLC Weapon 15",
+ "EFLC Weapon 16",
+ "EFLC Weapon 17",
+ "EFLC Weapon 18",
+ "EFLC Weapon 19",
+ "EFLC Weapon 20",
+ "EFLC Weapon 21",
+ "EFLC Weapon 22",
+ "EFLC Weapon 23",
+ "EFLC Weapon 24",
+ "Camera",
+ ],
+
+ [ // GTA IV (EFLC)
+ "Fist",
+ "Bat",
+ "Pool Cue",
+ "Knife",
+ "Grenade",
+ "Molotov",
+ "UNUSED",
+ "Pistol",
+ "Desert Eagle",
+ "Stubby Shotgun",
+ "Baretta Shotgun",
+ "Shotgun",
+ "Micro Uzi",
+ "MP5",
+ "AK-47",
+ "M4",
+ "Combat Sniper",
+ "M40A1",
+ "RPG",
+ "Flamethrower",
+ "Minigun",
+ "EFLC Weapon 1",
+ "EFLC Weapon 2",
+ "EFLC Weapon 3",
+ "EFLC Weapon 4",
+ "EFLC Weapon 5",
+ "EFLC Weapon 6",
+ "EFLC Weapon 7",
+ "EFLC Weapon 8",
+ "EFLC Weapon 9",
+ "EFLC Weapon 10",
+ "EFLC Weapon 11",
+ "EFLC Weapon 12",
+ "EFLC Weapon 13",
+ "EFLC Weapon 14",
+ "EFLC Weapon 15",
+ "EFLC Weapon 16",
+ "EFLC Weapon 17",
+ "EFLC Weapon 18",
+ "EFLC Weapon 19",
+ "EFLC Weapon 20",
+ "EFLC Weapon 21",
+ "EFLC Weapon 22",
+ "EFLC Weapon 23",
+ "EFLC Weapon 24",
+ "Camera",
+ ],
+ ],
+ gameAnnounceColours: [
+ COLOUR_BLACK, // Invalid
+ COLOUR_WHITE, // GTA III
+ COLOUR_AQUA, // GTA Vice City
+ COLOUR_ORANGE, // GTA San Andreas
+ COLOUR_ORANGE, // GTA Underground
+ COLOUR_SILVER, // GTA IV
+ COLOUR_SILVER // GTA IV (EFLC)
+ ],
+ weatherNames: [
+ ["Unknown"],
+ [ // GTA III
+ "Clear",
+ "Overcast",
+ "Thunderstorm",
+ "Fog",
+ "Clear",
+ "Rainy",
+ "Dark/Cloudy",
+ "Light/Cloudy",
+ "Overcast/Cloudy",
+ "Grey/Cloudy"
+ ],
+ [ // GTA Vice City
+ "Clear",
+ "Overcast",
+ "Thunderstorm",
+ "Fog",
+ "Clear",
+ "Rainy",
+ "Dark/Cloudy",
+ "Light/Cloudy",
+ "Overcast/Cloudy",
+ "Grey/Cloudy"
+ ],
+ [ // GTA San Andreas
+ "Blue Skies",
+ "Blue Skies",
+ "Blue Skies",
+ "Blue Skies",
+ "Blue Skies",
+ "Blue Skies",
+ "Blue Skies",
+ "Blue Skies",
+ "Thunderstorm",
+ "Cloudy/Foggy",
+ "Clear Blue Skies",
+ "Heatwave",
+ "Dull/Colorless",
+ "Dull/Colorless",
+ "Dull/Colorless",
+ "Dull/Colorless",
+ "Dull/Rainy",
+ "Heatwave",
+ "Heatwave",
+ "Sandstorm",
+ "Greenish/Foggy"
+ ],
+ [ // GTA Underground
+ "Blue Skies",
+ "Blue Skies",
+ "Blue Skies",
+ "Blue Skies",
+ "Blue Skies",
+ "Blue Skies",
+ "Blue Skies",
+ "Blue Skies",
+ "Thunderstorm",
+ "Cloudy/Foggy",
+ "Clear Blue Skies",
+ "Heatwave",
+ "Dull/Colorless",
+ "Dull/Colorless",
+ "Dull/Colorless",
+ "Dull/Colorless",
+ "Dull/Rainy",
+ "Heatwave",
+ "Heatwave",
+ "Sandstorm",
+ "Greenish/Foggy"
+ ],
+ [ // GTA IV
+ "Extra Sunny",
+ "Sunny",
+ "Sunny/Windy",
+ "Cloudy",
+ "Rain",
+ "Light Rain",
+ "Foggy",
+ "Thunderstorm",
+ "Extra Sunny",
+ "Sunny/Windy",
+ ],
+ ],
+ gameNames: [
+ "Unknown",
+ "GTA III",
+ "GTA Vice City",
+ "GTA San Andreas",
+ "GTA Underground",
+ "GTA IV",
+ "GTA IV: Episodes from Liberty City",
+ ],
+ vehicleWheelStateNames: [
+ "normal",
+ "flat",
+ "gone"
+ ],
+ vehicleDoorStateNames: [
+ "closed",
+ "closed",
+ "swinging",
+ "open"
+ ],
+ vehicleWheelNames: [
+ "front left",
+ "rear left",
+ "front right",
+ "rear right"
+ ],
+ vehicleLightNames: [
+ "front left",
+ "rear left",
+ "front right",
+ "rear right"
+ ],
+ vehicleRadioStationNames: [
+ [],
+ [ // GTA III
+ "Head Radio",
+ "Double Cleff FM",
+ "Jah Radio",
+ "Rise FM",
+ "Lips 106",
+ "Flashback FM",
+ "Chatterbox 109",
+ "MP3 Player"
+ ],
+ [ // GTA Vice City
+ "Wildstyle",
+ "Flash FM",
+ "K CHAT",
+ "Fever 105",
+ "VROCK",
+ "VCPR",
+ "Espantoso",
+ "Emotion 98.3",
+ "Wave 103",
+ "MP3 Player"
+ ],
+ [ // GTA San Andreas
+ "KROSE",
+ "KDST",
+ "Bounce FM",
+ "SFUR",
+ "Radio Los Santos",
+ "Radio X",
+ "CSR Radio",
+ "KJAH West",
+ "Master Sounds",
+ "WCTR",
+ "User Track Player"
+ ]
+ ],
+ vehicleModelIdStart: [
+ 0,
+ 90, // GTA III
+ 130, // GTA Vice City
+ 400, // GTA San Andreas
+ 400 // GTA Underground
+ ],
+ vehicleNames: [
+ [],
+ [ // GTA III
+ "Landstalker",
+ "Idaho",
+ "Stinger",
+ "Linerunner",
+ "Perennial",
+ "Sentinel",
+ "Patriot",
+ "Fire Truck",
+ "Trashmaster",
+ "Stretch",
+ "Manana",
+ "Infernus",
+ "Blista",
+ "Pony",
+ "Mule",
+ "Cheetah",
+ "Ambulance",
+ "FBI Car",
+ "Moonbeam",
+ "Esperanto",
+ "Taxi",
+ "Kuruma",
+ "Bobcat",
+ "Mr. Whoopee",
+ "BF Injection",
+ "Manana (Corpse)",
+ "Police Car",
+ "Enforcer",
+ "Securicar",
+ "Banshee",
+ "Predator",
+ "Bus",
+ "Rhino",
+ "Barracks OL",
+ "Train",
+ "Police Helicopter",
+ "Dodo",
+ "Coach",
+ "Cabbie",
+ "Stallion",
+ "Rumpo",
+ "RC Bandit",
+ "Bellyup",
+ "Mr. Wongs",
+ "Mafia Sentinel",
+ "Yardie Lobo",
+ "Yakuza Stinger",
+ "Diablo Stallion",
+ "Cartel Cruiser",
+ "Hoods Rumpo XL",
+ "Air Train",
+ "Dead Dodo",
+ "Speeder",
+ "Reefer",
+ "Panlantic",
+ "Flatbed",
+ "Yankee",
+ "Escape",
+ "Borgnine Taxi",
+ "Toyz Van",
+ "Ghost"
+ ],
+ [ // GTA Vice City
+ "Landstalker",
+ "Idaho",
+ "Stinger",
+ "Linerunner",
+ "Perennial",
+ "Sentinel",
+ "Rio",
+ "Firetruck",
+ "Trashmaster",
+ "Stretch",
+ "Manana",
+ "Infernus",
+ "Voodoo",
+ "Pony",
+ "Mule",
+ "Cheetah",
+ "Ambulance",
+ "FBI Washington",
+ "Moonbeam",
+ "Esperanto",
+ "Taxi",
+ "Washington",
+ "Bobcat",
+ "Mr.Whoopee",
+ "BF-Injection",
+ "Hunter",
+ "Police",
+ "Enforcer",
+ "Securicar",
+ "Banshee",
+ "Predator",
+ "Bus",
+ "Rhino",
+ "Barracks OL",
+ "Cuban Hermes",
+ "Helicopter",
+ "Angel",
+ "Coach",
+ "Cabbie",
+ "Stallion",
+ "Rumpo",
+ "RC Bandit",
+ "Romero's Hearse",
+ "Packer",
+ "Sentinel XS",
+ "Admiral",
+ "Squalo",
+ "Sea Sparrow",
+ "Pizza Boy",
+ "Gang Burrito",
+ "Airtrain",
+ "Deaddodo",
+ "Speeder",
+ "Reefer",
+ "Tropic",
+ "Flatbed",
+ "Yankee",
+ "Caddy",
+ "Zebra Cab",
+ "Top Fun",
+ "Skimmer",
+ "PCJ-600",
+ "Faggio",
+ "Freeway",
+ "Rcbaron",
+ "RC Raider",
+ "Glendale",
+ "Oceanic",
+ "Sanchez",
+ "Sparrow",
+ "Patriot",
+ "Love Fist",
+ "Coast Guard",
+ "Dinghy",
+ "Hermes",
+ "Sabre",
+ "Sabre Turbo",
+ "Phoenix",
+ "Walton",
+ "Regina",
+ "Comet",
+ "Deluxo",
+ "Burrito",
+ "Spand Express",
+ "Marquis",
+ "Baggage Handler",
+ "Kaufman Cab",
+ "Maverick",
+ "VCN Maverick",
+ "Rancher",
+ "FBI Rancher",
+ "Virgo",
+ "Greenwood",
+ "Cuban Jetmax",
+ "Hotring Racer 1",
+ "Sandking",
+ "Blista Compact",
+ "Police Maverick",
+ "Boxville",
+ "Benson",
+ "Mesa Grande",
+ "RC Goblin",
+ "Hotring Racer 2",
+ "Hotring Racer 3",
+ "Bloodring Banger 1",
+ "Bloodring Banger 2",
+ "VCPD Cheetah"
+ ],
+ [ // GTA San Andreas
+ "Landstalker",
+ "Bravura",
+ "Buffalo",
+ "Linerunner",
+ "Pereniel",
+ "Sentinel",
+ "Dumper",
+ "Firetruck",
+ "Trashmaster",
+ "Stretch",
+ "Manana",
+ "Infernus",
+ "Voodoo",
+ "Pony",
+ "Mule",
+ "Cheetah",
+ "Ambulance",
+ "Leviathan",
+ "Moonbeam",
+ "Esperanto",
+ "Taxi",
+ "Washington",
+ "Bobcat",
+ "Mr Whoopee",
+ "BF Injection",
+ "Hunter",
+ "Premier",
+ "Enforcer",
+ "Securicar",
+ "Banshee",
+ "Predator",
+ "Bus",
+ "Rhino",
+ "Barracks",
+ "Hotknife",
+ "Trailer",
+ "Previon",
+ "Coach",
+ "Cabbie",
+ "Stallion",
+ "Rumpo",
+ "RC Bandit",
+ "Romero",
+ "Packer",
+ "Monster",
+ "Admiral",
+ "Squalo",
+ "Seasparrow",
+ "Pizzaboy",
+ "Tram",
+ "Trailer",
+ "Turismo",
+ "Speeder",
+ "Reefer",
+ "Tropic",
+ "Flatbed",
+ "Yankee",
+ "Caddy",
+ "Solair",
+ "Berkley's RC Van",
+ "Skimmer",
+ "PCJ-600",
+ "Faggio",
+ "Freeway",
+ "RC Baron",
+ "RC Raider",
+ "Glendale",
+ "Oceanic",
+ "Sanchez",
+ "Sparrow",
+ "Patriot",
+ "Quad",
+ "Coastguard",
+ "Dinghy",
+ "Hermes",
+ "Sabre",
+ "Rustler",
+ "ZR-350",
+ "Walton",
+ "Regina",
+ "Comet",
+ "BMX",
+ "Burrito",
+ "Camper",
+ "Marquis",
+ "Baggage",
+ "Dozer",
+ "Maverick",
+ "News Maverick",
+ "Rancher",
+ "FBI Rancher",
+ "Virgo",
+ "Greenwood",
+ "Jetmax",
+ "Hotring-Racer A",
+ "Sandking",
+ "Blista",
+ "Police Maverick",
+ "Boxville",
+ "Benson",
+ "Mesa",
+ "RC Goblin",
+ "Hotring-Racer B",
+ "Hotring-Racer C",
+ "Bloodring-Banger",
+ "Rancher",
+ "Super-GT",
+ "Elegant",
+ "Journey",
+ "Bike",
+ "Mountain Bike",
+ "Beagle",
+ "Cropdust",
+ "Stunt",
+ "Tanker",
+ "RoadTrain",
+ "Nebula",
+ "Majestic",
+ "Buccaneer",
+ "Shamal",
+ "Hydra",
+ "FCR-900",
+ "NRG-500",
+ "HPV1000",
+ "Cement Truck",
+ "Tow Truck",
+ "Fortune",
+ "Cadrona",
+ "FBI Truck",
+ "Willard",
+ "Forklift",
+ "Tractor",
+ "Combine",
+ "Feltzer",
+ "Remington",
+ "Slamvan",
+ "Blade",
+ "Freight",
+ "Streak",
+ "Vortex",
+ "Vincent",
+ "Bullet",
+ "Clover",
+ "Sadler",
+ "Firetruck",
+ "Hustler",
+ "Intruder",
+ "Primo",
+ "Cargobob",
+ "Tampa",
+ "Sunrise",
+ "Merit",
+ "Utility",
+ "Nevada",
+ "Yosemite",
+ "Windsor",
+ "Monster Truck A",
+ "Monster Truck B",
+ "Uranus",
+ "Jester",
+ "Sultan",
+ "Stratum",
+ "Elegy",
+ "Raindance",
+ "RC Tiger",
+ "Flash",
+ "Tahoma",
+ "Savanna",
+ "Bandito",
+ "Freight",
+ "Trailer",
+ "Kart",
+ "Mower",
+ "Duneride",
+ "Sweeper",
+ "Broadway",
+ "Tornado",
+ "AT-400",
+ "DFT-30",
+ "Huntley",
+ "Stafford",
+ "BF-400",
+ "Newsvan",
+ "Tug",
+ "Trailer",
+ "Emperor",
+ "Wayfarer",
+ "Euros",
+ "Hotdog",
+ "Club",
+ "Trailer",
+ "Trailer",
+ "Andromada",
+ "Dodo",
+ "RC Cam",
+ "Launch",
+ "Police Car (LSPD)",
+ "Police Car (SFPD)",
+ "Police Car (LVPD)",
+ "Police Ranger",
+ "Picador",
+ "S.W.A.T. Van",
+ "Alpha",
+ "Phoenix",
+ "Broken Glendale",
+ "Broken Sadler",
+ "Luggage Trailer",
+ "Luggage Trailer",
+ "Stair Trailer",
+ "Boxville",
+ "Farm Plow",
+ "Utility Trailer"
+ ],
+ ],
+ vehicleColourHex: [
+ [],
+ [ // GTA III
+ "#050505",
+ "#F5F5F5",
+ "#2A77A1",
+ "#B3363A",
+ "#263739",
+ "#86446E",
+ "#F3ED47",
+ "#4C75B7",
+ "#667292",
+ "#5E7072",
+ "#352224",
+ "#5A2124",
+ "#662B2B",
+ "#63322E",
+ "#842827",
+ "#8A3A42",
+ "#682731",
+ "#8B3C44",
+ "#9E2F2B",
+ "#A33A2F",
+ "#D25633",
+ "#925635",
+ "#F4723A",
+ "#D35733",
+ "#E25A59",
+ "#772A25",
+ "#E17743",
+ "#C44636",
+ "#E17844",
+ "#C35938",
+ "#464840",
+ "#747761",
+ "#757763",
+ "#918A3D",
+ "#948C66",
+ "#998D79",
+ "#D8A534",
+ "#C9BD7D",
+ "#C9C591",
+ "#D4C84E",
+ "#1A332E",
+ "#062505",
+ "#1D373F",
+ "#3C4A3B",
+ "#2D5037",
+ "#3A6C60",
+ "#3A623C",
+ "#7CA282",
+ "#4C524E",
+ "#56775B",
+ "#101450",
+ "#485E84",
+ "#1C2745",
+ "#1F3468",
+ "#2B4878",
+ "#475C83",
+ "#447C92",
+ "#3D67AB",
+ "#4B7D82",
+ "#80B0B7",
+ "#3D2333",
+ "#1C2948",
+ "#343941",
+ "#40454C",
+ "#4A2D2B",
+ "#563E33",
+ "#41464C",
+ "#672731",
+ "#835A75",
+ "#868587",
+ "#171717",
+ "#2E2E2E",
+ "#454545",
+ "#5C5C5C",
+ "#737373",
+ "#8A8A8A",
+ "#A1A1A1",
+ "#B8B8B8",
+ "#CFCFCF",
+ "#E6E6E6",
+ "#AAAFAA",
+ "#6A736B",
+ "#AAAFAA",
+ "#BBBEB5",
+ "#BBBEB5",
+ "#6A6F70",
+ "#60635F",
+ "#6A736B",
+ "#AAAFAA",
+ "#BBBEB5",
+ "#21292B",
+ "#343842",
+ "#414648",
+ "#4E5960",
+ "#41454C"
+ ],
+ [ // GTA Vice City
+ "#050505",
+ "#F5F5F5",
+ "#2A77A1",
+ "#B3363A",
+ "#263739",
+ "#86446E",
+ "#F3ED47",
+ "#4C75B7",
+ "#667292",
+ "#5E7072",
+ "#352224",
+ "#5A2124",
+ "#662B2B",
+ "#63322E",
+ "#842827",
+ "#8A3A42",
+ "#682731",
+ "#8B3C44",
+ "#9E2F2B",
+ "#A33A2F",
+ "#D25633",
+ "#925635",
+ "#F4723A",
+ "#D35733",
+ "#E25A59",
+ "#772A25",
+ "#E17743",
+ "#C44636",
+ "#E17844",
+ "#C35938",
+ "#464840",
+ "#747761",
+ "#757763",
+ "#918A3D",
+ "#948C66",
+ "#998D79",
+ "#D8A534",
+ "#C9BD7D",
+ "#C9C591",
+ "#D4C84E",
+ "#1A332E",
+ "#062505",
+ "#1D373F",
+ "#3C4A3B",
+ "#2D5037",
+ "#3A6C60",
+ "#3A623C",
+ "#7CA282",
+ "#4C524E",
+ "#56775B",
+ "#101450",
+ "#485E84",
+ "#1C2745",
+ "#1F3468",
+ "#2B4878",
+ "#475C83",
+ "#447C92",
+ "#3D67AB",
+ "#4B7D82",
+ "#80B0B7",
+ "#3D2333",
+ "#1C2948",
+ "#343941",
+ "#40454C",
+ "#4A2D2B",
+ "#563E33",
+ "#41464C",
+ "#672731",
+ "#835A75",
+ "#868587",
+ "#171717",
+ "#2E2E2E",
+ "#454545",
+ "#5C5C5C",
+ "#737373",
+ "#8A8A8A",
+ "#A1A1A1",
+ "#B8B8B8",
+ "#CFCFCF",
+ "#E6E6E6",
+ "#AAAFAA",
+ "#6A736B",
+ "#AAAFAA",
+ "#BBBEB5",
+ "#BBBEB5",
+ "#6A6F70",
+ "#60635F",
+ "#6A736B",
+ "#AAAFAA",
+ "#BBBEB5",
+ "#21292B",
+ "#343842",
+ "#414648",
+ "#4E5960",
+ "#41454C"
+ ],
+ [ // GTA San Andreas
+ "#000000",
+ "#F5F5F5",
+ "#2A77A1",
+ "#840410",
+ "#263739",
+ "#86446E",
+ "#D78E10",
+ "#4C75B7",
+ "#BDBEC6",
+ "#5E7072",
+ "#46597A",
+ "#656A79",
+ "#5D7E8D",
+ "#58595A",
+ "#D6DAD6",
+ "#9CA1A3",
+ "#335F3F",
+ "#730E1A",
+ "#7B0A2A",
+ "#9F9D94",
+ "#3B4E78",
+ "#732E3E",
+ "#691E3B",
+ "#96918C",
+ "#515459",
+ "#3F3E45",
+ "#A5A9A7",
+ "#635C5A",
+ "#3D4A68",
+ "#979592",
+ "#421F21",
+ "#5F272B",
+ "#8494AB",
+ "#767B7C",
+ "#646464",
+ "#5A5752",
+ "#252527",
+ "#2D3A35",
+ "#93A396",
+ "#6D7A88",
+ "#221918",
+ "#6F675F",
+ "#7C1C2A",
+ "#5F0A15",
+ "#193826",
+ "#5D1B20",
+ "#9D9872",
+ "#7A7560",
+ "#989586",
+ "#ADB0B0",
+ "#848988",
+ "#304F45",
+ "#4D6268",
+ "#162248",
+ "#272F4B",
+ "#7D6256",
+ "#9EA4AB",
+ "#9C8D71",
+ "#6D1822",
+ "#4E6881",
+ "#9C9C98",
+ "#917347",
+ "#661C26",
+ "#949D9F",
+ "#A4A7A5",
+ "#8E8C46",
+ "#341A1E",
+ "#6A7A8C",
+ "#AAAD8E",
+ "#AB988F",
+ "#851F2E",
+ "#6F8297",
+ "#585853",
+ "#9AA790",
+ "#601A23",
+ "#20202C",
+ "#A4A096",
+ "#AA9D84",
+ "#78222B",
+ "#0E316D",
+ "#722A3F",
+ "#7B715E",
+ "#741D28",
+ "#1E2E32",
+ "#4D322F",
+ "#7C1B44",
+ "#2E5B20",
+ "#395A83",
+ "#6D2837",
+ "#A7A28F",
+ "#AFB1B1",
+ "#364155",
+ "#6D6C6E",
+ "#0F6A89",
+ "#204B6B",
+ "#2B3E57",
+ "#9B9F9D",
+ "#6C8495",
+ "#4D8495",
+ "#AE9B7F",
+ "#406C8F",
+ "#1F253B",
+ "#AB9276",
+ "#134573",
+ "#96816C",
+ "#64686A",
+ "#105082",
+ "#A19983",
+ "#385694",
+ "#525661",
+ "#7F6956",
+ "#8C929A",
+ "#596E87",
+ "#473532",
+ "#44624F",
+ "#730A27",
+ "#223457",
+ "#640D1B",
+ "#A3ADC6",
+ "#695853",
+ "#9B8B80",
+ "#620B1C",
+ "#5B5D5E",
+ "#624428",
+ "#731827",
+ "#1B376D",
+ "#EC6AAE",
+ "#000000"
+ ],
+ [ // GTA Underground
+ "#000000",
+ "#F5F5F5",
+ "#2A77A1",
+ "#840410",
+ "#263739",
+ "#86446E",
+ "#D78E10",
+ "#4C75B7",
+ "#BDBEC6",
+ "#5E7072",
+ "#46597A",
+ "#656A79",
+ "#5D7E8D",
+ "#58595A",
+ "#D6DAD6",
+ "#9CA1A3",
+ "#335F3F",
+ "#730E1A",
+ "#7B0A2A",
+ "#9F9D94",
+ "#3B4E78",
+ "#732E3E",
+ "#691E3B",
+ "#96918C",
+ "#515459",
+ "#3F3E45",
+ "#A5A9A7",
+ "#635C5A",
+ "#3D4A68",
+ "#979592",
+ "#421F21",
+ "#5F272B",
+ "#8494AB",
+ "#767B7C",
+ "#646464",
+ "#5A5752",
+ "#252527",
+ "#2D3A35",
+ "#93A396",
+ "#6D7A88",
+ "#221918",
+ "#6F675F",
+ "#7C1C2A",
+ "#5F0A15",
+ "#193826",
+ "#5D1B20",
+ "#9D9872",
+ "#7A7560",
+ "#989586",
+ "#ADB0B0",
+ "#848988",
+ "#304F45",
+ "#4D6268",
+ "#162248",
+ "#272F4B",
+ "#7D6256",
+ "#9EA4AB",
+ "#9C8D71",
+ "#6D1822",
+ "#4E6881",
+ "#9C9C98",
+ "#917347",
+ "#661C26",
+ "#949D9F",
+ "#A4A7A5",
+ "#8E8C46",
+ "#341A1E",
+ "#6A7A8C",
+ "#AAAD8E",
+ "#AB988F",
+ "#851F2E",
+ "#6F8297",
+ "#585853",
+ "#9AA790",
+ "#601A23",
+ "#20202C",
+ "#A4A096",
+ "#AA9D84",
+ "#78222B",
+ "#0E316D",
+ "#722A3F",
+ "#7B715E",
+ "#741D28",
+ "#1E2E32",
+ "#4D322F",
+ "#7C1B44",
+ "#2E5B20",
+ "#395A83",
+ "#6D2837",
+ "#A7A28F",
+ "#AFB1B1",
+ "#364155",
+ "#6D6C6E",
+ "#0F6A89",
+ "#204B6B",
+ "#2B3E57",
+ "#9B9F9D",
+ "#6C8495",
+ "#4D8495",
+ "#AE9B7F",
+ "#406C8F",
+ "#1F253B",
+ "#AB9276",
+ "#134573",
+ "#96816C",
+ "#64686A",
+ "#105082",
+ "#A19983",
+ "#385694",
+ "#525661",
+ "#7F6956",
+ "#8C929A",
+ "#596E87",
+ "#473532",
+ "#44624F",
+ "#730A27",
+ "#223457",
+ "#640D1B",
+ "#A3ADC6",
+ "#695853",
+ "#9B8B80",
+ "#620B1C",
+ "#5B5D5E",
+ "#624428",
+ "#731827",
+ "#1B376D",
+ "#EC6AAE",
+ "#000000"
+ ],
+ ],
+ skinNames: [
+ [],
+ [ // GTA III
+ "Claude",
+ "Police Officer",
+ "SWAT Officer",
+ "FBI Agent",
+ "Army Soldier",
+ "Paramedic",
+ "Firefighter",
+ "Wise Guy",
+ "Taxi Driver",
+ "Pimp",
+ "Mafia Member",
+ "Mafia Member",
+ "Triad Member",
+ "Triad Member",
+ "Diablo Member",
+ "Diablo Member",
+ "Yakuza Member",
+ "Yakuza Member",
+ "Yardie Member",
+ "Yardie Member",
+ "Cartel Soldier",
+ "Cartel Soldier",
+ "Red Jacks Thug",
+ "Purple Nines Thug",
+ "Street Criminal",
+ "Street Criminal",
+ "INVALID",
+ "INVALID",
+ "INVALID",
+ "INVALID",
+ "Male Client",
+ "Random Guy",
+ "Vacationist",
+ "Dj",
+ "Young Woman",
+ "Young Woman",
+ "Business Woman",
+ "Elder Woman",
+ "Elder Woman",
+ "Prostitute",
+ "Prostitute",
+ "Random Guy",
+ "Diseased Man",
+ "Deseased Woman",
+ "Young Woman",
+ "Old Man",
+ "Random Guy",
+ "Old Woman",
+ "Old Woman",
+ "Old Man",
+ "Random Guy",
+ "Old Woman",
+ "Young Woman",
+ "Docks Worker",
+ "Docks Worker",
+ "Male Street Bum",
+ "Female Street Bum",
+ "Delivery Guy",
+ "Delivery Guy",
+ "Business Man",
+ "Marty Chonks",
+ "Cia Agent",
+ "Female Client",
+ "Young Woman",
+ "Business Woman",
+ "Business Man",
+ "Female Client",
+ "Male Steward",
+ "Female Steward",
+ "Male Cocks Fan",
+ "Male Cocks Fan",
+ "Female Cocks Fan",
+ "Male Paramedics Assistant",
+ "Female Paramedics Assistant",
+ "Construction Worker",
+ "Construction Worker",
+ "Zip Customer",
+ "Party Woman",
+ "Party Woman",
+ "Male College Student",
+ "Female College Student",
+ "Old Man",
+ "Female Jogger",
+ "Asuka Kasen",
+ "Spank Suicide Bomber",
+ "Salvatore's Butler",
+ "Catalina",
+ "Lee Chong",
+ "Colombian Cartel Member",
+ "Colombian Cartel Member",
+ "Colombian Cartel Member",
+ "Colombian Cartel Member",
+ "Police Officer",
+ "Curly Bob",
+ "Phil Cassidy",
+ "Detective",
+ "8-Ball",
+ "8-Ball",
+ "Salvatore Leone",
+ "Mafia Member",
+ "Joey Leone",
+ "Joey Leone",
+ "Bar Owner",
+ "Kenji Kasen",
+ "Mike Forelli",
+ "Donald Love",
+ "Donald Love",
+ "Luigi Goterelli",
+ "Maria Latore",
+ "Mickey Hamfists",
+ "Miguel",
+ "Misty",
+ "Old Oriental Gentleman",
+ "Old Oriental Gentleman",
+ "Old Oriental Gentleman",
+ "Ray Machowski",
+ "Mafia Member",
+ "Ammu-Nation Clerk",
+ "Tanner",
+ "Toni Cipriani",
+ "Darkel",
+ "Chuff Security Officer",
+ "Claude"
+ ],
+ [ // GTA Vice City
+ "Tommy Vercetti",
+ "Police Officer",
+ "SWAT Officer",
+ "FBI Agent",
+ "Army Soldier",
+ "Paramedic",
+ "Fireman",
+ "Golfer",
+ "INVALID",
+ "Random Lady",
+ "Bum",
+ "Greaser",
+ "Random Guy",
+ "Random Guy",
+ "Random Lady",
+ "Random Guy",
+ "Random Guy",
+ "Beach Girl",
+ "Fat Beach Lady",
+ "Beach Guy",
+ "Fat Beach Guy",
+ "Random Lady",
+ "Random Lady",
+ "Random Lady",
+ "Prostitute",
+ "Bum",
+ "Bum",
+ "Random Guy",
+ "Taxi Driver",
+ "Haitian",
+ "Criminal",
+ "Random Lady",
+ "Random Lady",
+ "Random Guy",
+ "Random Guy",
+ "Random Lady",
+ "Random Lady",
+ "Random Guy",
+ "Beach Lady",
+ "Beach Guy",
+ "Beach Lady",
+ "Beach Guy",
+ "Random Guy",
+ "Prostitute",
+ "Bum",
+ "Bum",
+ "Random Guy",
+ "Random Guy",
+ "Punk",
+ "Prostitute",
+ "Random Old Lady",
+ "Punk",
+ "Random Guy",
+ "Random Lady",
+ "Random Lady",
+ "Random Guy",
+ "Random Guy",
+ "Beach Lady",
+ "Beach Guy",
+ "Beach Lady",
+ "Beach Guy",
+ "Construction Worker",
+ "Golfer",
+ "Golfer",
+ "Golfer",
+ "Beach Lady",
+ "Beach Guy",
+ "Random Lady",
+ "Random Guy",
+ "Random Guy",
+ "Prostitute",
+ "Bum Lady",
+ "Random Guy",
+ "Random Guy",
+ "Taxi Driver",
+ "Random Woman",
+ "Skater Guy",
+ "Beach Lady",
+ "Skater Guy",
+ "Young Woman Shopper",
+ "Old Women Shopper",
+ "Tourist",
+ "Tourist",
+ "Cuban",
+ "Cuban",
+ "Haitian",
+ "Haitian",
+ "Shark",
+ "Shark",
+ "Diaz Guy",
+ "Diaz Guy",
+ "Security Guard",
+ "Security Guard",
+ "Biker",
+ "Biker",
+ "Vercetti Guy",
+ "Vercetti Guy",
+ "Undercover Cop",
+ "Undercover Cop",
+ "Undercover Cop",
+ "Undercover Cop ",
+ "Undercover Cop",
+ "Undercover Cop",
+ "Random Guy",
+ "Bodyguard",
+ "Prostitute",
+ "Prostitute",
+ "Love Fist Guy",
+ "Ken Rosenburg",
+ "Candy Suxx",
+ "Hilary",
+ "Love Fist",
+ "Phil",
+ "Rockstar Guy",
+ "Sonny",
+ "Lance",
+ "Mercades",
+ "Love Fist",
+ "Alex Scrub",
+ "Lance Vance",
+ "Lance Vance",
+ "Cpt. Cortez",
+ "Love Fist",
+ "Columbian",
+ "Hilary",
+ "Mercades",
+ "Cam",
+ "Cam",
+ "Phil",
+ "Phil",
+ "Bodyguard",
+ "Pizza Worker",
+ "Taxi Driver",
+ "Taxi Driver",
+ "Sailor",
+ "Sailor",
+ "Sailor",
+ "Chef",
+ "Criminal",
+ "French Guy",
+ "Worker",
+ "Hatian",
+ "Waitress",
+ "Forelli Member",
+ "Forelli Member",
+ "Forelli Member",
+ "Columbian",
+ "Random Guy",
+ "Beach Guy",
+ "Random Guy",
+ "Random Guy",
+ "Random Guy",
+ "Drag Queen",
+ "Diaz Traitor",
+ "Random Guy",
+ "Random Guy",
+ "Stripper",
+ "Stripper",
+ "Stripper",
+ "Store Clerk"
+ ],
+ [ // GTA San Andreas
+ "Carl 'CJ' Johnson",
+ "The Truth",
+ "Maccer",
+ "Andre",
+ "Barry 'Big Bear' Thorne",
+ "Emmet",
+ "Taxi Driver/Train Driver",
+ "Janitor",
+ "Normal Ped",
+ "Old Woman",
+ "Casino Croupier",
+ "Rich Woman",
+ "Street Girl",
+ "Normal Ped",
+ "Mr.Whittaker (Rs Haul Owner)",
+ "Airport Ground Worker",
+ "Businessman",
+ "Beach Visitor",
+ "DJ",
+ "Rich Guy (Madd Dogg's Manager)",
+ "Normal Ped",
+ "Normal Ped",
+ "Bmxer",
+ "Madd Dogg Bodyguard",
+ "Madd Dogg Bodyguard",
+ "Backpacker",
+ "Construction Worker",
+ "Drug Dealer",
+ "Drug Dealer",
+ "Drug Dealer",
+ "Farm-Town Inhabitant",
+ "Farm-Town Inhabitant",
+ "Farm-Town Inhabitant",
+ "Farm-Town Inhabitant",
+ "Gardener",
+ "Golfer",
+ "Golfer",
+ "Normal Ped",
+ "Normal Ped",
+ "Normal Ped",
+ "Normal Ped",
+ "Jethro",
+ "Normal Ped",
+ "Normal Ped",
+ "Beach Visitor",
+ "Normal Ped",
+ "Normal Ped",
+ "Normal Ped",
+ "Snakehead (Da Nang)",
+ "Mechanic",
+ "Mountain Biker",
+ "Mountain Biker",
+ "Unknown",
+ "Normal Ped",
+ "Normal Ped",
+ "Normal Ped",
+ "Oriental Ped",
+ "Oriental Ped",
+ "Normal Ped",
+ "Normal Ped",
+ "Pilot",
+ "Colonel Fuhrberger",
+ "Prostitute",
+ "Prostitute",
+ "Kendl Johnson",
+ "Pool Player",
+ "Pool Player",
+ "Priest/Preacher",
+ "Normal Ped",
+ "Scientist",
+ "Security Guard",
+ "Hippy",
+ "Hippy",
+ "Prostitute",
+ "Stewardess",
+ "Homeless",
+ "Homeless",
+ "Homeless",
+ "Boxer",
+ "Boxer",
+ "Black Elvis",
+ "White Elvis",
+ "Blue Elvis",
+ "Prostitute",
+ "Ryder With Robbery Mask",
+ "Stripper",
+ "Normal Ped",
+ "Normal Ped",
+ "Jogger",
+ "Rich Woman",
+ "Rollerskater",
+ "Normal Ped",
+ "Normal Ped",
+ "Normal Ped",
+ "Jogger",
+ "Lifeguard",
+ "Normal Ped",
+ "Rollerskater",
+ "Biker",
+ "Normal Ped",
+ "Balla",
+ "Balla",
+ "Balla",
+ "Grove Street Families",
+ "Grove Street Families",
+ "Grove Street Families",
+ "Los Santos Vagos",
+ "Los Santos Vagos",
+ "Los Santos Vagos",
+ "The Russian Mafia",
+ "The Russian Mafia",
+ "The Russian Mafia",
+ "Varios Los Aztecas",
+ "Varios Los Aztecas",
+ "Varios Los Aztecas",
+ "Triad",
+ "Triad",
+ "Johhny Sindacco",
+ "Triad Boss",
+ "Da Nang Boy",
+ "Da Nang Boy",
+ "Da Nang Boy",
+ "The Mafia",
+ "The Mafia",
+ "The Mafia",
+ "The Mafia",
+ "Farm Inhabitant",
+ "Farm Inhabitant",
+ "Farm Inhabitant",
+ "Farm Inhabitant",
+ "Farm Inhabitant",
+ "Farm Inhabitant",
+ "Homeless",
+ "Homeless",
+ "Normal Ped",
+ "Homeless",
+ "Beach Visitor",
+ "Beach Visitor",
+ "Beach Visitor",
+ "Businesswoman",
+ "Taxi Driver",
+ "Crack Maker",
+ "Crack Maker",
+ "Crack Maker",
+ "Crack Maker",
+ "Businessman",
+ "Businesswoman",
+ "Big Smoke Armored",
+ "Businesswoman",
+ "Normal Ped",
+ "Prostitute",
+ "Construction Worker",
+ "Beach Visitor",
+ "Well Stacked Pizza Worker",
+ "Barber",
+ "Hillbilly",
+ "Farmer",
+ "Hillbilly",
+ "Hillbilly",
+ "Farmer",
+ "Hillbilly",
+ "Black Bouncer",
+ "White Bouncer",
+ "White Mib Agent",
+ "Black Mib Agent",
+ "Cluckin' Bell Worker",
+ "Hotdog/Chilli Dog Vendor",
+ "Normal Ped",
+ "Normal Ped",
+ "Blackjack Dealer",
+ "Casino Croupier",
+ "San Fierro Rifa",
+ "San Fierro Rifa",
+ "San Fierro Rifa",
+ "Barber",
+ "Barber",
+ "Whore",
+ "Ammunation Salesman",
+ "Tattoo Artist",
+ "Punk",
+ "Cab Driver",
+ "Normal Ped",
+ "Normal Ped",
+ "Normal Ped",
+ "Normal Ped",
+ "Businessman",
+ "Normal Ped",
+ "Valet",
+ "Barbara Schternvart",
+ "Helena Wankstein",
+ "Michelle Cannes",
+ "Katie Zhan",
+ "Millie Perkins",
+ "Denise Robinson",
+ "Farm-Town Inhabitant",
+ "Hillbilly",
+ "Farm-Town Inhabitant",
+ "Farm-Town Inhabitant",
+ "Hillbilly",
+ "Farmer",
+ "Farmer",
+ "Karate Teacher",
+ "Karate Teacher",
+ "Burger Shot Cashier",
+ "Cab Driver",
+ "Prostitute",
+ "Su Xi Mu (Suzie)",
+ "Oriental Noodle Stand Vendor",
+ "Oriental Boating School Instructor",
+ "Clothes Shop Staff",
+ "Homeless",
+ "Weird Old Man",
+ "Waitress (Maria Latore)",
+ "Normal Ped",
+ "Normal Ped",
+ "Clothes Shop Staff",
+ "Normal Ped",
+ "Rich Woman",
+ "Cab Driver",
+ "Normal Ped",
+ "Normal Ped",
+ "Normal Ped",
+ "Normal Ped",
+ "Normal Ped",
+ "Normal Ped",
+ "Oriental Businessman",
+ "Oriental Ped",
+ "Oriental Ped",
+ "Homeless",
+ "Normal Ped",
+ "Normal Ped",
+ "Normal Ped",
+ "Cab Driver",
+ "Normal Ped",
+ "Normal Ped",
+ "Prostitute",
+ "Prostitute",
+ "Homeless",
+ "The D.A",
+ "Afro-American",
+ "Mexican",
+ "Prostitute",
+ "Stripper",
+ "Prostitute",
+ "Stripper",
+ "Biker",
+ "Biker",
+ "Pimp",
+ "Normal Ped",
+ "Lifeguard",
+ "Naked Valet",
+ "Bus Driver",
+ "Biker Drug Dealer",
+ "Chauffeur (Limo Driver)",
+ "Stripper",
+ "Stripper",
+ "Heckler",
+ "Heckler",
+ "Construction Worker",
+ "Cab Driver",
+ "Cab Driver",
+ "Normal Ped",
+ "Clown (Ice-Cream Van Driver)",
+ "Officer Frank Tenpenny",
+ "Officer Eddie Pulaski",
+ "Officer Jimmy Hernandez",
+ "Dwaine/Dwayne",
+ "Melvin 'Big Smoke' Harris (Mission)",
+ "Sean 'Sweet' Johnson",
+ "Lance 'Ryder' Wilson",
+ "Mafia Boss",
+ "T-Bone Mendez",
+ "Paramedic",
+ "Paramedic",
+ "Paramedic",
+ "Firefighter",
+ "Firefighter",
+ "Firefighter",
+ "Los Santos Police Officer",
+ "San Fierro Police Officer",
+ "Las Venturas Police Officer",
+ "County Sheriff",
+ "Motorbike Cop",
+ "S.W.A.T.",
+ "Federal Agent",
+ "Army Soldier",
+ "Desert Sheriff",
+ "Zero",
+ "Ken Rosenberg",
+ "Kent Paul",
+ "Cesar Vialpando",
+ "Jeffery 'Og Loc' Martin/Cross",
+ "Wu Zi Mu (Woozie)",
+ "Michael Toreno",
+ "Jizzy B.",
+ "Madd Dogg",
+ "Catalina",
+ "Claude Speed"
+ ],
+ ],
+ weaponModels: [
+ [],
+ [ // GTA III
+ 0, // Fist
+ 172, // Baseball Bat
+ 173, // Colt 45
+ 178, // Uzi
+ 176, // Shotgun
+ 171, // AK-47
+ 180, // M16
+ 177, // Sniper Rifle
+ 175, // Rocket Launcher
+ 181, // Flamethrower
+ 174, // Molotov Cocktail
+ 170 // Grenade
+ ],
+ [ // GTA Vice City
+ 0,
+ 259,
+ 260,
+ 261,
+ 262,
+ 263,
+ 264,
+ 265,
+ 266,
+ 267,
+ 268,
+ 269,
+ 270,
+ 291,
+ 271,
+ 272,
+ 273,
+ 274,
+ 275,
+ 277,
+ 278,
+ 279,
+ 281,
+ 282,
+ 283,
+ 284,
+ 280,
+ 276,
+ 285,
+ 286,
+ 287,
+ 288,
+ 289,
+ 290,
+ -1,
+ -1,
+ 292
+ ],
+ [ // GTA San Andreas
+
+ ],
+ ],
+ locations: [
+ [],
+
+ [ // GTA III
+ // Police Stations
+ ["Portland Police Station", [1143.875, -675.1875, 14.97], 0.0],
+ ["Staunton Island Police Station", [340.25, -1123.375, 25.98], 0.0],
+ ["Shoreside Vale Police Station", [-1253.0, -138.1875, 58.75], 0.0],
+
+ // Hospitals
+ ["Portland Hospital", [1144.25, -596.875, 14.97], 0.0],
+ ["Staunton Island Hospital", [183.5, -17.75, 16.21], 0.0],
+ ["Shoreside Vale Hospital", [-1259.5, -44.5, 58.89], 0.0],
+
+ // Fire Stations
+ ["Portland Fire Station", [1103.70, -52.45, 7.49], 0.0],
+ ["Staunton Island Fire Station", [-78.48, -436.80, 16.17], 0.0],
+ ["Shoreside Vale Fire Station", [-1202.10, -14.67, 53.20], 0.0],
+
+ // Pay and Sprays
+ ["Portland Pay and Spray", [925.4, -360.3, 10.83], 0.0],
+ ["Staunton Island Pay and Spray", [381.8, -493.8, 25.95], 0.0],
+ ["Shoreside Vale Pay and Spray", [-1142.4, 35.01, 58.61], 0.0],
+
+ // Ammunations
+ ["Portland Ammunation", [1068.3, -400.9, 15.24], 0.0],
+ ["Staunton Island Ammunation", [348.2, -717.9, 26.43], 0.0],
+
+ // Train Stations
+ ["Bedford Point Train Station", [178.52, -1551.40, 26.162], -3.105],
+ ["Francis International Airport Train Station", [-633.42, -760.06, 18.919], 1.586],
+ ["Rockford Train Station", [225.66, -69.07, 20.998], -3.115],
+ ["Saint Marks Train Station", [1306.69, -512.38, 40.078], -2.458],
+ ["Hepburn Heights Train Station", [1029.07, -164.18, 4.972], 0.005],
+ ["Chinatown Train Station", [775.27, -622.28, 14.747], 0.006],
+
+ // Safehouses
+ ["Portland Safehouse", [885.52, -308.47, 8.615], -1.532],
+
+ // Other
+ ["St Mathias College", [201.59, -281.42, 15.779], -0.005],
+ ["Newport Parking Garage", [294.22, -547.87, 25.780], 3.119],
+ ["City Hall", [96.60, -951.61, 26.168], 3.138],
+ ["Belleville Park East", [109.15, -695.76, 26.168], 1.594],
+ ["Belleville Park Bathroom", [38.69, -724.96, 22.756], -3.104],
+ ["Belleville Park West", [0.40, -773.05, 26.056], -1.476],
+ ["Stadium Entrance", [-18.65, -231.80, 29.861], 0.002],
+ ["Kenji's Casino", [454.10, -1421.26, 26.124], -0.769],
+ ["Saint Marks Bistro", [1345.48, -457.41, 49.549], 1.537],
+ ["Leone Mansion", [1417.94, -194.18, 49.905], -1.570],
+ ["Ciprianis Ristorante", [1202.50, -320.78, 24.973], -1.553],
+ ["Luigi's Club", [904.82, -425.37, 14.929], 1.602],
+ ["Portland Fuel Station", [1157.34, -75.45, 7.065], -0.027],
+ ["Easy Credit Autos", [1217.81, -113.87, 14.973], -3.051],
+ ["Head Radio Headquarters", [986.40, -46.40, 7.473], -1.615],
+ ["Borgnine Taxi Headquarters", [929.36, -48.59, 7.473], -2.935],
+ ["Fuzz Ball", [1000.03, -877.82, 14.547], -3.136],
+ ["Portland Docks Entrance", [1360.55, -818.08, 14.415], -1.574],
+ ["Punk Noodle Diner", [1040.10, -653.10, 14.973], 1.551],
+ ["Greasy Joe's Diner", [864.45, -999.86, 4.646], -0.020],
+ ],
+
+ [ // GTA VC
+ // Police Stations
+ ["Washington Beach Police Station", [399.77, -468.90, 11.73], 0.0],
+ ["Vice Point Police Station", [508.96, 512.07, 12.10], 0.0],
+ ["Downtown Police Station", [-657.43, 762.31, 11.59], 0.0],
+ ["Little Havana Police Station", [-885.08, -470.44, 13.11], 0.0],
+
+ // Hospitals
+ ["Downtown Hospital", [-822.57, 1152.82, 12.41], 0.0],
+ ["Little Havana Medical Center", [-885.08, -470.44, 13.11], 0.0],
+ ["Ocean Beach Hospital", [-133.19, -980.76, 10.46], 0.0],
+ ],
+
+ [ // GTA SA
+ // Coming Soon!
+ ],
+
+ [ // GTA UG
+ // Coming Soon!
+ ],
+
+ [ // GTA IV
+ // Police Stations
+ ["Broker Police Station", [894.99, -357.39, 18.185], 2.923],
+ ["South Bohan Police Station", [435.40, 1592.29, 17.353], 3.087],
+ ["Northern Gardens Police Station", [974.93, 1870.45, 23.073], -1.621],
+ ["South Slopes Police Station", [1233.25, -89.13, 28.034], 1.568],
+ ["Middle Part East Police Station", [50.12, 679.88, 15.316], 1.569],
+ ["East Holland Police Station", [85.21, 1189.82, 14.755], 3.127],
+ ["Francis International Airport Police Station", [2170.87, 448.87, 6.085], 1.501],
+ ["Chinatown Police Station", [213.12, -211.70, 10.752], 0.200],
+ ["Acter Police Station", [-1714.95, 276.31, 22.134], 1.127],
+ ["Port Tudor Police Station", [-1220.73, -231.53, 3.024], 2.210],
+ ["Leftwood Police Station", [-927.66, 1263.63, 24.587], -0.913],
+
+ // Fire Stations
+ ["Broker Fire Station", [953.13, 95.90, 35.004], 1.595],
+ ["Northwood Fire Station", [-271.02, 1542.15, 20.420], -1.160],
+ ["Northern Gardens Fire Station", [1120.47, 1712.36, 10.534], -0.682],
+ ["Francis International Airport Fire Station", [2364.87, 166.83, 5.813], 0.156],
+ ["Chinatown Fire Station", [295.40, -336.88, 4.963], 2.887],
+ ["Berchem Fire Station", [-1574.90, 546.54, 25.449], -0.509],
+ ["Tudor Fire Station", [-2144.97, 164.15, 12.051], -2.149],
+
+ // Safehouses
+ ["Hove Beach Safehouse Parking", [904.27, -498.00, 14.522], 3.127],
+ ["South Bohan Safehouse", [589.42, 1402.15, 10.364], 0.007],
+
+ // Hospitals
+ ["Schottler Medical Center", [1199.59, 196.78, 33.554], 1.633],
+ ["Northern Gardens Medical Center", [980.71, 1831.61, 23.898], -0.049],
+ ["Leftwood Hospital", [-1317.27, 1277.20, 22.370], 2.246],
+ ["Acter Medical Center", [-1538.43, 344.58, 20.943], -0.156],
+
+ // Fuel Stations
+ ["Hove Beach Fuel Station", [1128.51, -359.55, 18.441], -0.052],
+ ["Lancaster Fuel Station", [108.37, 1135.13, 13.975], 0.007],
+ ["The Meat Quarter Fuel Station", [-434.30, -19.47, 9.864], 1.469],
+ ["Cerveza Heights Fuel Station", [1123.50, 328.84, 29.245], -0.154],
+ ["Tudor Fuel Station", [-1389.91, 29.19, 6.875], 0.982],
+
+ // Restaurants
+ ["Star Junction Burger Shot", [-174.00, 276.96, 14.818], -0.029],
+ ["South Bohan Burger Shot", [441.95, 1516.64, 16.289], -2.682],
+ ["Industrial Burger Shot", [1096.93, 1598.33, 16.721], -2.289],
+
+ // Night Clubs/Strip Clubs/Bars
+ ["Perestroika Club", [957.58, -292.58, 19.644], -0.009],
+ ["Triangle Club", [1210.90, 1718.18, 16.667], 1.819],
+
+ // TW@ Cafes
+ ["Outlook Internet Cafe", [977.42, -169.11, 24.013], 1.844],
+ ["Berchem Internet Cafe", [-1584.46, 466.05, 25.398], -2.441],
+
+ // Pay-n-Sprays
+ ["Hove Beach Pay-n-Spray", [1058.57, -282.58, 20.760], -3.135],
+ ["Leftwood Pay-n-Spray", [-1148.69, 1171.52, 16.457], -0.059],
+
+ // Clothes Shops
+ ["Hove Beach Russian Clothes Shop", [896.31, -442.59, 15.888], 1.500],
+
+ // Car Wash
+ ["Willis Car Wash", [1831.02, 360.20, 22.061], -1.515],
+ ["Tudor Car Wash", [-1371.68, 35.13, 7.028], 1.029],
+
+ // Gun Shops
+ ["Downtown Broker Gun Shop", [1054.11, 86.84, 33.408], -1.574],
+ ["Chinatown Gun Shop", [65.43, -342.36, 14.767], -1.589],
+ ["Port Tudor Gun Shop", [-1338.77, 307.61, 13.378], -1.530],
+
+ // Train Stations
+ ["Hove Beach Train Station", [1000.41, -544.82, 14.854], -1.576],
+ ["Schottler Train Station", [1303.93, -37.75, 28.377], 3.065],
+ ["Cerveza Heights Train Station", [1386.87, 374.13, 23.063], 3.111],
+ ["Lynch Street Train Station", [1594.73, 364.80, 25.226], -0.965],
+ ["East Park Train Station", [-35.78, 634.79, 14.663], -0.050],
+ ["West Park Train Station", [-377.13, 677.05, 14.679], -0.069],
+ ["North Park Train Station", [-135.08, 1153.95, 14.773], -1.567],
+ ["Vespucci Circus Train Station", [-85.11, 1427.04, 20.421], 1.501],
+ ["Frankfort Low Train Station", [-331.94, 1427.05, 12.617], 1.541],
+ ["Frankfort High Train Station", [-343.79, 1433.12, 12.283], 0.113],
+ ["Vauxite Train Station", [-483.38, 1333.91, 17.481], 1.509],
+ ["Quartz Street West Train Station", [-545.54, 926.22, 9.945], -1.524],
+ ["Manganese West Train Station", [-461.60, 530.56, 9.857], 3.091],
+ ["Frankfort Ave Train Station", [-377.52, 371.91, 14.762], -3.125],
+ ["Suffolk Train Station", [-252.77, -171.83, 14.447], 1.594],
+ ["Feldspar Train Station", [-350.62, -335.35, 4.909], -2.287],
+ ["City Hall Train Station", [-115.31, -501.22, 14.755], -1.365],
+ ["Castle Gardens Train Station", [82.95, -757.81, 4.965], -1.006],
+ ["Emerald Train Station", [116.57, -318.15, 14.768], 1.499],
+ ["Easton Train Station", [-35.76, -18.50, 14.769], 3.137],
+ ["Manganese East Train Station", [131.46, 522.74, 14.661], 0.005],
+ ["Quartz Street East Train Station", [134.35, 910.15, 14.717], -0.112],
+ ["San Quentin Ave Train Station", [373.12, 1625.93, 16.347], -2.249],
+ ["Windmill Street Train Station", [749.97, 1447.44, 14.252], -0.120],
+ ["Francis International Airport Train Station", [2297.57, 474.62, 6.086], 0.066],
+
+ // Misc
+ ["Hove Beach Laundromat", [1011.74, -325.33, 20.339], -1.402],
+ ["The Exchange Docks", [-354.68, -661.62, 4.791], 2.066],
+ ["Firefly Island Bowling", [1198.99, -681.49, 16.445], -0.017],
+ ["Broker Bus Depot", [1004.15, 279.19, 31.512], -2.193],
+ ["The Lost MC Clubhouse", [-1713.29, 358.25, 25.449], 2.566],
+ ["Alderney State Correctional Facility", [-1155.21, -374.34, 2.885], -1.680],
+ ["Chinatown Bank of Liberty", [-34.92, -466.80, 14.75], -1.52],
+ ["Suffolk Church", [-274.30, -281.63, 14.36], 1.56],
+
+ // More will be added soon!
+ ],
+
+ [ // GTA EFLC
+ // Police Stations
+ ["Broker Police Station", [894.99, -357.39, 18.185], 2.923],
+ ["South Bohan Police Station", [435.40, 1592.29, 17.353], 3.087],
+ ["Northern Gardens Police Station", [974.93, 1870.45, 23.073], -1.621],
+ ["South Slopes Police Station", [1233.25, -89.13, 28.034], 1.568],
+ ["Middle Part East Police Station", [50.12, 679.88, 15.316], 1.569],
+ ["East Holland Police Station", [85.21, 1189.82, 14.755], 3.127],
+ ["Francis International Airport Police Station", [2170.87, 448.87, 6.085], 1.501],
+ ["Chinatown Police Station", [213.12, -211.70, 10.752], 0.200],
+ ["Acter Police Station", [-1714.95, 276.31, 22.134], 1.127],
+ ["Port Tudor Police Station", [-1220.73, -231.53, 3.024], 2.210],
+ ["Leftwood Police Station", [-927.66, 1263.63, 24.587], -0.913],
+
+ // Fire Stations
+ ["Broker Fire Station", [953.13, 95.90, 35.004], 1.595],
+ ["Northwood Fire Station", [-271.02, 1542.15, 20.420], -1.160],
+ ["Northern Gardens Fire Station", [1120.47, 1712.36, 10.534], -0.682],
+ ["Francis International Airport FIre Station", [2364.87, 166.83, 5.813], 0.156],
+ ["Chinatown Fire Station", [295.40, -336.88, 4.963], 2.887],
+ ["Berchem Fire Station", [-1574.90, 546.54, 25.449], -0.509],
+ ["Tudor Fire Station", [-2144.97, 164.15, 12.051], -2.149],
+
+ // Safehouses
+ ["Hove Beach Safehouse Parking", [904.27, -498.00, 14.522], 3.127],
+ ["South Bohan Safehouse", [589.42, 1402.15, 10.364], 0.007],
+
+ // Hospitals
+ ["Schottler Medical Center", [1199.59, 196.78, 33.554], 1.633],
+ ["Northern Gardens Medical Center", [980.71, 1831.61, 23.898], -0.049],
+ ["Leftwood Hospital", [-1317.27, 1277.20, 22.370], 2.246],
+ ["Acter Medical Center", [-1538.43, 344.58, 20.943], -0.156],
+
+ // Fuel Stations
+ ["Hove Beach Fuel Station", [1128.51, -359.55, 18.441], -0.052],
+ ["Lancaster Fuel Station", [108.37, 1135.13, 13.975], 0.007],
+ ["The Meat Quarter Fuel Station", [-434.30, -19.47, 9.864], 1.469],
+ ["Cerveza Heights Fuel Station", [1123.50, 328.84, 29.245], -0.154],
+ ["Tudor Fuel Station", [-1389.91, 29.19, 6.875], 0.982],
+
+ // Restaurants
+ ["Star Junction Burger Shot", [-174.00, 276.96, 14.818], -0.029],
+ ["South Bohan Burger Shot", [441.95, 1516.64, 16.289], -2.682],
+ ["Industrial Burger Shot", [1096.93, 1598.33, 16.721], -2.289],
+
+ // Night Clubs/Strip Clubs/Bars
+ ["Perestroika Club", [957.58, -292.58, 19.644], -0.009],
+ ["Triangle Club", [1210.90, 1718.18, 16.667], 1.819],
+
+ // TW@ Cafes
+ ["Outlook Internet Cafe", [977.42, -169.11, 24.013], 1.844],
+ ["Berchem Internet Cafe", [-1584.46, 466.05, 25.398], -2.441],
+
+ // Pay-n-Sprays
+ ["Hove Beach Pay-n-Spray", [1058.57, -282.58, 20.760], -3.135],
+ ["Leftwood Pay-n-Spray", [-1148.69, 1171.52, 16.457], -0.059],
+
+ // Clothes Shops
+ ["Hove Beach Russian Clothes Shop", [896.31, -442.59, 15.888], 1.500],
+
+ // Car Wash
+ ["Willis Car Wash", [1831.02, 360.20, 22.061], -1.515],
+ ["Tudor Car Wash", [-1371.68, 35.13, 7.028], 1.029],
+
+ // Gun Shops
+ ["Downtown Broker Gun Shop", [1054.11, 86.84, 33.408], -1.574],
+ ["Chinatown Gun Shop", [65.43, -342.36, 14.767], -1.589],
+ ["Port Tudor Gun Shop", [-1338.77, 307.61, 13.378], -1.530],
+
+ // Train Stations
+ ["Hove Beach Train Station", [1000.41, -544.82, 14.854], -1.576],
+ ["Schottler Train Station", [1303.93, -37.75, 28.377], 3.065],
+ ["Cerveza Heights Train Station", [1386.87, 374.13, 23.063], 3.111],
+ ["Lynch Street Train Station", [1594.73, 364.80, 25.226], -0.965],
+ ["East Park Train Station", [-35.78, 634.79, 14.663], -0.050],
+ ["West Park Train Station", [-377.13, 677.05, 14.679], -0.069],
+ ["North Park Train Station", [-135.08, 1153.95, 14.773], -1.567],
+ ["Vespucci Circus Train Station", [-85.11, 1427.04, 20.421], 1.501],
+ ["Frankfort Low Train Station", [-331.94, 1427.05, 12.617], 1.541],
+ ["Frankfort High Train Station", [-343.79, 1433.12, 12.283], 0.113],
+ ["Vauxite Train Station", [-483.38, 1333.91, 17.481], 1.509],
+ ["Quartz Street West Train Station", [-545.54, 926.22, 9.945], -1.524],
+ ["Manganese West Train Station", [-461.60, 530.56, 9.857], 3.091],
+ ["Frankfort Ave Train Station", [-377.52, 371.91, 14.762], -3.125],
+ ["Suffolk Train Station", [-252.77, -171.83, 14.447], 1.594],
+ ["Feldspar Train Station", [-350.62, -335.35, 4.909], -2.287],
+ ["City Hall Train Station", [-115.31, -501.22, 14.755], -1.365],
+ ["Castle Gardens Train Station", [82.95, -757.81, 4.965], -1.006],
+ ["Emerald Train Station", [116.57, -318.15, 14.768], 1.499],
+ ["Easton Train Station", [-35.76, -18.50, 14.769], 3.137],
+ ["Manganese East Train Station", [131.46, 522.74, 14.661], 0.005],
+ ["Quartz Street East Train Station", [134.35, 910.15, 14.717], -0.112],
+ ["San Quentin Ave Train Station", [373.12, 1625.93, 16.347], -2.249],
+ ["Windmill Street Train Station", [749.97, 1447.44, 14.252], -0.120],
+ ["Francis International Airport Train Station", [2297.57, 474.62, 6.086], 0.066],
+
+ // Misc
+ ["Hove Beach Laundromat", [1011.74, -325.33, 20.339], -1.402],
+ ["The Exchange Docks", [-354.68, -661.62, 4.791], 2.066],
+ ["Firefly Island Bowling", [1198.99, -681.49, 16.445], -0.017],
+ ["Broker Bus Depot", [1004.15, 279.19, 31.512], -2.193],
+ ["The Lost MC Clubhouse", [-1713.29, 358.25, 25.449], 2.566],
+ ["Alderney State Correctional Facility", [-1155.21, -374.34, 2.885], -1.680],
+ ["Chinatown Bank of Liberty", [-34.92, -466.80, 14.75], -1.52],
+ ["Suffolk Church", [-274.30, -281.63, 14.36], 1.56],
+
+ // More will be added soon!
+ ],
+ ],
+ gtaivSkinModels: [
+ //["Nico Bellic", 1862763509],
+ ["Male Multiplayer", -2020305438],
+ ["Female Multiplayer", -641875910],
+ ["MODEL_SUPERLOD", -1370810922],
+ ["Anna", 1853617247],
+ ["Anthony", -1646893330],
+ ["Badman", 1495769888],
+ ["Bernie Crane", 1500493064],
+ ["Bledar", 1731510984],
+ ["Brian", 422305098],
+ ["Brucie", -1729980128],
+ ["Bulgarin", 237511807],
+ ["Charise", 88667657],
+ ["Charlie Undercover", -1328445565],
+ ["Clarence", 1343144208],
+ ["Dardan", 1468450703],
+ ["Darko", 386513184],
+ ["Derric", 1169442297],
+ ["Dmitri", 237497537],
+ ["Dwayne", -617264103],
+ ["Eddie", -1600585231],
+ ["Faustin", 57218969],
+ ["Francis", 1710545037],
+ ["French Tom", 1424670436],
+ ["Gordon", 2129490787],
+ ["Gracie", -357652594],
+ ["Hossan", 980768434],
+ ["Ilyena", -835225126],
+ ["Issac", -479595866],
+ ["Ivan", 1166762483],
+ ["Jay", 364686627],
+ ["Jason", 170756246],
+ ["Jeff", 390357829],
+ ["Jimmy", -366421228],
+ ["Johnny Klebitz", -911507684],
+ ["Kate", -773750838],
+ ["Kenny", 995576506],
+ ["Lil Jacob", 1487004273],
+ ["Lil Jacob 2", -1275031987],
+ ["Luca", -681942840],
+ ["Luis", -492470690],
+ ["Mallorie", -1040287406],
+ ["Mam", -322700377],
+ ["Manny", 1445589009],
+ ["Marnie", 411185872],
+ ["Mel", -807339118],
+ ["Michael", 735211577],
+ ["Michelle", -1080659212],
+ ["Mickey", -636669566],
+ ["Packie", 1690783035],
+ ["Pathos", -165448092],
+ ["Petrovic", -1947682830],
+ ["Phil Bell", -1826458934],
+ ["Playboy X", 1794146792],
+ ["Ray Boccino", 954215094],
+ ["Ricky", -587324132],
+ ["Roman", -1992728631],
+ ["Roman 2", 558221221],
+ ["Sarah", -17823883],
+ ["Tuna", 1384833284],
+ ["Vinny Spaz", -1014976873],
+ ["Vlad", 896408642],
+ ["Black Street Thug 1", -301223260],
+ ["Black Street Thug 2", -1143910864],
+ ["Black Street OG 1", 869501081],
+ ["Black Street OG 1", 632613980],
+ ["Albanian Thug 1", -503930010],
+ ["Albanian Thug 2", -235584669],
+ ["Albanian Thug 3", 207714363],
+ ["Albanian Thug 4", 514268366],
+ ["Biker 1", 43005364],
+ ["Biker 2", 1346668127],
+ ["Biker 3", -1677255197],
+ ["Biker 4", -1461281345],
+ ["Biker 5", 1574850459],
+ ["Biker 6", -1953289472],
+ ["Irish Man 1", 280474699],
+ ["Irish Man 2", -19263344],
+ ["Irish Man 3", 1844702918],
+ ["Jamaican OG 1", 1609755055],
+ ["Jamaican OG 2", -330497431],
+ ["Jamaican OG 3", 1117105909],
+ ["Jamaican Thug 1", -1500397869],
+ ["Jamaican Thug 2", -881358690],
+ ["Asian Man 1", 1540383669],
+ ["Asian Man 2", 764249904],
+ ["Hispanic Man 1", 492147228],
+ ["Hispanic Man 2", -1926041127],
+ ["Hispanic Man 3", 1168388225],
+ ["Hispanic Man 4", -1746774780],
+ ["Fat Italian Mafia Boss", -302362397],
+ ["Italian Mafia Boss", -1616890832],
+ ["Italian Mafia Associate", 64730935],
+ ["Fat Italian Mafia Associate", 510389335],
+ ["Russian Thug 1", -1836006237],
+ ["Russian Thug 2", -2088164056],
+ ["Russian Thug 3", 1976502708],
+ ["Russian Thug 4", 1543404628],
+ ["Russian Thug 5", 1865532596],
+ ["Russian Thug 6", 431692232],
+ ["Russian Thug 7", 1724587620],
+ ["Russian Thug 8", -1180674815],
+ ["Triad Boss 1", 871281791],
+ ["Triad Boss 2", 683712035],
+ ["Triad Member 3", -1084007777],
+ ["Triad Member 4", -164935626],
+ ["Female Maid", -751071255],
+ ["Female Binco Worker", -109247258],
+ ["Female Bank Teller", 1366257926],
+ ["Female Doctor", 346338575],
+ ["Female Gym Worker", 1350216795],
+ ["Female Burger Shot Worker", 924926104],
+ ["Female Cluckin Bell Worker", -346378101],
+ ["Female Rockstar Cafe Worker", -2104311883],
+ ["Female TW@ Cafe Worker", 212900845],
+ ["Female Well Stacked Pizza Worker", -290070895],
+ ["Hooker", 552542187],
+ ["Hooker 2", 996267216],
+ ["Nurse", -1193778389],
+ ["Stripper 1", 1113677074],
+ ["Stripper 2", 1353709999],
+ ["Waitress", 24233425],
+ ["Alcoholic Man", -1761003415],
+ ["Armoured Truck Driver", 1075583233],
+ ["Bus Driver", 134077503],
+ ["Generic Asian Man", 757349871],
+ ["Black Crackhead", -1827421800],
+ ["Doctor (Scrubs)", 219393781],
+ ["Doctor", -1186940778],
+ ["Doctor (Blood Covered Coat)", 375732086],
+ ["Cook", 2105015949],
+ ["Italian Mob Enforcer", -200234085],
+ ["Factory Worker", 800131009],
+ ["FIB Agent", -999506922],
+ ["Fat Delivery Driver", -1993909080],
+ ["Fire Chief", 610888851],
+ ["Mercenary Soldier", 486302863],
+ ["Helicopter Pilot", -778316080],
+ ["Hotel Doorman", 624314380],
+ ["Korean Cook", -1784833142],
+ ["Lawyer 1", -1852976689],
+ ["Lawyer 2", -1134712978],
+ ["Loony Black Man", 379171768],
+ ["Pilot", -1945168882],
+ ["Generic Man", 807236245],
+ ["Postal Worker", -284362863],
+ ["Saxophone Player", -1188246269],
+ ["Security Guard", -1870989171],
+ ["Stadium Food Vendor", 420915580],
+ ["Stadium Food Cook", 1878085135],
+ ["Street Food Vendor", 142730876],
+ ["Street Sweeper Driver", -690681764],
+ ["Taxi Driver", 8772846],
+ ["Telephone Company Worker", 1186270890],
+ ["Tennis Player", -379234846],
+ ["Train Conductor", 1159759556],
+ ["Homeless Black Man", -142386662],
+ ["Trucker", -46564867],
+ ["Janitor", -1284047560],
+ ["Hotel Doorman 2", 22944263],
+ ["Mob Boss", 1178487645],
+ ["Airport Worker", -1464712858],
+ ["Bartender", -2139064254],
+ ["Biker Bouncer", -1780698891],
+ ["High End Club Bouncer", -409283472],
+ ["Bowling Alley Worker", -799229885],
+ ["Bowling Alley Worker 2", -434183225],
+ ["Chinese Food Vendor", 768442188],
+ ["Club Security", 676448572],
+ ["Construction Worker", -722019798],
+ ["Construction Worker 2", -1015957728],
+ ["Construction Worker 3", -714220780],
+ ["Police Officer", -183203150],
+ ["Traffic Officer", -1518937979],
+ ["Fat Police Officer", -370395528],
+ ["Courier", -1371133859],
+ ["Cowboy 1", -573788283],
+ ["Drug Dealer 1", -1283406538],
+ ["Drug Dealer 2", 1448755353],
+ ["Male Burger Shot Worker", 989485],
+ ["Male Cluckin Bell Worker", -1011530423],
+ ["Male Rockstar Cafe Worker", 1979561477],
+ ["Male TW@ Cafe Worker", -786449781],
+ ["Male Well Stacked Pizza Worker", 206941425],
+ ["Firefighter", -610224615],
+ ["Garbage Collector", 1136499716],
+ ["Goon", 897868981],
+ ["Male Gym Worker", -1902758612],
+ ["Mechanic 2", -356904519],
+ ["Male Modo Worker", -1056268969],
+ ["Helicopter Pilot", 1201610759],
+ ["Perseus", -151000142],
+ ["Generic Male 1", 501136335],
+ ["Generic Male 2", 186619473],
+ ["Generic Male 3", -111611196],
+ ["Paramedic", -1175077216],
+ ["Prisoner", -1676937780],
+ ["Prisoner 2", 215190023],
+ ["Roman's Taxi Service Driver", 1552970117],
+ ["Male Runner", -1481923910],
+ ["Male Shop Assistant 1", 357919731],
+ ["State Trooper", -89302119],
+ ["SWAT", -1004762946],
+ ["Sword Swallower", -64233032],
+ ["Thief", -1292254815],
+ ["Valet", 271284208],
+ ["Vendor", -186113957],
+ ["French Tom", -2015686009],
+ ["Jim Fitz", 1977784957],
+ ["East European Woman", -203833294],
+ ["East European Woman 2", 189853472],
+ ["Woman", -349043578],
+ ["Jersey Woman", -114937692],
+ ["Oriental Woman", -1697333660],
+ ["Rich Woman", 100706569],
+ ["Business Woman 1", 155063868],
+ ["Business Woman 2", 394310337],
+ ["Chinatown Woman", 1375728805],
+ ["Business Woman 3", -284229525],
+ ["East European Woman 3", 677687516],
+ ["Fat Black Woman", -1188238883],
+ ["Jersey Woman 1", -2075220936],
+ ["Jersey Woman 2", -1356924456],
+ ["Fat Hispanic Woman 1", 812112483],
+ ["Fat Hispanic Woman 2", -129242580],
+ ["White Manhattan Woman", 852423121],
+ ["Black Manhattan Woman", 76551508],
+ ["Old Asian Woman", -2118501976],
+ ["Old Rich Woman", 1616769823],
+ ["Business Woman 4", 453889158],
+ ["Asian Woman in Dress", 824245375],
+ ["Fat Black Bronx Woman", -1362442041],
+ ["Random White Woman", -1788328884],
+ ["Random Hispanic Woman", -1523915823],
+ ["Random Eastern European Woman", -949987237],
+ ["Random Black Woman", -1926577323],
+ ["Black Harlem Woman 1", 168065679],
+ ["Fat Jersey Woman 1", 441464],
+ ["Fat Hispanic Woman 3", 54114008],
+ ["Hispanic Woman 1", -292713088],
+ ["Hispanic Woman 2", 1743814728],
+ ["Manhattan Woman 1", 1670568326],
+ ["Manhattan Woman 2", 1354281938],
+ ["Manhattan Woman 1", 1056837725],
+ ["Asian Woman 1", -1193633577],
+ ["Black Woman 2", 713691120],
+ ["Rich White Woman 1", -1780385799],
+ ["Asian Woman", -952185135],
+ ["Female Shopper 1", 1586287288],
+ ["Female Shopper 2", 1848013291],
+ ["Female Shopper 3", -1702036227],
+ ["Female Socialite 1", 1182843182],
+ ["Street Woman 1", -900623157],
+ ["Street Woman 2", 286007875],
+ ["Street Woman 3", 1473654742],
+ ["Street Woman 4", -1850743775],
+ ["Street Woman 5", 1290755317],
+ ["Street Woman 6", 1872110126],
+ ["Tourist Woman 1", 1754440500],
+ ["MODEL_F_Y_VILLBO_01", 761763258],
+ ["Business Man 1", -636579119],
+ ["Business Man 2", -1754526315],
+ ["Street Criminal 1", -1516474414],
+ ["Street Criminal 2", -1821258883],
+ ["Obese Mafia Thug", 1952671026],
+ ["Gay Man 1", -1991603022],
+ ["Homeless Bum 1", -1080673049],
+ ["Loony White Man 1", 495499562],
+ ["MODEL_M_M_MIDTOWN_01", -1984134881],
+ ["Business Man 2", 1063816580],
+ ["Eastern European Man 1", 208763854],
+ ["Fat Black Man 2", -1020237172],
+ ["MODEL_M_M_PINDUS_02", 1782277836],
+ ["Fat Italian Man 1", -1402442039],
+ ["Italian Man 2", -1628417063],
+ ["Hispanic Man 1", 1158569407],
+ ["Hispanic Man 2", 1969438324],
+ ["Hispanic Man 3", 1621955848],
+ ["Tourist Man 1", -657489059],
+ ["Black Business Man 1", -1307068958],
+ ["Asian Man 3", 734334931],
+ ["MODEL_M_M_PRICH_01", 1865082075],
+ ["MODEL_M_O_EASTEURO_01", -432593815],
+ ["Hasidic Jewish Man 1", -1639359785],
+ ["Old Man 1", 1656087115],
+ ["MODEL_M_O_PEASTEURO_02", 2034185905],
+ ["MODEL_M_O_PHARBRON_01", 1316404726],
+ ["MODEL_M_O_PJERSEY_01", 980990533],
+ ["MODEL_M_O_STREET_01", -1298691925],
+ ["Old Business Man", 243672348],
+ ["MODEL_M_Y_BOHO_01", 2085884255],
+ ["MODEL_M_Y_BOHOGUY_01", 221246143],
+ ["MODEL_M_Y_BRONX_01", 52357603],
+ ["Black Business Man 2", 1530937394],
+ ["Black Business Man 3", 690281432],
+ ["Asian Man 4", -1149743642],
+ ["Chopshop Mechanic 1", -314369597],
+ ["Chopshop Mechanic 2", -552829610],
+ ["MODEL_M_Y_DODGY_01", -1097188138],
+ ["MODEL_M_Y_DORK_02", -1775659292],
+ ["MODEL_M_Y_DOWNTOWN_01", 1207402441],
+ ["MODEL_M_Y_DOWNTOWN_02", 1500619449],
+ ["MODEL_M_Y_DOWNTOWN_03", 594261682],
+ ["MODEL_M_Y_GAYYOUNG", -747824291],
+ ["MODEL_M_Y_GENSTREET_11", -677160979],
+ ["MODEL_M_Y_GENSTREET_16", -1678614360],
+ ["MODEL_M_Y_GENSTREET_20", 989044076],
+ ["MODEL_M_Y_GENSTREET_34", 1180218190],
+ ["MODEL_M_Y_HARDMAN_01", -1420592428],
+ ["MODEL_M_Y_HARLEM_01", -1222963415],
+ ["MODEL_M_Y_HARLEM_02", -1746153269],
+ ["MODEL_M_Y_HARLEM_04", 2104499156],
+ ["Hasidic Jewish Man 2", -1874580889],
+ ["MODEL_M_Y_LEASTSIDE_01", -1055386282],
+ ["MODEL_M_Y_PBRONX_01", 575808580],
+ ["MODEL_M_Y_PCOOL_01", -71980543],
+ ["MODEL_M_Y_PCOOL_02", -195159218],
+ ["MODEL_M_Y_PEASTEURO_01", 697247370],
+ ["MODEL_M_Y_PHARBRON_01", 670406267],
+ ["MODEL_M_Y_PHARLEM_01", 26615298],
+ ["MODEL_M_Y_PJERSEY_01", 1542927558],
+ ["MODEL_M_Y_PLATIN_01", -1806886352],
+ ["MODEL_M_Y_PLATIN_02", -1022920796],
+ ["MODEL_M_Y_PLATIN_03", -1326394505],
+ ["MODEL_M_Y_PMANHAT_01", 607901190],
+ ["MODEL_M_Y_PMANHAT_02", 1968470106],
+ ["MODEL_M_Y_PORIENT_01", -344136289],
+ ["MODEL_M_Y_PQUEENS_01", 560413584],
+ ["MODEL_M_Y_PRICH_01", 1352017873],
+ ["MODEL_M_Y_PVILLBO_01", 223726252],
+ ["MODEL_M_Y_PVILLBO_02", -1252681043],
+ ["MODEL_M_Y_PVILLBO_03", -1562020391],
+ ["MODEL_M_Y_QUEENSBRIDGE", 1223224881],
+ ["MODEL_M_Y_SHADY_02", -1220737489],
+ ["MODEL_M_Y_SKATEBIKE_01", 1755322862],
+ ["MODEL_M_Y_SOHO_01", 386690478],
+ ["MODEL_M_Y_STREET_01", 62496225],
+ ["MODEL_M_Y_STREET_03", 523785438],
+ ["MODEL_M_Y_STREET_04", 813889395],
+ ["MODEL_M_Y_STREETBLK_02", -1552214124],
+ ["MODEL_M_Y_STREETBLK_03", -650575089],
+ ["Street Punk 1", -740078918],
+ ["Street Punk 2", -1927496394],
+ ["Street Punk 3", 1374242512],
+ ["Tough Guy", -1139941790],
+ ["Male Tourist", 809067472],
+ ],
+ gtaivVehicleModels: [
+ ["Admiral", 1264341792],
+ ["Airtug", 1560980623],
+ ["Ambulance", 1171614426],
+ ["Banshee", -1041692462],
+ ["Benson", 2053223216],
+ ["Biff", 850991848],
+ ["Blista", -344943009],
+ ["Bobcat", 1075851868],
+ ["Boxville", -1987130134],
+ ["Buccaneer", -682211828],
+ ["Burrito", -1346687836],
+ ["Burrito 2", -907477130],
+ ["Bus", -713569950],
+ ["Cabby", 1884962369],
+ ["Cavalcade", 2006918058],
+ ["Chavos", -67282078],
+ ["Cognoscenti", -2030171296],
+ ["Comet", 1063483177],
+ ["Coquette", 108773431],
+ ["DF8", 162883121],
+ ["Dillettante", -1130810103],
+ ["Dukes", 723973206],
+ ["E109", -1971955454],
+ ["Emperor", -685276541],
+ ["Rusty Emperor", -1883002148],
+ ["Esperanto", -276900515],
+ ["Faction", -2119578145],
+ ["FIB Car", 1127131465],
+ ["Feltzer", -1097828879],
+ ["Feroci", 974744810],
+ ["Airport Feroci", 1026055242],
+ ["Firetruck", 1938952078],
+ ["Flatbed", 1353720154],
+ ["Fortune", 627033353],
+ ["Forklift", 1491375716],
+ ["Futo", 2016857647],
+ ["FXT", 675415136],
+ ["Habanero", 884422927],
+ ["Hakumai", -341892653],
+ ["Huntley", 486987393],
+ ["Infernus", 418536135],
+ ["Ingot", -1289722222],
+ ["Intruder", 886934177],
+ ["Landstalker", 1269098716],
+ ["Lokus", -37030056],
+ ["Manana", -2124201592],
+ ["Marbella", 1304597482],
+ ["Merit", -1260881538],
+ ["Minivan", -310465116],
+ ["Moonbeam", 525509695],
+ ["Mr. Tasty", 583100975],
+ ["Mule", 904750859],
+ ["Noose Patrol Car", 148777611],
+ ["Noose Stockade", 1911513875],
+ ["Oracle", 1348744438],
+ ["Packer", 569305213],
+ ["Patriot", -808457413],
+ ["Perennial", -2077743597],
+ ["Airport Perennial", -1590284256],
+ ["Peyote", 1830407356],
+ ["Phantom", -2137348917],
+ ["Pinnacle", 131140572],
+ ["PMP-600", 1376298265],
+ ["Police Cruiser", 2046537925],
+ ["Police Patrol", -1627000575],
+ ["Police Patriot", -350085182],
+ ["Pony", -119658072],
+ ["Premier", -1883869285],
+ ["Presidente", -1962071130],
+ ["Primo", -1150599089],
+ ["Police Stockade", -1900572838],
+ ["Rancher", 1390084576],
+ ["Rebla", 83136452],
+ ["Reply", -845979911],
+ ["Romero", 627094268],
+ ["Roman's Taxi", -1932515764],
+ ["Ruiner", -227741703],
+ ["Sabre", -449022887],
+ ["Sabre 2", 1264386590],
+ ["Sabre GT", -1685021548],
+ ["Schafter", -322343873],
+ ["Sentinel", 1349725314],
+ ["Solair", 1344573448],
+ ["Speedo", -810318068],
+ ["Stallion", 1923400478],
+ ["Steed", 1677715180],
+ ["Stockade", 1747439474],
+ ["Stratum", 1723137093],
+ ["Stretch", -1961627517],
+ ["Sultan", 970598228],
+ ["Sultan RS", -295689028],
+ ["Super GT", 1821991593],
+ ["Taxi", -956048545],
+ ["Taxi 2", 1208856469],
+ ["Trashmaster", 1917016601],
+ ["Turismo", -1896659641],
+ ["Uranus", 1534326199],
+ ["Vigero", -825837129],
+ ["Vigero 2", -1758379524],
+ ["Vincent", -583281407],
+ ["Virgo", -498054846],
+ ["Voodoo", 2006667053],
+ ["Washington", 1777363799],
+ ["Willard", 1937616578],
+ ["Yankee", -1099960214],
+ ["Bobber", -1830458836],
+ ["Faggio", -1842748181],
+ ["Hellfury", 584879743],
+ ["NRG-900", 1203311498],
+ ["PCJ-600", -909201658],
+ ["Sanchez", 788045382],
+ ["Zombie", -570033273],
+ ["Annihilator", 837858166],
+ ["Maverick", -1660661558],
+ ["Police Maverick", 353883353],
+ ["Tour Maverick", 2027357303],
+ ["Dinghy", 1033245328],
+ ["Jetmax", 861409633],
+ ["Marquis", -1043459709],
+ ["Predator", -488123221],
+ ["Reefer", 1759673526],
+ ["Squalo", 400514754],
+ ["Tuga", 1064455782],
+ ["Tropic", 290013743],
+ ["Cablecar", -960289747],
+ ["Subway", 800869680],
+ ["El Train", -1953988645],
+ ]
+};
+
+// ---------------------------------------------------------------------------
+
+function getGameData() {
+ return gameData;
+}
+
+// ---------------------------------------------------------------------------
\ No newline at end of file
diff --git a/scripts/shared/native.js b/scripts/shared/native.js
new file mode 100644
index 00000000..5ff598dd
--- /dev/null
+++ b/scripts/shared/native.js
@@ -0,0 +1,63 @@
+// ===========================================================================
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
+// ---------------------------------------------------------------------------
+// FILE: native.js
+// DESC: Provides util funcs for native wrapping
+// TYPE: Shared (JavaScript)
+// ===========================================================================
+
+// ---------------------------------------------------------------------------
+
+function toInteger(val) {
+ return Number(val);
+}
+
+// ---------------------------------------------------------------------------
+
+function toFloat(val) {
+ return parseFloat(val);
+}
+
+// ---------------------------------------------------------------------------
+
+function toString(val) {
+ return String(val);
+}
+
+// ---------------------------------------------------------------------------
+
+function toVector3(x, y, z) {
+ return new Vec3(x, y, z);
+}
+
+// ---------------------------------------------------------------------------
+
+function toVector2(x, y, z) {
+ return new Vec2(x, y, z);
+}
+
+// ---------------------------------------------------------------------------
+
+function toUpperCase(val) {
+ return val.toUpperCase();
+}
+
+// ---------------------------------------------------------------------------
+
+function toLowerCase(val) {
+ return val.toLowerCase();
+}
+
+// ---------------------------------------------------------------------------
+
+function isNull(val) {
+ if(typeof val === "undefined") {
+ return true;
+ }
+
+ return false;
+}
+
+// ---------------------------------------------------------------------------
\ No newline at end of file
diff --git a/third-party/mexui/Core/Component/Control.js b/third-party/mexui/Core/Component/Control.js
index c745e682..7d87f0c9 100644
--- a/third-party/mexui/Core/Component/Control.js
+++ b/third-party/mexui/Core/Component/Control.js
@@ -4,8 +4,8 @@ mexui.Component.Control = function(window, x, y, w, h, styles, callback)
mexui.Entity.StyleableEntity.call(this, this.linkComponentStyles('Control', styles));
this.window = window;
- this.position = new Vec2(x, y);
- this.size = new Vec2(w, h);
+ this.position = toVector2(x, y);
+ this.size = toVector2(w, h);
this.callback = callback;
this.boundTo = null;
@@ -87,7 +87,7 @@ mexui.Component.Control.prototype.getScreenPosition = function()
{
var pos = mexui.util.addVec2(this.window.position, this.position);
if(this.boundTo)
- pos = mexui.util.addVec2(pos, new Vec2(-this.boundTo.axis.x.getScrolledOffsetFixedStart(), -this.boundTo.axis.y.getScrolledOffsetFixedStart()));
+ pos = mexui.util.addVec2(pos, toVector2(-this.boundTo.axis.x.getScrolledOffsetFixedStart(), -this.boundTo.axis.y.getScrolledOffsetFixedStart()));
return pos;
};
@@ -112,7 +112,7 @@ mexui.Component.Control.prototype.isInsideBoundControl = function()
mexui.Component.Control.prototype.isInsideBoundControlEntries = function()
{
var boundToControlPosition = mexui.util.addVec2(this.boundTo.getScreenPosition(), this.boundTo.entriesPositionOffset);
- var boundToControlSize = new Vec2(this.boundTo.size.x, this.boundTo.axis.y.getDisplayedEntriesLength());
+ var boundToControlSize = toVector2(this.boundTo.size.x, this.boundTo.axis.y.getDisplayedEntriesLength());
return mexui.util.isRectangleInsideRectangle(this.getScreenPosition(), this.size, boundToControlPosition, boundToControlSize);
};
diff --git a/third-party/mexui/Core/Component/Window.js b/third-party/mexui/Core/Component/Window.js
index 2f6cea5a..242468b2 100644
--- a/third-party/mexui/Core/Component/Window.js
+++ b/third-party/mexui/Core/Component/Window.js
@@ -3,15 +3,15 @@ mexui.Component.Window = function(x, y, w, h, title, styles)
mexui.Entity.Component.call(this, true);
mexui.Entity.StyleableEntity.call(this, this.linkComponentStyles('Window', styles));
- this.position = new Vec2(x, y);
- this.size = new Vec2(w, h);
+ this.position = toVector2(x, y);
+ this.size = toVector2(w, h);
this.title = title || '';
this.controls = [];
this.titleBarShown = true;
this.titleBarHeight = 30;
this.titleBarIconShown = true;
- this.titleBarIconSize = new Vec2(30, 30);
+ this.titleBarIconSize = toVector2(30, 30);
};
mexui.util.extend(mexui.Component.Window, mexui.Entity.Component);
@@ -133,8 +133,8 @@ mexui.Component.Window.prototype.render = function()
if(this.titleBarShown)
{
// window title bar
- mexui.native.drawRectangle(this.position, new Vec2(this.size.x, this.titleBarHeight), this.getStyles('title'));
- mexui.native.drawText(this.position, new Vec2(this.size.x, this.titleBarHeight), this.title, this.getStyles('title'));
+ mexui.native.drawRectangle(this.position, toVector2(this.size.x, this.titleBarHeight), this.getStyles('title'));
+ mexui.native.drawText(this.position, toVector2(this.size.x, this.titleBarHeight), this.title, this.getStyles('title'));
if(this.titleBarIconShown)
{
@@ -211,7 +211,7 @@ mexui.Component.Window.prototype.isCursorOverCloseIcon = function()
mexui.Component.Window.prototype.getCloseIconPosition = function()
{
- return new Vec2(this.position.x + (this.size.x - this.titleBarIconSize.x), this.position.y);
+ return toVector2(this.position.x + (this.size.x - this.titleBarIconSize.x), this.position.y);
};
mexui.Component.Window.prototype.triggerEvent = function(eventName, e, data, callBaseMethodFirst)
@@ -365,14 +365,14 @@ mexui.Component.Window.prototype.line = function(x, y, w, h, styles, callback)
mexui.Component.Window.prototype.list = function(x, y, w, h, styles, callback) { return this.addControl(new mexui.Control.List(this, x, y, w, h, styles, callback)); };
mexui.Component.Window.prototype.minute = function(x, y, w, h, text, styles, callback) { return this.addControl(new mexui.Control.Minute(this, x, y, w, h, text, styles, callback)); };
mexui.Component.Window.prototype.month = function(x, y, w, h, text, styles, callback) { return this.addControl(new mexui.Control.Month(this, x, y, w, h, text, styles, callback)); };
-mexui.Component.Window.prototype.number = function(x, y, w, h, text, styles, callback) { return this.addControl(new mexui.Control.Number(this, x, y, w, h, text, styles, callback)); };
+mexui.Component.Window.prototype.number = function(x, y, w, h, text, styles, callback) { return this.addControl(new mexui.Control.toInteger(this, x, y, w, h, text, styles, callback)); };
mexui.Component.Window.prototype.password = function(x, y, w, h, text, styles, callback) { return this.addControl(new mexui.Control.Password(this, x, y, w, h, text, styles, callback)); };
mexui.Component.Window.prototype.positiveInteger = function(x, y, w, h, text, styles, callback) { return this.addControl(new mexui.Control.PositiveInteger(this, x, y, w, h, text, styles, callback)); };
-mexui.Component.Window.prototype.positiveNumber = function(x, y, w, h, text, styles, callback) { return this.addControl(new mexui.Control.PositiveNumber(this, x, y, w, h, text, styles, callback)); };
+mexui.Component.Window.prototype.positiveNumber = function(x, y, w, h, text, styles, callback) { return this.addControl(new mexui.Control.PositivetoInteger(this, x, y, w, h, text, styles, callback)); };
mexui.Component.Window.prototype.progressBar = function(x, y, w, h, text, styles) { return this.addControl(new mexui.Control.ProgressBar(this, x, y, w, h, text, styles)); };
mexui.Component.Window.prototype.radioButton = function(x, y, w, h, text, groupId, styles, callback) { return this.addControl(new mexui.Control.RadioButton(this, x, y, w, h, text, groupId, styles, callback)); };
mexui.Component.Window.prototype.rangedInteger = function(x, y, w, h, text, min, max, styles, callback) { return this.addControl(new mexui.Control.RangedInteger(this, x, y, w, h, text, min, max, styles, callback)); };
-mexui.Component.Window.prototype.rangedNumber = function(x, y, w, h, text, min, max, styles, callback) { return this.addControl(new mexui.Control.RangedNumber(this, x, y, w, h, text, min, max, styles, callback)); };
+mexui.Component.Window.prototype.rangedNumber = function(x, y, w, h, text, min, max, styles, callback) { return this.addControl(new mexui.Control.RangedtoInteger(this, x, y, w, h, text, min, max, styles, callback)); };
mexui.Component.Window.prototype.rectangle = function(x, y, w, h, styles, callback) { return this.addControl(new mexui.Control.Rectangle(this, x, y, w, h, styles, callback)); };
mexui.Component.Window.prototype.scrollBar = function(x, y, w, h, isVertical, styles, callback) { return this.addControl(new mexui.Control.ScrollBar(this, x, y, w, h, isVertical, styles, callback)); };
mexui.Component.Window.prototype.second = function(x, y, w, h, text, styles, callback) { return this.addControl(new mexui.Control.Second(this, x, y, w, h, text, styles, callback)); };
diff --git a/third-party/mexui/Core/Control/Button.js b/third-party/mexui/Core/Control/Button.js
index ef89836c..83116e04 100644
--- a/third-party/mexui/Core/Control/Button.js
+++ b/third-party/mexui/Core/Control/Button.js
@@ -36,5 +36,5 @@ mexui.Control.Button.prototype.render = function()
mexui.native.drawText(pos, this.size, this.text, this.getStyles('main'));
if(this.isFocused())
- mexui.native.drawRectangleBorder(mexui.util.subtractVec2(pos,new Vec2(2,2)), mexui.util.addVec2(this.size,new Vec2(3,3)), this.getStyles('focused'));
+ mexui.native.drawRectangleBorder(mexui.util.subtractVec2(pos,toVector2(2,2)), mexui.util.addVec2(this.size,toVector2(3,3)), this.getStyles('focused'));
};
\ No newline at end of file
diff --git a/third-party/mexui/Core/Control/CheckBox.js b/third-party/mexui/Core/Control/CheckBox.js
index 9404463a..b02e99ef 100644
--- a/third-party/mexui/Core/Control/CheckBox.js
+++ b/third-party/mexui/Core/Control/CheckBox.js
@@ -46,19 +46,19 @@ mexui.Control.CheckBox.prototype.render = function()
mexui.native.drawRectangle(pos, this.size, this.getStyles('main'));
if(this.checked)
- mexui.native.drawRectangle(mexui.util.addVec2(pos, new Vec2(1, 1)), new Vec2(this.size.x - 2, this.size.y - 2), this.getStyles('innerBox'));
+ mexui.native.drawRectangle(mexui.util.addVec2(pos, toVector2(1, 1)), toVector2(this.size.x - 2, this.size.y - 2), this.getStyles('innerBox'));
- mexui.native.drawText(mexui.util.addVec2(pos, new Vec2(this.size.x + this.textMarginLeft, 2)), this.size, this.text, this.getStyles('main'));
+ mexui.native.drawText(mexui.util.addVec2(pos, toVector2(this.size.x + this.textMarginLeft, 2)), this.size, this.text, this.getStyles('main'));
if(this.isFocused())
- mexui.native.drawRectangleBorder(mexui.util.subtractVec2(pos,new Vec2(2,2)), mexui.util.addVec2(this.size,new Vec2(3,3)), this.getStyles('focused'));
+ mexui.native.drawRectangleBorder(mexui.util.subtractVec2(pos,toVector2(2,2)), mexui.util.addVec2(this.size,toVector2(3,3)), this.getStyles('focused'));
};
// model
mexui.Control.CheckBox.prototype.getSizeForInput = function()
{
var textWidth = mexui.native.getTextWidth(this.text, this.getStyles('main'));
- return new Vec2(this.size.x + this.textMarginLeft + textWidth, this.size.y);
+ return toVector2(this.size.x + this.textMarginLeft + textWidth, this.size.y);
};
mexui.Control.CheckBox.prototype.toggleChecked = function()
diff --git a/third-party/mexui/Core/Control/Date.js b/third-party/mexui/Core/Control/Date.js
index 585a045d..5c0dcb13 100644
--- a/third-party/mexui/Core/Control/Date.js
+++ b/third-party/mexui/Core/Control/Date.js
@@ -7,8 +7,8 @@ mexui.util.createControlConstructor('Date', false, function(window, x, y, w, h,
this.year = 2019;
this.inputShown = false;
- this.valueBoxSize = new Vec2(50, 30);
- this.arrowBoxSize = new Vec2(25, 22);
+ this.valueBoxSize = toVector2(50, 30);
+ this.arrowBoxSize = toVector2(25, 22);
this.maxYearOffset = 10;
this.minYearCallback = ()=>{ return 1900; };
@@ -92,7 +92,7 @@ mexui.Control.Date.prototype.renderAfter = function()
var screenPos = this.getScreenPosition();
- var pos = new Vec2(screenPos.x, screenPos.y);
+ var pos = toVector2(screenPos.x, screenPos.y);
for(var i=0; i<3; i++)
{
mexui.native.drawRectangle(pos, this.valueBoxSize, this.getStyles('main'));
@@ -101,7 +101,7 @@ mexui.Control.Date.prototype.renderAfter = function()
pos.x += this.valueBoxSize.x;
}
- pos = new Vec2(screenPos.x, screenPos.y);
+ pos = toVector2(screenPos.x, screenPos.y);
pos.y += this.valueBoxSize.y;
for(var i=0; i<3; i++)
{
@@ -168,8 +168,8 @@ mexui.Control.Date.prototype.getArrowIndexByCursor = function()
var cursorPos = gui.cursorPosition;
var screenPos = this.getScreenPosition();
- var firstArrowStartPos = new Vec2(screenPos.x, screenPos.y + this.valueBoxSize.y);
- var lastArrowEndPos = new Vec2(screenPos.x + (this.arrowBoxSize.x * 6), screenPos.y + this.valueBoxSize.y + this.arrowBoxSize.y);
+ var firstArrowStartPos = toVector2(screenPos.x, screenPos.y + this.valueBoxSize.y);
+ var lastArrowEndPos = toVector2(screenPos.x + (this.arrowBoxSize.x * 6), screenPos.y + this.valueBoxSize.y + this.arrowBoxSize.y);
if(cursorPos.x >= firstArrowStartPos.x && cursorPos.y >= firstArrowStartPos.y && cursorPos.x <= lastArrowEndPos.x && cursorPos.y <= lastArrowEndPos.y)
{
diff --git a/third-party/mexui/Core/Control/DropDown.js b/third-party/mexui/Core/Control/DropDown.js
index ac394e3e..e13d183a 100644
--- a/third-party/mexui/Core/Control/DropDown.js
+++ b/third-party/mexui/Core/Control/DropDown.js
@@ -1,7 +1,7 @@
mexui.util.createControlConstructor('DropDown', true, function(window, x, y, w, h, text, styles, callback)
{
mexui.Component.Control.call(this, window, x, y, w, h, this.linkControlStyles('DropDown', styles), callback);
- mexui.Entity.ControlWithEntries.call(this, true, true, new Vec2(0, h), new Vec2(w + 120, 25));
+ mexui.Entity.ControlWithEntries.call(this, true, true, toVector2(0, h), toVector2(w + 120, 25));
this.axis.y.entriesShown = false;
@@ -89,14 +89,14 @@ mexui.Control.DropDown.prototype.render = function()
if(this.arrowShown)
{
- var pos2 = new Vec2(pos.x + this.size.x - (25 + 3), pos.y + 0);
- mexui.native.drawImage(pos2, new Vec2(25, 25), mexui.images.downArrow, this.getStyles('main'));
+ var pos2 = toVector2(pos.x + this.size.x - (25 + 3), pos.y + 0);
+ mexui.native.drawImage(pos2, toVector2(25, 25), mexui.images.downArrow, this.getStyles('main'));
}
mexui.Entity.ControlWithEntries.prototype.render.call(this);
if(this.isFocused())
- mexui.native.drawRectangleBorder(mexui.util.subtractVec2(pos,new Vec2(2,2)), mexui.util.addVec2(this.size,new Vec2(3,3)), this.getStyles('focused'));
+ mexui.native.drawRectangleBorder(mexui.util.subtractVec2(pos,toVector2(2,2)), mexui.util.addVec2(this.size,toVector2(3,3)), this.getStyles('focused'));
};
mexui.Control.DropDown.prototype.renderAfter = function()
@@ -104,7 +104,7 @@ mexui.Control.DropDown.prototype.renderAfter = function()
if(this.axis.y.entriesShown)
{
var pos = this.getScreenPosition();
- var pos2 = new Vec2(pos.x, pos.y);
+ var pos2 = toVector2(pos.x, pos.y);
pos.x += this.entriesPositionOffset.x;
pos.y += this.entriesPositionOffset.y;
@@ -127,7 +127,7 @@ mexui.Control.DropDown.prototype.renderAfter = function()
}
if(this.isFocused())
- mexui.native.drawRectangleBorder(mexui.util.subtractVec2(pos2,new Vec2(2,2)), mexui.util.addVec2(new Vec2(this.entrySize.x,this.axis.y.getDisplayedEntriesLength()),new Vec2(3,3)), this.getStyles('focused'));
+ mexui.native.drawRectangleBorder(mexui.util.subtractVec2(pos2,toVector2(2,2)), mexui.util.addVec2(toVector2(this.entrySize.x,this.axis.y.getDisplayedEntriesLength()),toVector2(3,3)), this.getStyles('focused'));
}
mexui.Entity.ControlWithEntries.prototype.renderAfter.call(this);
diff --git a/third-party/mexui/Core/Control/Grid.js b/third-party/mexui/Core/Control/Grid.js
index 6d7a126d..35df87cf 100644
--- a/third-party/mexui/Core/Control/Grid.js
+++ b/third-party/mexui/Core/Control/Grid.js
@@ -1,7 +1,7 @@
mexui.util.createControlConstructor('Grid', true, function(window, x, y, w, h, styles)
{
mexui.Component.Control.call(this, window, x, y, w, h, this.linkControlStyles('Grid', styles));
- mexui.Entity.ControlWithEntries.call(this, false, false, new Vec2(0, 25), new Vec2(this.size.x, 25), new Vec2(0, -25));
+ mexui.Entity.ControlWithEntries.call(this, false, false, toVector2(0, 25), toVector2(this.size.x, 25), toVector2(0, -25));
});
// default styles
@@ -39,10 +39,10 @@ mexui.Control.Grid.prototype.render = function()
{
var column = this.axis.x.entries[i];
- mexui.native.drawText(new Vec2(startX, pos.y), new Vec2(column.width, column.height), column.text, this.getStyles('header'));
+ mexui.native.drawText(toVector2(startX, pos.y), toVector2(column.width, column.height), column.text, this.getStyles('header'));
startX += column.width;
- mexui.native.drawAALine(new Vec2(startX, pos.y), new Vec2(startX, pos.y + this.size.y), this.getStyles('column'));
+ mexui.native.drawAALine(toVector2(startX, pos.y), toVector2(startX, pos.y + this.size.y), this.getStyles('column'));
if(column.height > maxColumnHeight)
{
@@ -51,7 +51,7 @@ mexui.Control.Grid.prototype.render = function()
}
var startY = pos.y + maxColumnHeight;
- mexui.native.drawAALine(new Vec2(pos.x, startY), new Vec2(pos.x + this.size.x, startY), this.getStyles('row'));
+ mexui.native.drawAALine(toVector2(pos.x, startY), toVector2(pos.x + this.size.x, startY), this.getStyles('row'));
for(var i=this.axis.y.getEntryStartIndex(),j=this.axis.y.getEntryEndIndex(); i= firstArrowStartPos.x && cursorPos.y >= firstArrowStartPos.y && cursorPos.x <= lastArrowEndPos.x && cursorPos.y <= lastArrowEndPos.y)
{
diff --git a/third-party/mexui/Core/Control/Tree.js b/third-party/mexui/Core/Control/Tree.js
index a6e5d56b..5e17d745 100644
--- a/third-party/mexui/Core/Control/Tree.js
+++ b/third-party/mexui/Core/Control/Tree.js
@@ -49,7 +49,7 @@ mexui.Control.Tree.prototype.render = function()
this.renderRows(this.axis.y.entries, 0, pos);
if(this.isFocused())
- mexui.native.drawRectangleBorder(mexui.util.subtractVec2(pos,new Vec2(2,2)), mexui.util.addVec2(this.size,new Vec2(3,3)), this.getStyles('focused'));
+ mexui.native.drawRectangleBorder(mexui.util.subtractVec2(pos,toVector2(2,2)), mexui.util.addVec2(this.size,toVector2(3,3)), this.getStyles('focused'));
};
mexui.Control.Tree.prototype.renderRows = function(rows, level, pos)
@@ -62,17 +62,17 @@ mexui.Control.Tree.prototype.renderRows = function(rows, level, pos)
if(shouldDraw)
{
if(row.rows.length > 0)
- mexui.native.drawText(new Vec2(pos.x - (this.rowLevelIndentation * 2), pos.y), new Vec2(this.size.x, this.rowHeight), row.open ? '-' : '+', this.getStyles('rowIcon'));
+ mexui.native.drawText(toVector2(pos.x - (this.rowLevelIndentation * 2), pos.y), toVector2(this.size.x, this.rowHeight), row.open ? '-' : '+', this.getStyles('rowIcon'));
- mexui.native.drawRectangle(pos, new Vec2(this.size.x - (this.rowLevelIndentation * level), this.rowHeight), this.getStyles('row'));
- mexui.native.drawText(pos, new Vec2(this.size.x, this.rowHeight), row.text, this.getStyles('row'));
+ mexui.native.drawRectangle(pos, toVector2(this.size.x - (this.rowLevelIndentation * level), this.rowHeight), this.getStyles('row'));
+ mexui.native.drawText(pos, toVector2(this.size.x, this.rowHeight), row.text, this.getStyles('row'));
}
pos.y += this.rowHeight;
if(shouldDraw)
{
- mexui.native.drawAALine(pos, new Vec2(pos.x + this.size.x, pos.y), this.getStyles('rowLine'));
+ mexui.native.drawAALine(pos, toVector2(pos.x + this.size.x, pos.y), this.getStyles('rowLine'));
}
if(row.rows.length > 0 && row.open)
@@ -107,8 +107,8 @@ mexui.Control.Tree.prototype.testRowClick = function(e, rows, pos)
{
var row = rows[i];
- var rowPos = new Vec2(pos.x - (this.rowLevelIndentation * 2), pos.y);
- var rowSize = new Vec2(this.size.x + (this.rowLevelIndentation * 2), this.rowHeight);
+ var rowPos = toVector2(pos.x - (this.rowLevelIndentation * 2), pos.y);
+ var rowSize = toVector2(this.size.x + (this.rowLevelIndentation * 2), this.rowHeight);
if(mexui.util.isCursorInRectangle(rowPos, rowSize))
{
this.onClickRow(row);
diff --git a/third-party/mexui/Core/Entity/Component.js b/third-party/mexui/Core/Entity/Component.js
index e0afae23..3d3e7ce9 100644
--- a/third-party/mexui/Core/Entity/Component.js
+++ b/third-party/mexui/Core/Entity/Component.js
@@ -29,7 +29,7 @@ mexui.Entity.Component.prototype.onMouseMove = function(e, offset)
{
if(this.moving)
{
- this.position = new Vec2(this.position.x + offset.x, this.position.y + offset.y);
+ this.position = toVector2(this.position.x + offset.x, this.position.y + offset.y);
e.used = true;
}
};
diff --git a/third-party/mexui/Core/Entity/ControlAxis.js b/third-party/mexui/Core/Entity/ControlAxis.js
index 4bddcdec..80e9749f 100644
--- a/third-party/mexui/Core/Entity/ControlAxis.js
+++ b/third-party/mexui/Core/Entity/ControlAxis.js
@@ -19,12 +19,12 @@ mexui.Entity.ControlAxis.prototype.initScrollBar = function()
{
if(this.isVertical)
{
- var pos = mexui.util.addVec2(this.control.position, new Vec2(this.control.entrySize.x, this.control.entriesPositionOffset.y));
+ var pos = mexui.util.addVec2(this.control.position, toVector2(this.control.entrySize.x, this.control.entriesPositionOffset.y));
this.scrollBar = new mexui.Control.ScrollBar(this.control.window, pos.x, pos.y, 25, this.getDisplayedEntriesLength(), true, this.control.styles.scrollBar);
}
else
{
- var pos = mexui.util.addVec2(this.control.position, new Vec2(this.control.entriesPositionOffset.x, this.control.size.y));
+ var pos = mexui.util.addVec2(this.control.position, toVector2(this.control.entriesPositionOffset.x, this.control.size.y));
this.scrollBar = new mexui.Control.ScrollBar(this.control.window, pos.x, pos.y, this.getDisplayedEntriesLength(), 25, false, this.control.styles.scrollBar);
}
@@ -74,7 +74,7 @@ mexui.Entity.ControlAxis.prototype.getEntryIndexByPoint = function(point)
return null;
}
- var pos = new Vec2(screenPos.x + this.control.entriesPositionOffset.x, screenPos.y + this.control.entriesPositionOffset.y);
+ var pos = toVector2(screenPos.x + this.control.entriesPositionOffset.x, screenPos.y + this.control.entriesPositionOffset.y);
var index = Math.floor((point.y - pos.y) / this.control.entrySize[this.axisIndex]);
index += this.getEntryStartIndex();
diff --git a/third-party/mexui/Core/Entity/ControlWithEntries.js b/third-party/mexui/Core/Entity/ControlWithEntries.js
index 732014ff..5decf22f 100644
--- a/third-party/mexui/Core/Entity/ControlWithEntries.js
+++ b/third-party/mexui/Core/Entity/ControlWithEntries.js
@@ -1,9 +1,9 @@
mexui.Entity.ControlWithEntries = function(entriesOutsideControl, manualScrollBar, entriesPositionOffset, entrySize, entriesSizeOffset)
{
this.entriesOutsideControl = entriesOutsideControl;
- this.entriesPositionOffset = entriesPositionOffset || new Vec2(0, 0);
- this.entrySize = entrySize || new Vec2(this.size.x, 25);
- this.entriesSizeOffset = entriesSizeOffset || new Vec2(0, 0);
+ this.entriesPositionOffset = entriesPositionOffset || toVector2(0, 0);
+ this.entrySize = entrySize || toVector2(this.size.x, 25);
+ this.entriesSizeOffset = entriesSizeOffset || toVector2(0, 0);
this.axis = {};
this.axis.x = new mexui.Entity.ControlAxis(this, false, manualScrollBar, entriesPositionOffset);
diff --git a/third-party/mexui/Core/Native.js b/third-party/mexui/Core/Native.js
index efe3c32a..ab0dcc45 100644
--- a/third-party/mexui/Core/Native.js
+++ b/third-party/mexui/Core/Native.js
@@ -12,7 +12,7 @@ mexui.native.loadImage = function(imageFilePath, imageName)
var image = null;
var parts = imageFilePath.split('.');
- var ext = parts[parts.length - 1].toLowerCase();
+ var ext = toLowerCase(parts[parts.length - 1]);
if(ext == 'png')
image = drawing.loadPNG(file);
else if(ext == 'bmp')
@@ -105,10 +105,10 @@ mexui.native.drawRectangleBorder = function(position, size, styles)
var rightXPosition = position.x + size.x;
var bottomYPosition = position.y + size.y;
- var topLeftPosition = new Vec2(position.x, position.y);
- var topRightPosition = new Vec2(rightXPosition, position.y);
- var bottomLeftPosition = new Vec2(position.x, bottomYPosition);
- var bottomRightPosition = new Vec2(rightXPosition, bottomYPosition);
+ var topLeftPosition = toVector2(position.x, position.y);
+ var topRightPosition = toVector2(rightXPosition, position.y);
+ var bottomLeftPosition = toVector2(position.x, bottomYPosition);
+ var bottomRightPosition = toVector2(rightXPosition, bottomYPosition);
var original = styles.lineColour;
@@ -133,7 +133,7 @@ mexui.native.drawAALine = function(point1, point2, styles)
if(lineColour == null || lineColour == 'none')
return;
- drawing.drawRectangle(null, point1, new Vec2((point2.x - point1.x) + styles.lineWeight, (point2.y - point1.y) + styles.lineWeight), lineColour, lineColour, lineColour, lineColour);
+ drawing.drawRectangle(null, point1, toVector2((point2.x - point1.x) + styles.lineWeight, (point2.y - point1.y) + styles.lineWeight), lineColour, lineColour, lineColour, lineColour);
};
mexui.native.drawText = function(position, size, text, styles)
@@ -142,7 +142,7 @@ mexui.native.drawText = function(position, size, text, styles)
var textHeight = mexui.native.getTextHeight(text, styles, font);
var textIndent = styles.textAlign == 0.0 || styles.textAlign == 1.0 ? styles.textIndent : 0;
- var textPos = new Vec2(position.x + textIndent, position.y + ((size.y - textHeight) / 2.0));
+ var textPos = toVector2(position.x + textIndent, position.y + ((size.y - textHeight) / 2.0));
font.render(text + '', textPos, size.x, styles.textAlign, 0.0, styles.textSize, styles.textColour != null ? styles.textColour : styles.textColor);
};
diff --git a/third-party/mexui/Core/Utility.js b/third-party/mexui/Core/Utility.js
index 25098920..d1415b69 100644
--- a/third-party/mexui/Core/Utility.js
+++ b/third-party/mexui/Core/Utility.js
@@ -26,17 +26,17 @@ mexui.util.isCursorInRectangle = function(position, size)
mexui.util.addVec2 = function(vec2a, vec2b)
{
- return new Vec2(vec2a.x + vec2b.x, vec2a.y + vec2b.y);
+ return toVector2(vec2a.x + vec2b.x, vec2a.y + vec2b.y);
};
mexui.util.subtractVec2 = function(vec2a, vec2b)
{
- return new Vec2(vec2a.x - vec2b.x, vec2a.y - vec2b.y);
+ return toVector2(vec2a.x - vec2b.x, vec2a.y - vec2b.y);
};
mexui.util.addVec3 = function(vec3a, vec3b)
{
- return new Vec3(vec3a.x + vec3b.x, vec3a.y + vec3b.y, vec3a.z + vec3b.z);
+ return toVector3(vec3a.x + vec3b.x, vec3a.y + vec3b.y, vec3a.z + vec3b.z);
};
mexui.util.createControlConstructor = function(controlName, hasEntries, constructor)
@@ -228,7 +228,7 @@ mexui.util.round = function(x, n)
mexui.util.getCenterPosition = function(largerSize, smallerSize)
{
- return new Vec2(
+ return toVector2(
(largerSize.x - smallerSize.x) / 2.0,
(largerSize.y - smallerSize.y) / 2.0
);
@@ -236,7 +236,7 @@ mexui.util.getCenterPosition = function(largerSize, smallerSize)
mexui.util.getWindowSize = function()
{
- return new Vec2(gta.width, gta.height);
+ return toVector2(gta.width, gta.height);
};
mexui.util.isRectangleInsideRectangle = function(pos1, size1, pos2, size2)
@@ -543,7 +543,7 @@ mexui.util.isWeekDayName = function(text)
mexui.util.isDayIdSuffix = function(text)
{
- switch(text.toLowerCase())
+ switch(toLowerCase(text))
{
case 'st':
case 'nd':
@@ -556,7 +556,7 @@ mexui.util.isDayIdSuffix = function(text)
mexui.util.isDayIdSuffixForDayId = function(dayId, text)
{
- switch(text.toLowerCase())
+ switch(toLowerCase(text))
{
case 'st': return dayId == 1 || dayId == 21 || dayId == 31;
case 'nd': return dayId == 2 || dayId == 22;
@@ -604,7 +604,7 @@ mexui.util.isDayIdWithOptionalSuffix = function(text)
mexui.util.inArrayOrStartsWithInArray = function(text, arr, startsWithCharCount)
{
- text = text.toLowerCase();
+ text = toLowerCase(text);
for(var i in arr)
{
diff --git a/third-party/mexui/mexui.js b/third-party/mexui/mexui.js
index 9829f4eb..936ff441 100644
--- a/third-party/mexui/mexui.js
+++ b/third-party/mexui/mexui.js
@@ -44,7 +44,7 @@ mexui.bindEvents = function()
if(isAbsolute)
return;
- mexui.triggerEvent('onMouseMove', new Vec2(position.x, position.y), true);
+ mexui.triggerEvent('onMouseMove', toVector2(position.x, position.y), true);
});
addEventHandler('onMouseWheel', function(event, mouse, offset, flipped)
@@ -290,7 +290,7 @@ mexui.setInput = function(showInput)
//if(localPlayer)
//{
// if(showInput)
- // gta.setCameraLookAtEntity(new Vec3(gta.cameraMatrix.m41, gta.cameraMatrix.m42, gta.cameraMatrix.m43), localPlayer, false);
+ // gta.setCameraLookAtEntity(toVector3(gta.cameraMatrix.m41, gta.cameraMatrix.m42, gta.cameraMatrix.m43), localPlayer, false);
// else
// gta.restoreCamera(false);
//}