diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..b95e158d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+.vs/
+.git/
\ No newline at end of file
diff --git a/changes.txt b/changes.txt
deleted file mode 100644
index e69de29b..00000000
diff --git a/files/html/login.html b/files/html/login.html
new file mode 100644
index 00000000..246d1c1e
--- /dev/null
+++ b/files/html/login.html
@@ -0,0 +1,46 @@
+
+
+ Asshat Gaming: Login
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ideas.txt b/ideas.txt
deleted file mode 100644
index 9dd9cb33..00000000
--- a/ideas.txt
+++ /dev/null
@@ -1,239 +0,0 @@
-Ideas for Asshat Gaming RP!
-
-NOTICE: Most of these ideas are totally random and some might be unrealistic. Every time I thought of something,
-I immediately threw it into this file. There may be duplicates or similar entries spread out and unorganized.
-
-Thanks for understanding,
-- Vortrex
-
-==============================================================================================================
-- Businesses (some from GTA Online)
- - Nightclubs
- - Executive Offices
- - Warehouses
- - Hangars
- - Houses
- - Garages
- - Casinos
-
-- Interactive peds with each one having a background story, characteristics, certain people or groups they like/dislike.
- - Procedurally generated?
-
-- Nightclubs, bars, etc can employ "bouncer" peds that either prevent entry to certain people, or kick people out.
-
-- Background ambience.
- - Anonymous city traffic and pedestrians
- - They come and go and aren't persistent.
- - Police peds/traffic will pursue if player has 1+ stars and comes within range and line of sight.
- - Police presence becomes more frequent in areas where crimes occur (default police spawn rate will be increased for the area)
- - Random text bubble dialog above their heads.
- - Complain about life, work, taxes, nearby shady establishments, rising crime rates, gangs, etc
- - Praise nearby good establishments, lowered taxes, crime rates dropping, etc
-
-- Named NPCs
- - Persistent
- - Move from place to place. Eat at restaurants, drive home, to work, get drunk at a bar, etc.
- - Different personalities
- - Relationship levels with each player and faction.
- - If you piss them off, they won't do business with you.
- - If you fuck them over, you have a chance of being greenlit under certain circumstances (peds will show up randomly and attempt to kill or subdue you)
- - Faction/clans at war is basically kill on sight as long as cops aren't around
-
-- Firefighter Job
- - Vehicles catch on fire instead of blowing up.
- - Random property fires can occur.
- - Firetrucks can "spray" a fire, lowering the damage until it is extinguished (Aim detection).
-
-- Streetsweeper Job
- - Instead of checkpoints, show actual messes on the road.
- - Drive over the messes with the right vehicle to "clean" the mess.
- - Only show messes if at least one player is on duty.
-
-- Garbageman Job
- - Instead of checkpoints, have trashbag objects outside of properties or wherever.
- - Allow the trashtruck drivers to "pickup" the trashbag, then "place" into the truck.
- - If the truck is full, deliver the trashbags to the dump.
- - Only show trashbags if at least one player is currently doing the job.
-
-- Mailman Job
- - Use a white solid van (Pony maybe) as a mail van.
- - Load mail at the post office, and drive a specific route to "deliver" mail.
- - Return the truck for payment.
-
-- Vehicle Towing
- - Use a Yankee or something to store the vehicle "inside" (just make the car disappear) until better sync options are built for GTA 3/VC.
- - Universal command to tow/release a vehicle ( /tow ).
- - Attach to nearest vehicle.
-
-- Item System
- - Several item types, including armour, skins, weapons, drugs, materials, and more.
- - Items can be dropped and picked up.
- - Items can be stored in a vehicle trunk or dash compartment.
- - Items can be given, taken, or used.
-
-- Payphones
- - Make built in payphones usable (detect position, ring sound, etc)
- - Payphones can be called, making them ring to nearby players.
-
-- Multiple bed hospital.
- - When one is taken, use the next one.
- - If all are full, have a waiting list.
- - Allow people to go in and lay on a bed to heal (or use a check-in system)
-
-- Several NPC's
- - Paramedics/Doctors at hospitals,
- - LC/VC/LS/SF/LV police dept desk clerk and dispatcher.
- - Jail guard
- - Interactive. Go up and talk to them for responses etc
-
-- Use permissions/flag system for everything.
- - Admin abilities
- - Moderation (muted/frozen/etc)
- - LEO abilities
- - Faction abilities
- - etc
-
-- For games with interiors, properties inside of properties (make it a sub-property, but using a "type" to define it) AKA a business inside a business (illegal back room gambling, perhaps?)
-
-- Stealable clothes.
- - Police uniforms can be stolen, and the cop will be reverted to his non-uniform skin.
- - Clothes are items so the criminal can apply it immediately or store/drop/give/sell it
-
-- Black market for anything.
- - Smuggled drugs
- - LEO items
- - Weapons and weapon upgrades
- - Illegal vehicle upgrades like NOS.
-
-- Drug houses and weed farms.
- - Make weed only plantable in certain areas.
- - Drug houses aren't limited to the type of house, as anybody can deal or use in any place.
-
-- Size-based inventories.
- - Items should have a size and inventories can only hold so much.
- - Items inside of items. This could be (but not limited to):
- - Briefcases
- - Wallets
- - Safes
- - Trashbags
- - Boxes/crates
- - Use the item sizes for storage capacity
-
-- Weapons like DayZ.
- - Multiple weapon types that issue different damages.
- - Ammo clips that only fit a compatible weapon
- - Different clip types hold different amounts of ammo in them (and specific ammo types)
- - Hollow point and armor piercing round types
- - Modifications. Flashlight, silencer, bigger clip, tracer, scope, etc.
-
-- Crime scene investigations.
- - Blood
- - Fingerprints
- - Ballistics/bullets on ground, in objects, walls, etc.
- - Gunpowder traces
- - Weapons
- - Other crime scene stuff for investigation roleplay.
- - These items should be visible on the ground (particle effects?)
- - Can be cleaned up by anybody (including the murderer or suspects)
- - Showering or swimming clears blood from body
- - Rain washes away blood outside (if not under an object or bridge). Perhaps line of sight check with high up Z at same coord?
-
-- Huge police interiors and garages.
- - Multiple interrogation rooms with blocked sound (chat is localized to that room)
- - Multiple offices for ranking members
- - A large locker room
- - Crime scene lab
- - Cell block area (or multiple cell blocks)
- - Elevators that can take you to multiple levels of the building (and roof/garage).
-
-- Custom MDC.
- - Arrest logs
- - Past tickets
- - Officer reports
- - Investigation info
- - APB list
-
-- Admin panel.
- - Reports
- - Multiple actions for each
- - Viewing info and past reports/actions on the reporter and the situation.
- - Logs
- - Chat
- - Action
- - Weapon/Kill/Death
- - Others
-
-- Log everything possible.
-
-- Depending on type of injuries, have multiple results occur over time.
- - Gunshots lead to bleeding which could lead to passing out for loss of blood.
- - Post-treatment effects are also possible including siezures from blunt force trauma.
-
-- Custom actions to have different results. Interactive-ness.
- - Hotwiring a car could be successful or could also fail, depending on vehicle type and variance.
- - The user has to go through each step in order to complete the task.
- - Hotwiring could have things like splitting and joining wires to make the car start or the alarm stop.
- - Include medical procedures in this idea.
- - Require certain tools to perform different actions.
- - Different vehicles have different wires to use to be successful.
-
-- Limit weapons per person.
- - Have a visible large weapon if they have one, and allow a concealable smaller weapon as well.
-
-- Officers usually have a utility belt. Allow it to hold equipment as well.
-
-- Trunks can hold players/peds (not visibly) and items and is size based.
-
-- Get "inside" the back of trucks/trailers and store items inside.
- - Use an interior for this and allow dropped items (including crates and boxes and etc).
- - Ambulance, bus, delivery truck, semi truck trailer, etc.
- - Shouts can be heard outside wherever the vehicle is at.
- - Vehicle sink or explode while inside the back causes death and objects destroyed.
- - Also for airplane interiors
-
-- Impound
- - Inaccessible parking garage. Spawn retrieved impound vehicles at the door.
- - Or multi-space impound lot. When retrieving a car from impound, spawn it in the first empty space that isn't obstructed.
-
-- Weapon wear and tear
- - If not cared for, they can have decreased damage from shots, jam, misfire, etc.
- - Cleaning weapons improves reliability
-
-- Weapon ballistics and identity
- - Barrel bores
- - Serial numbers. Can be removed/rubbed off.
-
-- GUI color schemes
- - Settings page to switch them. Orange, red, blue, purple, etc.
-
-- Police
- - Stars
- - 1 star
- - Initial misdemeanor. Traffic violation, pedestrian crime, etc. Police will pursue to fine/ticket.
- - 2 stars
- - Any subsequent crimes, whether felony or misdeanor, after receiving one star and no action taken (if you don't pull over, evade, etc). Results in arrest.
- - Any felony crime that isn't extremely violent or doesn't involve a deadly weapon
- - 3 stars is basically a warrant. Police will attempt to arrest you on sight and may use heavier force than normal if you become a threat.
- - 4 stars is SWAT and/or air support backup callout. Police presence will become more dense and they will really pursue you now.
- - 5 stars (highest in the server) is all out manhunt. Police everywhere. They will most likely shoot to kill.
- - NPC police will chase you if you have 1+ stars. If you lose them with 2 or less stars, they go away unless you are sighted by another officer before cooldown.
- - Civilians can report crimes by calling police or informing nearby police. They will give them your description.
- - Any traffic violation that takes place within LOS and range of police will cause them to chase you until you pull over.
- - Failure to pull over within a timely manner, or breaking another law before pulling over adds a second star. They won't fine you at this level, only arrest or worse.
-
-- NPC Ideas
- - Bodyguards
- - Biker gang formation
- - Convoy Line
- - Guard/Protect Properties
- - Respond to enemy attacks at other locations
- - Taxi Driver
- - Personal Chauffeur
- - Bus Driver
- - Train Operator
- - Gangs/Mafia Members
- - Drug Dealers
- - Weapons Dealers
- - Mechanic
- - Tweakers
- - Bouncers
\ No newline at end of file
diff --git a/meta.xml b/meta.xml
index a2f4699d..d5c02b37 100644
--- a/meta.xml
+++ b/meta.xml
@@ -1,5 +1,5 @@
-
+
@@ -26,6 +26,7 @@
+
@@ -58,7 +59,6 @@
-
@@ -67,7 +67,6 @@
-
@@ -242,5 +241,5 @@
-
+
\ No newline at end of file
diff --git a/notes.txt b/notes.txt
deleted file mode 100644
index 26ae5741..00000000
--- a/notes.txt
+++ /dev/null
@@ -1 +0,0 @@
-- Fix client data loggedIn for switchCharacterCommand
\ No newline at end of file
diff --git a/scripts/client/afk.js b/scripts/client/afk.js
index d9b2b5b6..90fb9b02 100644
--- a/scripts/client/afk.js
+++ b/scripts/client/afk.js
@@ -1,3 +1,13 @@
+// ===========================================================================
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
+// ---------------------------------------------------------------------------
+// FILE: afk.js
+// DESC: Provides AFK detection
+// TYPE: Client (JavaScript)
+// ===========================================================================
+
// ----------------------------------------------------------------------------
addEventHandler("OnLostFocus", function(event) {
diff --git a/scripts/client/gui.js b/scripts/client/gui.js
index dc720bc1..79d47903 100644
--- a/scripts/client/gui.js
+++ b/scripts/client/gui.js
@@ -1,9 +1,10 @@
// ===========================================================================
// Asshat-Gaming Roleplay
-// Copyright (c) 2020 by Asshat Gaming (www.asshatgaming.com)
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: gui.js
-// DESC: Provides GUI functionality and styles
+// DESC: Provides GUI functionality and styles (using MexUI)
// TYPE: Client (JavaScript)
// ===========================================================================
@@ -16,13 +17,12 @@ let primaryColour = [
[51, 153, 255],
[144, 255, 96],
[255, 188, 218],
- [252, 145, 58],
- [252, 145, 58],
+ [255, 188, 218],
[180, 180, 180],
[180, 180, 180],
];
-let windowAlpha = 120;
+let windowAlpha = 185;
let windowTitleAlpha = 200;
let buttonAlpha = 200;
@@ -209,6 +209,861 @@ let skinNames = [
[120, "Darkel", "Skin120.png"],
//[121, "Chuff Security Officer", "Skin121.png"]
],
+ [ // 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],
+ [7, "Golfer", false],
+ [8, "INVALID", false],
+ [9, "Random Lady", false],
+ [10, "Bum", false],
+ [11, "Greaser", false],
+ [12, "Random Guy", false],
+ [13, "Random Guy", false],
+ [14, "Random Lady", false],
+ [15, "Random Guy", false],
+ [16, "Random Guy", false],
+ [17, "Beach Girl", false],
+ [18, "Fat Beach Lady", false],
+ [19, "Beach Guy", false],
+ [20, "Fat Beach Guy", false],
+ [21, "Random Lady", false],
+ [22, "Random Lady", false],
+ [23, "Random Lady", false],
+ [24, "Prostitute", false],
+ [25, "Bum", false],
+ [26, "Bum", false],
+ [27, "Random Guy", false],
+ [28, "Taxi Driver", false],
+ [29, "Haitian", false],
+ [30, "Criminal", false],
+ [31, "Random Lady", false],
+ [32, "Random Lady", false],
+ [33, "Random Guy", false],
+ [34, "Random Guy", false],
+ [35, "Random Lady", false],
+ [36, "Random Lady", false],
+ [37, "Random Guy", false],
+ [38, "Beach Lady", false],
+ [39, "Beach Guy", false],
+ [40, "Beach Lady", false],
+ [41, "Beach Guy", false],
+ [42, "Random Guy", false],
+ [43, "Prostitute", false],
+ [44, "Bum", false],
+ [45, "Bum", false],
+ [46, "Random Guy", false],
+ [47, "Random Guy", false],
+ [48, "Punk", false],
+ [49, "Prostitute", false],
+ [50, "Random Old Lady", false],
+ [51, "Punk", false],
+ [52, "Random Guy", false],
+ [53, "Random Lady", false],
+ [54, "Random Lady", false],
+ [55, "Random Guy", false],
+ [56, "Random Guy", false],
+ [57, "Beach Lady", false],
+ [58, "Beach Guy", false],
+ [59, "Beach Lady", false],
+ [60, "Beach Guy", false],
+ [61, "Construction Worker", false],
+ [62, "Golfer", false],
+ [63, "Golfer", false],
+ [64, "Golfer", false],
+ [65, "Beach Lady", false],
+ [66, "Beach Guy", false],
+ [67, "Random Lady", false],
+ [68, "Random Guy", false],
+ [69, "Random Guy", false],
+ [70, "Prostitute", false],
+ [71, "Bum Lady", false],
+ [72, "Random Guy", false],
+ [73, "Random Guy", false],
+ [74, "Taxi Driver", false],
+ [75, "Random Woman", false],
+ [76, "Skater Guy", false],
+ [77, "Beach Lady", false],
+ [78, "Skater Guy", false],
+ [79, "Young Woman Shopper", false],
+ [80, "Old Women Shopper", false],
+ [81, "Tourist", false],
+ [82, "Tourist", false],
+ [83, "Cuban", false],
+ [84, "Cuban", false],
+ [85, "Haitian", false],
+ [86, "Haitian", false],
+ [87, "Shark", false],
+ [88, "Shark", false],
+ [89, "Diaz Guy", false],
+ [90, "Diaz Guy", 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],
+ [103, "Random Guy", false],
+ [104, "Bodyguard", false],
+ [105, "Prostitute", false],
+ [106, "Prostitute", false],
+ [107, "Ricardo Diaz", false],
+ [108, "Love Fist Guy", false],
+ [109, "Ken Rosenburg", false],
+ [110, "Candy Suxx", false],
+ [111, "Hilary", false],
+ [112, "Love Fist", false],
+ [113, "Phil", false],
+ [114, "Rockstar Guy", false],
+ [115, "Sonny", false],
+ [116, "Lance", false],
+ [117, "Mercedes", false],
+ [118, "Love Fist", false],
+ [119, "Alex Scrub", false],
+ [120, "Officer Lance Vance", false],
+ [121, "Lance Vance", false],
+ [122, "Cortez", false],
+ [123, "SWAT 2", false],
+ [124, "Columbian", false],
+ [125, "Hilary", false],
+ [126, "Mercedes", false],
+ [127, "Cam", false],
+ [128, "Cam", false],
+ [129, "Phil", false],
+ [130, "Phil", false],
+ [131, "Bodyguard", false],
+ [132, "Pizza Worker", false],
+ [133, "Taxi Driver", false],
+ [134, "Taxi Driver", false],
+ [135, "Sailor", false],
+ [136, "Sailor", false],
+ [137, "Sailor", false],
+ [138, "Chef", false],
+ [139, "Criminal", false],
+ [140, "French Guy", false],
+ [141, "Worker", false],
+ [142, "Haitian", false],
+ [143, "Waitress", false],
+ [144, "Forelli Member", false],
+ [145, "Forelli Member", false],
+ [146, "Forelli Member", false],
+ [147, "Columbian", false],
+ [148, "Random Guy", false],
+ [149, "Beach Guy", false],
+ [150, "Random Guy", false],
+ [151, "Random Guy", false],
+ [152, "Random Guy", false],
+ [153, "Drag Queen", false],
+ [154, "Diaz Traitor", false],
+ [155, "Random Guy", false],
+ [156, "Random Guy", false],
+ [157, "Stripper", false],
+ [158, "Stripper", false],
+ [159, "Stripper", false],
+ [160, "Store Clerk", false],
+ [161, "Tommy Vercetti", false],
+ [162, "Tommy Vercetti (Business Suit)", false],
+ [163, "Tommy Vercetti (SpandEx Overalls)", false],
+ [164, "Tommy Vercetti (Golfer)", false],
+ [165, "Tommy Vercetti (Cuban)", 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],
+ [170, "Tommy Vercetti (Black Tracksuit)", false],
+ [171, "Tommy Vercetti (Red Tracksuit)", false],
+ [172, "Club Bouncer", false],
+ [173, "Club Bouncer", false],
+ [174, "Stripclub Dancer", false],
+ [175, "Random Guy", false],
+ [176, "Stripclub Dancer", false],
+ [177, "Stripclub Dancer", false],
+ [178, "Stripclub Dancer", false],
+ [179, "Gang Member", false],
+ [180, "Tommy Vercetti (Endgame T-Shirt)", false],
+ [181, "Forelli Thug", false],
+ [182, "Forelli Thug", false],
+ [183, "Random Lady", false],
+ [184, "Gang Member", false],
+ [185, "Party Waitress", false],
+ [186, "Kent Paul", false],
+ [187, "Big Head Taxi Driver", false],
+ ],
+
+ [ // GTA San Andreas
+ [0, "Carl 'CJ' Johnson", false],
+ [1, "The Truth", false],
+ [2, "Maccer", false],
+ [3, "Andre", false],
+ [4, "Barry 'Big Bear' Thorne", false],
+ [5, "Emmet", false],
+ [6, "Taxi Driver/Train Driver", false],
+ [7, "Janitor", false],
+ [8, "Unknown", false],
+ [9, "Normal Ped", false],
+ [10, "Old Woman", false],
+ [11, "Casino Croupier", false],
+ [12, "Rich Woman", false],
+ [13, "Street Girl", false],
+ [14, "Normal Ped", false],
+ [15, "Mr.Whittaker (RS Haul Owner)", false],
+ [16, "Airport Ground Worker", false],
+ [17, "Businessman", false],
+ [18, "Beach Visitor", false],
+ [19, "DJ", false],
+ [20, "Rich Guy (Madd Dogg's Manager)", false],
+ [21, "Normal Ped", false],
+ [22, "Normal Ped", false],
+ [23, "Bmxer", false],
+ [24, "Madd Dogg Bodyguard", false],
+ [25, "Madd Dogg Bodyguard", false],
+ [26, "Backpacker", false],
+ [27, "Construction Worker", false],
+ [28, "Drug Dealer", false],
+ [29, "Drug Dealer", false],
+ [30, "Drug Dealer", false],
+ [31, "Farm-Town Inhabitant", false],
+ [32, "Farm-Town Inhabitant", false],
+ [33, "Farm-Town Inhabitant", false],
+ [34, "Farm-Town Inhabitant", false],
+ [35, "Gardener", false],
+ [36, "Golfer", false],
+ [37, "Golfer", false],
+ [38, "Normal Ped", false],
+ [39, "Normal Ped", false],
+ [40, "Normal Ped", false],
+ [41, "Normal Ped", false],
+ [42, "Jethro", false],
+ [43, "Normal Ped", false],
+ [44, "Normal Ped", false],
+ [45, "Beach Visitor", false],
+ [46, "Normal Ped", false],
+ [47, "Normal Ped", false],
+ [48, "Normal Ped", false],
+ [49, "Snakehead (Da Nang)", false],
+ [50, "Mechanic", false],
+ [51, "Mountain Biker", false],
+ [52, "Mountain Biker", false],
+ [53, "Unknown", false],
+ [54, "Normal Ped", false],
+ [55, "Normal Ped", false],
+ [56, "Normal Ped", false],
+ [57, "Oriental Ped", false],
+ [58, "Oriental Ped", false],
+ [59, "Normal Ped", false],
+ [60, "Normal Ped", false],
+ [61, "Pilot", false],
+ [62, "Colonel Fuhrberger", false],
+ [63, "Prostitute", false],
+ [64, "Prostitute", false],
+ [65, "Kendl Johnson", false],
+ [66, "Pool Player", false],
+ [67, "Pool Player", false],
+ [68, "Priest/Preacher", false],
+ [69, "Normal Ped", false],
+ [70, "Scientist", false],
+ [71, "Security Guard", false],
+ [72, "Hippy", false],
+ [73, "Hippy", false],
+ [74, "INVALID", false],
+ [75, "Prostitute", false],
+ [76, "Stewardess", false],
+ [77, "Homeless", false],
+ [78, "Homeless", false],
+ [79, "Homeless", false],
+ [80, "Boxer", false],
+ [81, "Boxer", false],
+ [82, "Black Elvis", false],
+ [83, "White Elvis", false],
+ [84, "Blue Elvis", false],
+ [85, "Prostitute", false],
+ [86, "INVALID", false],
+ [87, "Stripper", false],
+ [88, "Normal Ped", false],
+ [89, "Normal Ped", false],
+ [90, "Jogger", false],
+ [91, "Rich Woman", false],
+ [92, "Rollerskater", false],
+ [93, "Normal Ped", false],
+ [94, "Normal Ped", false],
+ [95, "Normal Ped", false],
+ [96, "Jogger", false],
+ [97, "Lifeguard", false],
+ [98, "Normal Ped", false],
+ [99, "Rollerskater", false],
+ [100, "Biker", false],
+ [101, "Normal Ped", false],
+ [102, "Ballas Gang Member", false],
+ [103, "Ballas Gang Member", false],
+ [104, "Ballas Gang Member", false],
+ [105, "Grove Street Families Gang Member", false],
+ [106, "Grove Street Families Gang Member", false],
+ [107, "Grove Street Families Gang Member", false],
+ [108, "Los Santos Vagos Gang Member", false],
+ [109, "Los Santos Vagos Gang Member", false],
+ [110, "Los Santos Vagos Gang Member", false],
+ [111, "Russian Mafioso", false],
+ [112, "Russian Mafioso", false],
+ [113, "Russian Mafioso", false],
+ [114, "Varios Los Aztecas Gang Member", false],
+ [115, "Varios Los Aztecas Gang Member", false],
+ [116, "Varios Los Aztecas Gang Member", false],
+ [117, "Triad", false],
+ [118, "Triad", false],
+ [119, "Johhny Sindacco", false],
+ [120, "Triad Boss", false],
+ [121, "Da Nang Boy", false],
+ [122, "Da Nang Boy", false],
+ [123, "Da Nang Boy", false],
+ [124, "Italian Mafioso", false],
+ [125, "Italian Mafioso", false],
+ [126, "Italian Mafioso", false],
+ [127, "Italian Mafioso", false],
+ [128, "Farm Inhabitant", false],
+ [129, "Farm Inhabitant", false],
+ [130, "Farm Inhabitant", false],
+ [131, "Farm Inhabitant", false],
+ [132, "Farm Inhabitant", false],
+ [133, "Farm Inhabitant", false],
+ [134, "Homeless", false],
+ [135, "Homeless", false],
+ [136, "Normal Ped", false],
+ [137, "Homeless", false],
+ [138, "Beach Visitor", false],
+ [139, "Beach Visitor", false],
+ [140, "Beach Visitor", false],
+ [141, "Businesswoman", false],
+ [142, "Taxi Driver", false],
+ [143, "Crack Maker", false],
+ [144, "Crack Maker", false],
+ [145, "Crack Maker", false],
+ [146, "Crack Maker", false],
+ [147, "Businessman", false],
+ [148, "Businesswoman", false],
+ [149, "INVALID", false],
+ [150, "Businesswoman", false],
+ [151, "Normal Ped", false],
+ [152, "Prostitute", false],
+ [153, "Construction Worker", false],
+ [154, "Beach Visitor", false],
+ [155, "Well Stacked Pizza Worker", false],
+ [156, "Barber", false],
+ [157, "Hillbilly", false],
+ [158, "Farmer", false],
+ [159, "Hillbilly", false],
+ [160, "Hillbilly", false],
+ [161, "Farmer", false],
+ [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],
+ [168, "Hotdog/Chilli Dog Vendor", false],
+ [169, "Normal Ped", false],
+ [170, "Normal Ped", false],
+ [171, "Blackjack Dealer", false],
+ [172, "Casino Croupier", false],
+ [173, "San Fierro Rifa", false],
+ [174, "San Fierro Rifa", false],
+ [175, "San Fierro Rifa", false],
+ [176, "Barber", false],
+ [177, "Barber", false],
+ [178, "Whore", false],
+ [179, "Ammunation Salesman", false],
+ [180, "Tattoo Artist", false],
+ [181, "Punk", false],
+ [182, "Cab Driver", false],
+ [183, "Normal Ped", false],
+ [184, "Normal Ped", false],
+ [185, "Normal Ped", false],
+ [186, "Normal Ped", false],
+ [187, "Businessman", false],
+ [188, "Normal Ped", false],
+ [189, "Valet", false],
+ [190, "Barbara Schternvart", false],
+ [191, "Helena Wankstein", false],
+ [192, "Michelle Cannes", false],
+ [193, "Katie Zhan", false],
+ [194, "Millie Perkins", false],
+ [195, "Denise Robinson", false],
+ [196, "Farm-Town Inhabitant", false],
+ [197, "Hillbilly", false],
+ [198, "Farm-Town Inhabitant", false],
+ [199, "Farm-Town Inhabitant", false],
+ [200, "Hillbilly", false],
+ [201, "Farmer", false],
+ [202, "Farmer", false],
+ [203, "Karate Teacher", false],
+ [204, "Karate Teacher", false],
+ [205, "Burger Shot Cashier", false],
+ [206, "Cab Driver", false],
+ [207, "Prostitute", false],
+ [208, "Su Xi Mu (Suzie)", false],
+ [209, "Oriental Noodle Stand Vendor", false],
+ [210, "Oriental Boating School Instructor", false],
+ [211, "Clothes Shop Staff", false],
+ [212, "Homeless", false],
+ [213, "Weird Old Man", false],
+ [214, "Waitress (Maria Latore)", false],
+ [215, "Normal Ped", false],
+ [216, "Normal Ped", false],
+ [217, "Clothes Shop Staff", false],
+ [218, "Normal Ped", false],
+ [219, "Rich Woman", false],
+ [220, "Cab Driver", false],
+ [221, "Normal Ped", false],
+ [222, "Normal Ped", false],
+ [223, "Normal Ped", false],
+ [224, "Normal Ped", false],
+ [225, "Normal Ped", false],
+ [226, "Normal Ped", false],
+ [227, "Oriental Businessman", false],
+ [228, "Oriental Ped", false],
+ [229, "Oriental Ped", false],
+ [230, "Homeless", false],
+ [231, "Normal Ped", false],
+ [232, "Normal Ped", false],
+ [233, "Normal Ped", false],
+ [234, "Cab Driver", false],
+ [235, "Normal Ped", false],
+ [236, "Normal Ped", false],
+ [237, "Prostitute", false],
+ [238, "Prostitute", false],
+ [239, "Homeless", false],
+ [240, "The D.A", false],
+ [241, "Afro-American", false],
+ [242, "Mexican", false],
+ [243, "Prostitute", false],
+ [244, "Stripper", false],
+ [245, "Prostitute", false],
+ [246, "Stripper", false],
+ [247, "Biker", false],
+ [248, "Biker", false],
+ [249, "Pimp", false],
+ [250, "Normal Ped", false],
+ [251, "Lifeguard", false],
+ [252, "Naked Valet", false],
+ [253, "Bus Driver", false],
+ [254, "Biker Drug Dealer", false],
+ [255, "Chauffeur (Limo Driver)", false],
+ [256, "Stripper", false],
+ [257, "Stripper", false],
+ [258, "Heckler", false],
+ [259, "Heckler", false],
+ [260, "Construction Worker", false],
+ [261, "Cab Driver", false],
+ [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],
+ [268, "Dwaine/Dwayne", 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],
+ [289, "Zero", false],
+ [290, "Ken Rosenberg", false],
+ [291, "Kent Paul", false],
+ [292, "Cesar Vialpando", 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],
+ [302, "Emmet", false],
+ [303, "Unknown", false],
+ [304, "Denise", false],
+ [305, "Jethro", false],
+ [306, "Zero", false],
+ [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],
+ ],
+ false,
+ [
+ [-2020305438,"Male Multiplayer",false],
+ [-641875910,"Female Multiplayer",false],
+ [-1370810922,"MODEL_SUPERLOD",false],
+ [1853617247,"Anna",false],
+ [-1646893330,"Anthony",false],
+ [1495769888,"Badman",false],
+ [1500493064,"Bernie Crane",false],
+ [1731510984,"Bledar",false],
+ [422305098,"Brian",false],
+ [-1729980128,"Brucie",false],
+ [237511807,"Bulgarin",false],
+ [88667657,"Charise",false],
+ [-1328445565,"Charlie Undercover",false],
+ [1343144208,"Clarence",false],
+ [1468450703,"Dardan",false],
+ [386513184,"Darko",false],
+ [1169442297,"Derric",false],
+ [237497537,"Dmitri",false],
+ [-617264103,"Dwayne",false],
+ [-1600585231,"Eddie",false],
+ [57218969,"Faustin",false],
+ [1710545037,"Francis",false],
+ [1424670436,"French Tom",false],
+ [2129490787,"Gordon",false],
+ [-357652594,"Gracie",false],
+ [980768434,"Hossan",false],
+ [-835225126,"Ilyena",false],
+ [-479595866,"Issac",false],
+ [1166762483,"Ivan",false],
+ [364686627,"Jay",false],
+ [170756246,"Jason",false],
+ [390357829,"Jeff",false],
+ [-366421228,"Jimmy",false],
+ [-911507684,"Johnny Klebitz",false],
+ [-773750838,"Kate",false],
+ [995576506,"Kenny",false],
+ [1487004273,"Lil Jacob",false],
+ [-1275031987,"Lil Jacob 2,",false],
+ [-681942840,"Luca",false],
+ [-492470690,"Luis",false],
+ [-1040287406,"Mallorie",false],
+ [-322700377,"Mam",false],
+ [1445589009,"Manny",false],
+ [411185872,"Marnie",false],
+ [-807339118,"Mel",false],
+ [735211577,"Michael",false],
+ [-1080659212,"Michelle",false],
+ [-636669566,"Mickey",false],
+ [1690783035,"Packie",false],
+ [-165448092,"Pathos",false],
+ [-1947682830,"Petrovic",false],
+ [-1826458934,"Phil Bell",false],
+ [1794146792,"Playboy X",false],
+ [954215094,"Ray Boccino",false],
+ [-587324132,"Ricky",false],
+ [-1992728631,"Roman",false],
+ [558221221,"Roman 2,",false],
+ [-17823883,"Sarah",false],
+ [1384833284,"Tuna",false],
+ [-1014976873,"Vinny Spaz",false],
+ [896408642,"Vlad",false],
+ [-301223260,"Black Street Thug 1,",false],
+ [-1143910864,"Black Street Thug 2,",false],
+ [869501081,"Black Street OG 1,",false],
+ [632613980,"Black Street OG 1,",false],
+ [-503930010,"Albanian Thug 1,",false],
+ [-235584669,"Albanian Thug 2,",false],
+ [207714363,"Albanian Thug 3,",false],
+ [514268366,"Albanian Thug 4,",false],
+ [43005364,"Biker 1,",false],
+ [1346668127,"Biker 2,",false],
+ [-1677255197,"Biker 3,",false],
+ [-1461281345,"Biker 4,",false],
+ [1574850459,"Biker 5,",false],
+ [-1953289472,"Biker 6,",false],
+ [280474699,"Irish Man 1,",false],
+ [-19263344,"Irish Man 2,",false],
+ [1844702918,"Irish Man 3,",false],
+ [1609755055,"Jamaican OG 1,",false],
+ [-330497431,"Jamaican OG 2,",false],
+ [1117105909,"Jamaican OG 3,",false],
+ [-1500397869,"Jamaican Thug 1,",false],
+ [-881358690,"Jamaican Thug 2,",false],
+ [1540383669,"Asian Man 1,",false],
+ [764249904,"Asian Man 2,",false],
+ [492147228,"Hispanic Man 1,",false],
+ [-1926041127,"Hispanic Man 2,",false],
+ [1168388225,"Hispanic Man 3,",false],
+ [-1746774780,"Hispanic Man 4,",false],
+ [-302362397,"Fat Italian Mafia Boss",false],
+ [-1616890832,"Italian Mafia Boss",false],
+ [64730935,"Italian Mafia Associate",false],
+ [510389335,"Fat Italian Mafia Associate",false],
+ [-1836006237,"Russian Thug 1,",false],
+ [-2088164056,"Russian Thug 2,",false],
+ [1976502708,"Russian Thug 3,",false],
+ [1543404628,"Russian Thug 4,",false],
+ [1865532596,"Russian Thug 5,",false],
+ [431692232,"Russian Thug 6,",false],
+ [1724587620,"Russian Thug 7,",false],
+ [-1180674815,"Russian Thug 8,",false],
+ [871281791,"Triad Boss 1,",false],
+ [683712035,"Triad Boss 2,",false],
+ [-1084007777,"Triad Member 3,",false],
+ [-164935626,"Triad Member 4,",false],
+ [-751071255,"Female Maid",false],
+ [-109247258,"Female Binco Worker",false],
+ [1366257926,"Female Bank Teller",false],
+ [346338575,"Female Doctor",false],
+ [1350216795,"Female Gym Worker",false],
+ [924926104,"Female Burger Shot Worker",false],
+ [-346378101,"Female Cluckin Bell Worker",false],
+ [-2104311883,"Female Rockstar Cafe Worker",false],
+ [212900845,"Female TW@ Cafe Worker",false],
+ [-290070895,"Female Well Stacked Pizza Worker",false],
+ [552542187,"Hooker",false],
+ [996267216,"Hooker 2,",false],
+ [-1193778389,"Nurse",false],
+ [1113677074,"Stripper 1,",false],
+ [1353709999,"Stripper 2,",false],
+ [24233425,"Waitress",false],
+ [-1761003415,"Alcoholic Man",false],
+ [1075583233,"Armoured Truck Driver",false],
+ [134077503,"Bus Driver",false],
+ [757349871,"Generic Asian Man",false],
+ [-1827421800,"Black Crackhead",false],
+ [219393781,"Doctor (Scrubs)",false],
+ [-1186940778,"Doctor",false],
+ [375732086,"Doctor (Blood Covered Coat)",false],
+ [2105015949,"Cook",false],
+ [-200234085,"Italian Mob Enforcer",false],
+ [800131009,"Factory Worker",false],
+ [-999506922,"FIB Agent",false],
+ [-1993909080,"Fat Delivery Driver",false],
+ [610888851,"Fire Chief",false],
+ [486302863,"Mercenary Soldier",false],
+ [-778316080,"Helicopter Pilot",false],
+ [624314380,"Hotel Doorman",false],
+ [-1784833142,"Korean Cook",false],
+ [-1852976689,"Lawyer 1,",false],
+ [-1134712978,"Lawyer 2,",false],
+ [379171768,"Loony Black Man",false],
+ [-1945168882,"Pilot",false],
+ [807236245,"Generic Man",false],
+ [-284362863,"Postal Worker",false],
+ [-1188246269,"Saxophone Player",false],
+ [-1870989171,"Security Guard",false],
+ [420915580,"Stadium Food Vendor",false],
+ [1878085135,"Stadium Food Cook",false],
+ [142730876,"Street Food Vendor",false],
+ [-690681764,"Street Sweeper Driver",false],
+ [8772846,"Taxi Driver",false],
+ [1186270890,"Telephone Company Worker",false],
+ [-379234846,"Tennis Player",false],
+ [1159759556,"Train Conductor",false],
+ [-142386662,"Homeless Black Man",false],
+ [-46564867,"Trucker",false],
+ [-1284047560,"Janitor",false],
+ [22944263,"Hotel Doorman 2,",false],
+ [1178487645,"Mob Boss",false],
+ [-1464712858,"Airport Worker",false],
+ [-2139064254,"Bartender",false],
+ [-1780698891,"Biker Bouncer",false],
+ [-409283472,"High End Club Bouncer",false],
+ [-799229885,"Bowling Alley Worker",false],
+ [-434183225,"Bowling Alley Worker 2,",false],
+ [768442188,"Chinese Food Vendor",false],
+ [676448572,"Club Security",false],
+ [-722019798,"Construction Worker",false],
+ [-1015957728,"Construction Worker 2,",false],
+ [-714220780,"Construction Worker 3,",false],
+ [-183203150,"Police Officer",false],
+ [-1518937979,"Traffic Officer",false],
+ [-370395528,"Fat Police Officer",false],
+ [-1371133859,"Courier",false],
+ [-573788283,"Cowboy 1,",false],
+ [-1283406538,"Drug Dealer 1,",false],
+ [1448755353,"Drug Dealer 2,",false],
+ [989485,"Male Burger Shot Worker",false],
+ [-1011530423,"Male Cluckin Bell Worker",false],
+ [1979561477,"Male Rockstar Cafe Worker",false],
+ [-786449781,"Male TW@ Cafe Worker",false],
+ [206941425,"Male Well Stacked Pizza Worker",false],
+ [-610224615,"Firefighter",false],
+ [1136499716,"Garbage Collector",false],
+ [897868981,"Goon",false],
+ [-1902758612,"Male Gym Worker",false],
+ [-356904519,"Mechanic 2,",false],
+ [-1056268969,"Male Modo Worker",false],
+ [1201610759,"Helicopter Pilot",false],
+ [-151000142,"Perseus",false],
+ [501136335,"Generic Male 1,",false],
+ [186619473,"Generic Male 2,",false],
+ [-111611196,"Generic Male 3,",false],
+ [-1175077216,"Paramedic",false],
+ [-1676937780,"Prisoner",false],
+ [215190023,"Prisoner 2,",false],
+ [1552970117,"Roman's Taxi Service Driver",false],
+ [-1481923910,"Male Runner",false],
+ [357919731,"Male Shop Assistant 1,",false],
+ [-89302119,"State Trooper",false],
+ [-1004762946,"SWAT",false],
+ [-64233032,"Sword Swallower",false],
+ [-1292254815,"Thief",false],
+ [271284208,"Valet",false],
+ [-186113957,"Vendor",false],
+ [-2015686009,"French Tom",false],
+ [1977784957,"Jim Fitz",false],
+ [-203833294,"East European Woman",false],
+ [189853472,"East European Woman 2,",false],
+ [-349043578,"Woman",false],
+ [-114937692,"Jersey Woman",false],
+ [-1697333660,"Oriental Woman",false],
+ [100706569,"Rich Woman",false],
+ [155063868,"Business Woman 1,",false],
+ [394310337,"Business Woman 2,",false],
+ [1375728805,"Chinatown Woman",false],
+ [-284229525,"Business Woman 3,",false],
+ [677687516,"East European Woman 3,",false],
+ [-1188238883,"Fat Black Woman",false],
+ [-2075220936,"Jersey Woman 1,",false],
+ [-1356924456,"Jersey Woman 2,",false],
+ [812112483,"Fat Hispanic Woman 1,",false],
+ [-129242580,"Fat Hispanic Woman 2,",false],
+ [852423121,"White Manhattan Woman",false],
+ [76551508,"Black Manhattan Woman",false],
+ [-2118501976,"Old Asian Woman",false],
+ [1616769823,"Old Rich Woman",false],
+ [453889158,"Business Woman 4,",false],
+ [824245375,"Asian Woman in Dress",false],
+ [-1362442041,"Fat Black Bronx Woman",false],
+ [-1788328884,"Random White Woman",false],
+ [-1523915823,"Random Hispanic Woman",false],
+ [-949987237,"Random Eastern European Woman",false],
+ [-1926577323,"Random Black Woman",false],
+ [168065679,"Black Harlem Woman 1,",false],
+ [441464,"Fat Jersey Woman 1,",false],
+ [54114008,"Fat Hispanic Woman 3,",false],
+ [-292713088,"Hispanic Woman 1,",false],
+ [1743814728,"Hispanic Woman 2,",false],
+ [1670568326,"Manhattan Woman 1,",false],
+ [1354281938,"Manhattan Woman 2,",false],
+ [1056837725,"Manhattan Woman 1,",false],
+ [-1193633577,"Asian Woman 1,",false],
+ [713691120,"Black Woman 2,",false],
+ [-1780385799,"Rich White Woman 1,",false],
+ [-952185135,"Asian Woman",false],
+ [1586287288,"Female Shopper 1,",false],
+ [1848013291,"Female Shopper 2,",false],
+ [-1702036227,"Female Shopper 3,",false],
+ [1182843182,"Female Socialite 1,",false],
+ [-900623157,"Street Woman 1,",false],
+ [286007875,"Street Woman 2,",false],
+ [1473654742,"Street Woman 3,",false],
+ [-1850743775,"Street Woman 4,",false],
+ [1290755317,"Street Woman 5,",false],
+ [1872110126,"Street Woman 6,",false],
+ [1754440500,"Tourist Woman 1,",false],
+ [761763258,"MODEL_F_Y_VILLBO_01,",false],
+ [-636579119,"Business Man 1,",false],
+ [-1754526315,"Business Man 2,",false],
+ [-1516474414,"Street Criminal 1,",false],
+ [-1821258883,"Street Criminal 2,",false],
+ [1952671026,"Obese Mafia Thug",false],
+ [-1991603022,"Gay Man 1,",false],
+ [-1080673049,"Homeless Bum 1,",false],
+ [495499562,"Loony White Man 1,",false],
+ [-1984134881,"MODEL_M_M_MIDTOWN_01,",false],
+ [1063816580,"Business Man 2,",false],
+ [208763854,"Eastern European Man 1,",false],
+ [-1020237172,"Fat Black Man 2,",false],
+ [1782277836,"MODEL_M_M_PINDUS_02,",false],
+ [-1402442039,"Fat Italian Man 1,",false],
+ [-1628417063,"Italian Man 2,",false],
+ [1158569407,"Hispanic Man 1,",false],
+ [1969438324,"Hispanic Man 2,",false],
+ [1621955848,"Hispanic Man 3,",false],
+ [-657489059,"Tourist Man 1,",false],
+ [-1307068958,"Black Business Man 1,",false],
+ [734334931,"Asian Man 3,",false],
+ [1865082075,"MODEL_M_M_PRICH_01,",false],
+ [-432593815,"MODEL_M_O_EASTEURO_01,",false],
+ [-1639359785,"Hasidic Jewish Man 1,",false],
+ [1656087115,"Old Man 1,",false],
+ [2034185905,"MODEL_M_O_PEASTEURO_02,",false],
+ [1316404726,"MODEL_M_O_PHARBRON_01,",false],
+ [980990533,"MODEL_M_O_PJERSEY_01,",false],
+ [-1298691925,"MODEL_M_O_STREET_01,",false],
+ [243672348,"Old Business Man",false],
+ [2085884255,"MODEL_M_Y_BOHO_01,",false],
+ [221246143,"MODEL_M_Y_BOHOGUY_01,",false],
+ [52357603,"MODEL_M_Y_BRONX_01,",false],
+ [1530937394,"Black Business Man 2,",false],
+ [690281432,"Black Business Man 3,",false],
+ [-1149743642,"Asian Man 4,",false],
+ [-314369597,"Chopshop Mechanic 1,",false],
+ [-552829610,"Chopshop Mechanic 2,",false],
+ [-1097188138,"MODEL_M_Y_DODGY_01,",false],
+ [-1775659292,"MODEL_M_Y_DORK_02,",false],
+ [1207402441,"MODEL_M_Y_DOWNTOWN_01,",false],
+ [1500619449,"MODEL_M_Y_DOWNTOWN_02,",false],
+ [594261682,"MODEL_M_Y_DOWNTOWN_03,",false],
+ [-747824291,"MODEL_M_Y_GAYYOUNG",false],
+ [-677160979,"MODEL_M_Y_GENSTREET_11,",false],
+ [-1678614360,"MODEL_M_Y_GENSTREET_16,",false],
+ [989044076,"MODEL_M_Y_GENSTREET_20,",false],
+ [1180218190,"MODEL_M_Y_GENSTREET_34,",false],
+ [-1420592428,"MODEL_M_Y_HARDMAN_01,",false],
+ [-1222963415,"MODEL_M_Y_HARLEM_01,",false],
+ [-1746153269,"MODEL_M_Y_HARLEM_02,",false],
+ [2104499156,"MODEL_M_Y_HARLEM_04,",false],
+ [-1874580889,"Hasidic Jewish Man 2,",false],
+ [-1055386282,"MODEL_M_Y_LEASTSIDE_01,",false],
+ [575808580,"MODEL_M_Y_PBRONX_01,",false],
+ [-71980543,"MODEL_M_Y_PCOOL_01,",false],
+ [-195159218,"MODEL_M_Y_PCOOL_02,",false],
+ [697247370,"MODEL_M_Y_PEASTEURO_01,",false],
+ [670406267,"MODEL_M_Y_PHARBRON_01,",false],
+ [26615298,"MODEL_M_Y_PHARLEM_01,",false],
+ [1542927558,"MODEL_M_Y_PJERSEY_01,",false],
+ [-1806886352,"MODEL_M_Y_PLATIN_01,",false],
+ [-1022920796,"MODEL_M_Y_PLATIN_02,",false],
+ [-1326394505,"MODEL_M_Y_PLATIN_03,",false],
+ [607901190,"MODEL_M_Y_PMANHAT_01,",false],
+ [1968470106,"MODEL_M_Y_PMANHAT_02,",false],
+ [-344136289,"MODEL_M_Y_PORIENT_01,",false],
+ [560413584,"MODEL_M_Y_PQUEENS_01,",false],
+ [1352017873,"MODEL_M_Y_PRICH_01,",false],
+ [223726252,"MODEL_M_Y_PVILLBO_01,",false],
+ [-1252681043,"MODEL_M_Y_PVILLBO_02,",false],
+ [-1562020391,"MODEL_M_Y_PVILLBO_03,",false],
+ [1223224881,"MODEL_M_Y_QUEENSBRIDGE",false],
+ [-1220737489,"MODEL_M_Y_SHADY_02,",false],
+ [1755322862,"MODEL_M_Y_SKATEBIKE_01,",false],
+ [386690478,"MODEL_M_Y_SOHO_01,",false],
+ [62496225,"MODEL_M_Y_STREET_01,",false],
+ [523785438,"MODEL_M_Y_STREET_03,",false],
+ [813889395,"MODEL_M_Y_STREET_04,",false],
+ [-1552214124,"MODEL_M_Y_STREETBLK_02,",false],
+ [-650575089,"MODEL_M_Y_STREETBLK_03,",false],
+ [-740078918,"Street Punk 1,",false],
+ [-1927496394,"Street Punk 2,",false],
+ [1374242512,"Street Punk 3,",false],
+ [-1139941790,"Tough Guy",false],
+ [809067472,"Male Tourist",false],
+ ]
];
let placesOfOrigin = [
@@ -427,10 +1282,14 @@ app.init = function()
newCharacter.placeOfOrigin.item(placesOfOrigin[i]);
}
- newCharacter.placeOfOrigin.axis.y.scrollBar.styles.innerBar.backgroundColour = toColour(255, 128, 0, 200);
+ newCharacter.placeOfOrigin.axis.y.scrollBar.styles.innerBar.backgroundColour = toColour(primaryColour[gta.game][0], primaryColour[gta.game][1], primaryColour[gta.game][2], 200);
newCharacter.placeOfOrigin.setScrollBarsManual(true);
- newCharacter.skinImage = newCharacter.window.image(265, 30, 110, 70, "files/images/skins/gta3/Skin000.png");
+ if(gta.game == GAME_GTA_III) {
+ newCharacter.skinImage = newCharacter.window.image(265, 30, 110, 70, "files/images/skins/gta3/Skin000.png");
+ } else {
+ newCharacter.skinImage = newCharacter.window.image(265, 30, 110, 70, "files/images/skins/none.png");
+ }
newCharacter.skinDropDown = newCharacter.window.dropDown(220, 100, 200, 25, 'Choose Skin', {
main: {
@@ -472,7 +1331,11 @@ app.init = function()
if(newCharacter.skinImage != null) {
newCharacter.skinImage.remove();
}
- newCharacter.skinImage = newCharacter.window.image(265, 30, 110, 70, "files/images/skins/gta3/" + skinImagePath.toString());
+ if(gta.game == GAME_GTA_III) {
+ newCharacter.skinImage = newCharacter.window.image(265, 30, 110, 70, "files/images/skins/gta3/" + skinImagePath.toString());
+ } else {
+ newCharacter.skinImage = newCharacter.window.image(265, 30, 110, 70, "files/images/skins/none.png");
+ }
});
newCharacter.skinDropDown.axis.y.scrollBar.styles.innerBar.backgroundColour = toColour(255, 128, 0, 200);
newCharacter.skinDropDown.setScrollBarsManual(true);
@@ -482,6 +1345,7 @@ app.init = function()
newCharacter.skinDropDown.item(skinNames[gta.game][i][1]);
}
}
+ newCharacter.skinDropDown.selectedEntryIndex = 1;
newCharacter.createButton = newCharacter.window.button(220, 130, 200, 25, 'CREATE', {
main: {
@@ -497,7 +1361,7 @@ app.init = function()
register.window = mexui.window(game.width/2-130, game.height/2-140, 300, 260, 'Register', {
main: {
- backgroundColour: toColour(0, 0, 0, 120),
+ backgroundColour: toColour(0, 0, 0, windowAlpha),
},
title: {
textSize: 0.0,
@@ -616,7 +1480,7 @@ app.init = function()
errorDialog.window = mexui.window(game.width/2-200, game.height/2-70, 400, 140, 'ERROR', {
main: {
- backgroundColour: toColour(0, 0, 0, 120),
+ backgroundColour: toColour(0, 0, 0, windowAlpha),
},
title: {
textSize: 11.0,
@@ -653,7 +1517,7 @@ app.init = function()
yesNoDialog.window = mexui.window(game.width/2-200, game.height/2-70, 400, 140, 'Question', {
main: {
- backgroundColour: toColour(0, 0, 0, 120),
+ backgroundColour: toColour(0, 0, 0, windowAlpha),
},
title: {
textSize: 11.0,
@@ -700,7 +1564,7 @@ app.init = function()
infoDialog.window = mexui.window(game.width/2-200, game.height/2-70, 400, 140, 'Information', {
main: {
- backgroundColour: toColour(0, 0, 0, 120),
+ backgroundColour: toColour(0, 0, 0, windowAlpha),
},
title: {
textSize: 11.0,
@@ -737,7 +1601,7 @@ app.init = function()
characterSelect.window = mexui.window(game.width/2-215, game.height/2-83, 430, 166, 'Select Character', {
main: {
- backgroundColour: toColour(0, 0, 0, 120),
+ backgroundColour: toColour(0, 0, 0, windowAlpha),
},
title: {
textSize: 11.0,
@@ -949,6 +1813,7 @@ let yesNoDialogAnswerYes = function() {
// ---------------------------------------------------------------------------
let showRegistration = function() {
+ setChatWindowEnabled(false);
closeAllWindows();
mexui.setInput(true);
register.window.shown = true;
@@ -957,6 +1822,7 @@ let showRegistration = function() {
// ---------------------------------------------------------------------------
let showLogin = function() {
+ setChatWindowEnabled(false);
closeAllWindows();
mexui.setInput(true);
login.window.shown = true;
@@ -966,6 +1832,7 @@ let showLogin = function() {
let showCharacterSelect = function(firstName, lastName, placeOfOrigin, dateOfBirth, skinId) {
closeAllWindows();
+ setChatWindowEnabled(false);
mexui.setInput(true);
characterSelect.nameText.text = lastName + ", " + firstName;
@@ -992,6 +1859,7 @@ let showCharacterSelect = function(firstName, lastName, placeOfOrigin, dateOfBir
// ---------------------------------------------------------------------------
let showError = function(errorMessage, errorTitle) {
+ setChatWindowEnabled(false);
closeAllWindows();
mexui.setInput(true);
errorDialog.messageLabel.text = errorMessage;
@@ -1010,6 +1878,7 @@ let showYesNo = function(promptMessage, promptTitle) {
// ---------------------------------------------------------------------------
let showInfo = function(infoMessage, infoTitle) {
+ setChatWindowEnabled(false);
closeAllWindows();
mexui.setInput(true);
infoDialog.messageLabel.text = infoMessage;
@@ -1019,6 +1888,7 @@ let showInfo = function(infoMessage, infoTitle) {
// ---------------------------------------------------------------------------
let showNewCharacter = function() {
+ setChatWindowEnabled(false);
closeAllWindows();
mexui.setInput(true);
newCharacter.window.shown = true;
@@ -1045,11 +1915,11 @@ let selectThisCharacter = function() {
// ---------------------------------------------------------------------------
let switchCharacterSelect = function(firstName, lastName, placeOfOrigin, dateOfBirth, skinId) {
+ setChatWindowEnabled(false);
characterSelect.window.shown = false;
characterSelect.nameText.text = lastName + ", " + firstName;
characterSelect.dateOfBirthText.text = "Born: " + String(dateOfBirth);
characterSelect.placeOfOrigin.text = "From: " + String(placeOfOrigin);
-
if(characterSelect.skinImage != null) {
characterSelect.skinImage.remove();
@@ -1132,6 +2002,7 @@ addNetworkHandler("ag.loginSuccess", function() {
addNetworkHandler("ag.characterSelectSuccess", function() {
characterSelectSuccess();
+ setChatWindowEnabled(true);
});
// ---------------------------------------------------------------------------
diff --git a/scripts/client/main.js b/scripts/client/main.js
index 6450d45b..e1d3a23c 100644
--- a/scripts/client/main.js
+++ b/scripts/client/main.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2020 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: main.js
// DESC: Main client script (will be reorganized into individual files later)
@@ -11,20 +11,38 @@
let allServerBlips = [];
let currentServerBlips = [];
+let bigMessageFont = null;
+let mainLogo = null;
+
+let showLogo = true;
+
+// ---------------------------------------------------------------------------
+
addNetworkHandler("ag.connectCamera", function(cameraPosition, cameraLookat) {
- gta.fadeCamera(true);
- gta.setCameraLookAt(cameraPosition, cameraLookat, true);
+ //if(gta.game < GAME_GTA_IV) {
+ gta.fadeCamera(true);
+ gta.setCameraLookAt(cameraPosition, cameraLookat, true);
+ //}
+});
+
+// ---------------------------------------------------------------------------
+
+addNetworkHandler("ag.restoreCamera", function() {
+ //if(gta.game < GAME_GTA_IV) {
+ gta.restoreCamera(true);
+ //}
+});
+
+// ---------------------------------------------------------------------------
+
+addNetworkHandler("ag.logo", function(state) {
+ showLogo = state;
});
// ---------------------------------------------------------------------------
addEventHandler("onPickupCollected", function(event, pickup, ped) {
console.log(`PICKUP COLLECTED: Ped ${ped.id}, ${pickup.id}`);
-
- // This won't be needed in next GTAC update. onPickupCollccted has been added server side
- if(ped == localPlayer) {
- triggerNetworkEvent("ag.onPickupCollected", pickup);
- }
});
// ---------------------------------------------------------------------------
@@ -41,6 +59,20 @@ addNetworkHandler("ag.giveWeapon", function(weaponId, ammo, active) {
// ---------------------------------------------------------------------------
+addNetworkHandler("ag.showRegisterMessage", function() {
+ showRegisterMessage = true;
+ showLoginMessage = false;
+});
+
+// ---------------------------------------------------------------------------
+
+addNetworkHandler("ag.showLoginMessage", function() {
+ showLoginMessage = true;
+ showRegisterMessage = false;
+});
+
+// ---------------------------------------------------------------------------
+
function syncVehicle(vehicle) {
if(vehicle.getData("ag.lights") != null) {
let lights = vehicle.getData("ag.lights");
@@ -143,8 +175,27 @@ function attemptToShowBlipsOnSpawn(ped) {
// ---------------------------------------------------------------------------
-addNetworkHandler("ag.skin", function(ped, skin) {
- ped.skin = skin;
+addNetworkHandler("ag.skin", function(skin) {
+ localPlayer.skin = skin;
+});
+
+// ---------------------------------------------------------------------------
+
+addNetworkHandler("ag.position", function(position) {
+ localPlayer.position = position;
+});
+
+// ---------------------------------------------------------------------------
+
+addNetworkHandler("ag.interior", function(interior) {
+ localPlayer.interior = interior;
+ cameraInterior = interior;
+});
+
+// ---------------------------------------------------------------------------
+
+addNetworkHandler("ag.dimension", function(dimension) {
+ localPlayer.dimension = dimension;
});
// ---------------------------------------------------------------------------
@@ -156,26 +207,83 @@ addNetworkHandler("ag.removeFromVehicle", function() {
// ---------------------------------------------------------------------------
function initLocalPlayer(player) {
- attemptToShowBlipsOnSpawn(player)
- bindEventHandler("onEntityProcess", localPlayer, processLocalPlayerEntity);
+ attemptToShowBlipsOnSpawn(player);
+ if(gta.game < GAME_GTA_IV) {
+ addEventHandler("onProcess", processEvent);
+ }
}
// ---------------------------------------------------------------------------
-function processLocalPlayerEntity(event, player) {
+function processEvent(event, deltaTime) {
getElementsByType(ELEMENT_MARKER).forEach(function(sphere) {
- if(player.position.distance(sphere.position) <= sphere.radius) {
- if(player.getData("ag.inSphere") == null) {
- player.setData("ag.inSphere", sphere);
+ if(localPlayer.position.distance(sphere.position) <= sphere.radius) {
+ if(localPlayer.getData("ag.inSphere") == null) {
+ localPlayer.setData("ag.inSphere", sphere);
triggerNetworkEvent("ag.onPlayerEnterSphere", sphere);
}
} else {
- if(player.getData("ag.inSphere")) {
- player.removeData("ag.inSphere", sphere);
+ if(localPlayer.getData("ag.inSphere")) {
+ localPlayer.removeData("ag.inSphere", sphere);
triggerNetworkEvent("ag.onPlayerExitSphere", sphere);
}
}
});
}
-// ---------------------------------------------------------------------------
\ No newline at end of file
+// ---------------------------------------------------------------------------
+
+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);
+ drawing.drawRectangle(mainLogo, logoPos, logoSize);
+
+ let y = gta.height/2+10;
+
+ bigMessageFont.render(`Welcome back to Asshat Gaming, ${localClient.name}`, [gta.width/2, y], gta.width, 0.0, 0.0, bigMessageFont.size, COLOUR_WHITE, false, false, false, true);
+ y += 18;
+ bigMessageFont.render(`Please /login to access your account`, [gta.width/2, y], gta.width, 0.0, 0.0, bigMessageFont.size, COLOUR_WHITE, false, false, false, true);
+ }
+
+ if(showRegisterMessage) {
+ let logoPos = new Vec2(gta.width/2-128, gta.height/2-256);
+ let logoSize = new Vec2(256, 256);
+ drawing.drawRectangle(mainLogo, logoPos, logoSize);
+
+ let y = gta.height/2+10;
+
+ bigMessageFont.render(`Welcome to Asshat Gaming, ${localClient.name}`, [gta.width/2, y], gta.width, 0.0, 0.0, bigMessageFont.size, COLOUR_WHITE, false, false, false, true);
+ y += 18;
+ bigMessageFont.render(`Please /register to create an account`, [gta.width/2, y], gta.width, 0.0, 0.0, bigMessageFont.size, COLOUR_WHITE, false, false, false, true);
+ }
+ */
+ }
+
+ // 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);
+ drawing.drawRectangle(mainLogo, logoPos, logoSize);
+ }
+});
+
+// ---------------------------------------------------------------------------
+
+addEventHandler("OnResourceStart", function(event, resource) {
+ if(resource == thisResource) {
+ let fontStream = openFile("files/fonts/pricedown.ttf");
+ if(fontStream != null) {
+ bigMessageFont = lucasFont.createFont(fontStream, 28.0);
+ fontStream.close();
+ }
+
+ let logoStream = openFile("files/images/main-logo.png");
+ if(logoStream != null) {
+ mainLogo = drawing.loadPNG(logoStream);
+ logoStream.close();
+ }
+ }
+});
\ No newline at end of file
diff --git a/scripts/client/nametags.js b/scripts/client/nametags.js
index 8d5b32f5..4d57d6fc 100644
--- a/scripts/client/nametags.js
+++ b/scripts/client/nametags.js
@@ -1,4 +1,12 @@
-"use strict";
+// ===========================================================================
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
+// ---------------------------------------------------------------------------
+// FILE: nametags.js
+// DESC: Provides nametags for VRS
+// TYPE: Client (JavaScript)
+// ===========================================================================
// ----------------------------------------------------------------------------
@@ -20,22 +28,7 @@ addEventHandler("OnResourceReady", function(event, resource) {
// ----------------------------------------------------------------------------
-function createColour(alpha, red, green, blue) {
- return alpha << 24 | red << 16 | green << 8 | blue;
-}
-
-// ----------------------------------------------------------------------------
-
-function getDistance(pos1, pos2) {
- let dx = pos1[0] - pos2[0];
- let dy = pos1[1] - pos2[1];
- let dz = pos1[2] - pos2[2];
- return Math.sqrt(dx*dx + dy*dy + dz*dz);
-}
-
-// ----------------------------------------------------------------------------
-
-function drawNametag(x, y, health, armour, text, ping, alpha, distance, colour, afk) {
+function drawNametag(x, y, health, armour, text, ping, alpha, distance, colour, afk, skin) {
if(nametagFont == null) {
return false;
}
@@ -49,18 +42,21 @@ function drawNametag(x, y, health, armour, text, ping, alpha, distance, colour,
// -------------------------------------------
// Health Bar
- if(skin == 109) {
- y -= 20;
- } else {
- y -= 5;
- }
+ if(gta.game == GAME_GTA_III) {
+ // Mickey Hamfists is ridiculously tall. Raise the nametag for him a bit
+ if(skin == 109) {
+ y -= 20;
+ } else {
+ y -= 5;
+ }
+ }
if(health > 0.0) {
let hx = x-width/2;
let hy = y-10/2;
let colourB = toColour(0, 0, 0, Math.floor(255.0*alpha)); // Background colour (black)
drawing.drawRectangle(null, [hx, hy], [width, 8], colourB, colourB, colourB, colourB);
- let colour = createColour(Math.floor(255.0*alpha), Math.floor(255.0-(health*255.0)), Math.floor(health*255.0), 0); // Health bar colour (varies, depending on health)
+ let colour = toColour(Math.floor(255.0*alpha), Math.floor(255.0-(health*255.0)), Math.floor(health*255.0), 0); // Health bar colour (varies, depending on health)
drawing.drawRectangle(null, [hx+2, hy+2], [(width-4)*health, 10-6], colour, colour, colour, colour);
}
@@ -71,9 +67,9 @@ function drawNametag(x, y, health, armour, text, ping, alpha, distance, colour,
y -= 10;
let hx = x-width/2;
let hy = y-10/2;
- let colourB = createColour(Math.floor(255.0*alpha), 0, 0, 0); // Background colour (black)
+ let colourB = toColour(Math.floor(255.0*alpha), 0, 0, 0); // Background colour (black)
drawing.drawRectangle(null, [hx, hy], [width, 8], colourB, colourB, colourB, colourB);
- let colour = createColour(Math.floor(255.0*alpha), 255, 255, 255); // Armour bar colour (white)
+ let colour = toColour(Math.floor(255.0*alpha), 255, 255, 255); // Armour bar colour (white)
drawing.drawRectangle(null, [hx+2, hy+2], [(width-4)*armour, 10-6], colour, colour, colour, colour);
}
@@ -82,7 +78,7 @@ function drawNametag(x, y, health, armour, text, ping, alpha, distance, colour,
// Nametag
if(nametagFont != null) {
let size = nametagFont.measure(text, game.width, 0.0, 0.0, nametagFont.size, false, false);
- let colourT = createColour(Math.floor(255.0*alpha), 255, 255, 255);
+ let colourT = toColour(Math.floor(255.0*alpha), 255, 255, 255);
nametagFont.render(text, [x-size[0]/2, y-size[1]/2], game.width, 0.0, 0.0, nametagFont.size, colour, false, false, false, true);
}
@@ -95,18 +91,7 @@ function drawNametag(x, y, health, armour, text, ping, alpha, distance, colour,
let size = afkStatusFont.measure("PAUSED", game.width, 0.0, 0.0, afkStatusFont.size, false, false);
afkStatusFont.render("PAUSED", [x-size[0]/2, y-size[1]/2], game.width, 0.0, 0.0, afkStatusFont.size, toColour(255, 0, 0, 255), false, false, false, true);
}
- }
-
- // Go up another 50 pixels for the next part
- //y -= 30;
-
- //if(ping != -1) {
- // if(pingFont != null) {
- // let size2 = pingFont.measure(ping, game.width, 0.0, 0.0, pingFont.size, false, false);
- // let colourT2 = createColour(Math.floor(255.0*alpha), 255, 255, 255);
- // pingFont.render(ping, [x-size2[0]/2, y-size2[1]/2], game.width, 0.0, 0.0, pingFont.size, colourT2, false, false, false, true);
- // }
- //}
+ }
}
// ----------------------------------------------------------------------------
@@ -132,27 +117,26 @@ function updateNametags(element) {
armour = 1.0;
}
- let distance = getDistance(playerPos, elementPos);
- if(distance < nametagDistance) {
+ let distance = playerPos.distance(elementPos);
+ if(distance <= nametagDistance) {
if(element.type == ELEMENT_PLAYER) {
-
let name = element.name;
let colour = COLOUR_WHITE;
let afk = false;
- if(element.getData("ag.name") != null) {
- name = element.getData("ag.name");
+ if(client.getData("ag.name") != null) {
+ name = client.getData("ag.name");
}
- if(element.getData("ag.afk") != null) {
+ if(client.getData("ag.afk") != null) {
afk = true;
}
- if(element.getData("ag.colour") != null) {
- colour = element.getData("ag.colour");
- }
+ if(client.getData("ag.colour") != null) {
+ colour = client.getData("ag.colour");
+ }
- drawNametag(screenPos[0], screenPos[1], health, armour, name, 0, 1.0-distance/nametagDistance, distance, colour, afk);
+ drawNametag(screenPos[0], screenPos[1], health, armour, name, 0, 1.0-distance/nametagDistance, distance, colour, afk, element.skin);
}
}
}
@@ -162,31 +146,23 @@ function updateNametags(element) {
// ----------------------------------------------------------------------------
function getClientFromPlayer(player) {
- let clients = getClients();
- for(let i in clients) {
- if(clients[i].player == player) {
- return clients[i];
+ getClients().forEach(function(client) {
+ if(client.player == player) {
+ return client;
}
- }
+ });
}
// ----------------------------------------------------------------------------
-addNetworkHandler("armour", function(client, ped, armour) {
- if(ped != null) {
- ped.armour = armour;
- }
-});
-
-// ----------------------------------------------------------------------------
-
addEventHandler("OnDrawnHUD", function(event) {
- let peds = getPeds();
- for(let i in peds) {
- if(peds[i] != localPlayer) {
- updateNametags(peds[i]);
- }
- }
+ //if(gta.game >= GAME_GTA_IV) {
+ // return false;
+ //}
+
+ //getElementsByType(ELEMENT_PLAYER).forEach(function(player) {
+ // updateNametags(player)
+ //})
});
// ----------------------------------------------------------------------------
\ No newline at end of file
diff --git a/scripts/server/account.js b/scripts/server/account.js
index 39f664bc..6933a030 100644
--- a/scripts/server/account.js
+++ b/scripts/server/account.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2020 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: account.js
// DESC: Provides account functions and usage
@@ -57,13 +57,7 @@ function loginCommand(command, params, client) {
return false;
}
- if(isAccountPasswordCorrect(getClientData(client).accountData, hashAccountPassword(client.name, params))) {
- messageClientError(client, "Incorrect username or password!");
- return false;
- }
-
- loginSuccess(client);
- //messageClientSuccess(client, "You have been logged in! Press left CTRL to spawn.");
+ checkLogin(client, params);
return true;
}
@@ -99,20 +93,10 @@ function registerCommand(command, params, client) {
return false;
}
- if(!doesPasswordMeetRequirements(params)) {
- return false
- }
-
- let accountData = createAccount(client.name, params);
- if(!accountData) {
- messageClientError(client, "Something went wrong, and your account could not be created!");
- messageClientAlert(client, "Asshat Gaming staff have been notified of the problem and will fix it shortly.");
- return false;
- }
-
- getClientData(client).accountData = accountData;
- messageClientSuccess(client, "Your account has been created!");
- messageClientAlert(client, "To play on the server, you will need to make a character.");
+ checkRegistration(client, params);
+ //getClientData(client).accountData = accountData;
+ //messageClientSuccess(client, "Your account has been created!");
+ //messageClientAlert(client, "To play on the server, you will need to make a character.");
}
// ---------------------------------------------------------------------------
@@ -129,7 +113,7 @@ function changePasswordCommand(command, params, client) {
if(!isCommandAllowedOnDiscord(command)) {
messageClientError(client, "That command isn't available on discord!");
return false;
- }
+ }
}
if(!doesClientHaveStaffPermission(client, getCommandRequiredPermissions(command))) {
@@ -186,12 +170,77 @@ function switchCharacterCommand(command, params, client) {
getClientCurrentSubAccount(client).spawnPosition = client.player.position;
getClientCurrentSubAccount(client).spawnHeading = client.player.heading;
- let tempSubAccount = getClientCurrentSubAccount(client);
- saveSubAccountToDatabase(tempSubAccount);
+ saveSubAccountToDatabase(getClientCurrentSubAccount(client));
client.despawnPlayer();
- triggerNetworkEvent("ag.connectCamera", client, serverConfig.connectCameraPosition[getServerGame()], serverConfig.connectCameraLookAt[getServerGame()]);
- triggerNetworkEvent("ag.showCharacterSelect", client, tempSubAccount.firstName, tempSubAccount.lastName, tempSubAccount.placeOfOrigin, tempSubAccount.dateOfBirth, tempSubAccount.skin);
+ showConnectCameraToPlayer(client);
+ showCharacterSelectToClient(client);
+}
+
+// ---------------------------------------------------------------------------
+
+function newCharacterCommand(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;
+ }
+
+ if(areParamsEmpty(params)) {
+ messageClientSyntax(client, getCommandSyntaxText(command));
+ return false;
+ }
+
+ let splitParams = params.split(" ");
+ let firstName = splitParams[0];
+ let lastName = splitParams[1];
+
+ checkNewCharacter(client, firstName, lastName, "01/01/1901", "Liberty City", serverConfig.newCharacter.skin);
+}
+
+// ---------------------------------------------------------------------------
+
+function useCharacterCommand(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;
+ }
+
+ if(areParamsEmpty(params)) {
+ messageClientSyntax(client, getCommandSyntaxText(command));
+ return false;
+ }
+
+ let characterId = Number(params) || 1;
+
+ selectCharacter(client, characterId-1);
}
// ---------------------------------------------------------------------------
@@ -317,7 +366,7 @@ function loadSubAccountsFromAccount(accountId) {
if(accountId > 0) {
let dbConnection = connectToDatabase();
if(dbConnection) {
- let dbQueryString = `SELECT * FROM sacct_main WHERE sacct_acct = ${accountId};`;
+ 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)) {
@@ -394,7 +443,7 @@ function hashAccountPassword(name, password) {
// ---------------------------------------------------------------------------
function saltAccountInfo(name, password) {
- return "asshat.gaming." + String(accountSaltHash) + "." + String(name) + "." + String(password);
+ return "ag.gaming." + String(accountSaltHash) + "." + String(name) + "." + String(password);
}
// ---------------------------------------------------------------------------
@@ -406,7 +455,9 @@ function loginSuccess(client) {
client.administrator = true;
}
- triggerNetworkEvent("ag.loginSuccess", client);
+ if(serverConfig.useGUI) {
+ triggerNetworkEvent("ag.loginSuccess", client);
+ }
}
// ---------------------------------------------------------------------------
@@ -461,6 +512,7 @@ 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) {
@@ -468,7 +520,7 @@ function createSubAccount(accountId, firstName, lastName, skinId, dateOfBirth, p
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_cash) VALUES (${accountId}, '${safeFirstName}', '${safeLastName}', ${skinId}, '${safePlaceOfOrigin}', '${dateOfBirth}', ${serverConfig.newCharacter.spawnPosition.x}, ${serverConfig.newCharacter.spawnPosition.y}, ${serverConfig.newCharacter.spawnPosition.z}, ${serverConfig.newCharacter.money})`);
+ 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));
}
@@ -480,97 +532,138 @@ function createSubAccount(accountId, firstName, lastName, skinId, dateOfBirth, p
// ---------------------------------------------------------------------------
-addNetworkHandler("ag.checkLogin", function(client, password) {
+function checkLogin(client, password) {
let loginAttemptsRemaining = client.getData("ag.loginAttemptsRemaining")-1;
if(isClientLoggedIn(client)) {
- //messageClientError(client, "You are already logged in!");
- triggerNetworkEvent("ag.loginSuccess", client);
+ if(serverConfig.useGUI) {
+ triggerNetworkEvent("ag.loginSuccess", client);
+ } else {
+ messageClientError(client, "You are already logged in!");
+ }
return false;
}
if(!isClientRegistered(client)) {
- //messageClientError(client, "Your name is not registered! Use /register to make an account.");
- triggerNetworkEvent("ag.showRegistration", client);
+ if(serverConfig.useGUI) {
+ triggerNetworkEvent("ag.showRegistration", client);
+ } else {
+ messageClientError(client, "Your name is not registered! Use /register to make an account.");
+ }
return false;
}
if(areParamsEmpty(password)) {
- //messageClientError(client, "You must enter a password!");
- triggerNetworkEvent("ag.loginFailed", client, "Invalid password! " + String(loginAttemptsRemaining) + " tries remaining.");
+ if(serverConfig.useGUI) {
+ triggerNetworkEvent("ag.loginFailed", client, `Invalid password! ${loginAttemptsRemaining} tries remaining.`);
+ } else {
+ messageClientError(client, "You must enter a password!");
+ }
return false;
}
if(!isAccountPasswordCorrect(getClientData(client).accountData, hashAccountPassword(client.name, password))) {
- //messageClientError(client, "Invalid password!");
- triggerNetworkEvent("ag.loginFailed", client, "Invalid password! " + String(loginAttemptsRemaining) + " tries remaining.");
+ if(serverConfig.useGUI) {
+ triggerNetworkEvent("ag.loginFailed", client, `Invalid password! ${loginAttemptsRemaining} tries remaining.`);
+ } else {
+ messageClientError(client, `Invalid password! ${loginAttemptsRemaining} tries remaining.`);
+ }
return false;
}
loginSuccess(client);
if(getClientData(client).subAccounts.length == 0) {
- triggerNetworkEvent("ag.showPrompt", client, "You have no characters. Would you like to make one?", "No characters");
- client.setData("ag.prompt", AG_PROMPT_CREATEFIRSTCHAR, false);
+ 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 {
- getClientData(client).currentSubAccount = 0;
- let tempSubAccount = getClientData(client).subAccounts[0];
- triggerNetworkEvent("ag.showCharacterSelect", client, tempSubAccount.firstName, tempSubAccount.lastName, tempSubAccount.placeOfOrigin, tempSubAccount.dateOfBirth, tempSubAccount.skin);
+ showCharacterSelectToClient(client);
}
-});
+}
+addNetworkHandler("ag.checkLogin", checkLogin);
// ---------------------------------------------------------------------------
-addNetworkHandler("ag.checkRegistration", function(client, password, confirmPassword, emailAddress) {
+function checkRegistration(client, password, confirmPassword = "", emailAddress = "") {
console.log("[Asshat.Account]: Checking registration for " + String(client.name));
if(isClientRegistered(client)) {
- //messageClientError(client, "Your name is already registered!");
- triggerNetworkEvent("ag.showLogin", client);
+ if(serverConfig.useGUI) {
+ triggerNetworkEvent("ag.showLogin", client);
+ } else {
+ messageClientError(client, "Your name is already registered!");
+ }
return false;
}
if(isClientLoggedIn(client)) {
- //messageClientError(client, "You are already logged in!");
- triggerNetworkEvent("ag.loginSuccess", client);
+ if(serverConfig.useGUI) {
+ triggerNetworkEvent("ag.loginSuccess", client);
+ } else {
+ messageClientError(client, "You are already logged in!");
+ }
return false;
}
if(areParamsEmpty(password)) {
- triggerNetworkEvent("ag.registrationFailed", client, "Password cannot be blank!");
+ if(serverConfig.useGUI) {
+ triggerNetworkEvent("ag.registrationFailed", client, "Password cannot be blank!");
+ } else {
+ messageClientError(client, "The password cannot be blank!");
+ }
return false;
}
- if(areParamsEmpty(confirmPassword)) {
- triggerNetworkEvent("ag.registrationFailed", client, "Password confirm cannot be blank!");
- return false;
+ if(serverConfig.useGUI) {
+ if(areParamsEmpty(confirmPassword)) {
+ triggerNetworkEvent("ag.registrationFailed", client, "Password confirm cannot be blank!");
+ return false;
+ }
}
- if(areParamsEmpty(emailAddress)) {
- triggerNetworkEvent("ag.registrationFailed", client, "Email address cannot be blank!");
- return false;
+ if(serverConfig.useGUI) {
+ if(areParamsEmpty(emailAddress)) {
+ triggerNetworkEvent("ag.registrationFailed", client, "Email address cannot be blank!");
+ return false;
+ }
}
- if(password != confirmPassword) {
- triggerNetworkEvent("ag.registrationFailed", client, "The passwords must match!");
- return false;
+ if(serverConfig.useGUI) {
+ if(password != confirmPassword) {
+ triggerNetworkEvent("ag.registrationFailed", client, "The passwords must match!");
+ return false;
+ }
}
if(!doesPasswordMeetRequirements(password)) {
- // Work on this later. Function should return true by default anyway for now.
- triggerNetworkEvent("ag.registrationFailed", client, "Password doesn't meet requirements!");
+ if(serverConfig.useGUI) {
+ // Work on this later. Function should return true by default anyway for now.
+ triggerNetworkEvent("ag.registrationFailed", client, "Password doesn't meet requirements!");
+ } else {
+ messageClientError(client, "Password doesn't meet requirements!");
+ }
return false
}
- if(!isValidEmailAddress(emailAddress)) {
- // Work on this later. Function should return true by default anyway for now.
- triggerNetworkEvent("ag.registrationFailed", client, "You must put a valid email!");
- return false
+ if(serverConfig.useGUI) {
+ if(!isValidEmailAddress(emailAddress)) {
+ triggerNetworkEvent("ag.registrationFailed", client, "You must put a valid email!");
+ return false
+ }
}
let accountData = createAccount(client.name, password, emailAddress);
if(!accountData) {
- triggerNetworkEvent("ag.registrationFailed", client, "Something went wrong. Your account could not be created!");
+ if(serverConfig.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!");
+ }
+
messageClientAlert(client, "Asshat Gaming staff have been notified of the problem and will fix it shortly.");
return false;
}
@@ -580,15 +673,20 @@ addNetworkHandler("ag.checkRegistration", function(client, password, confirmPass
messageClientSuccess(client, "Your account has been created!");
messageClientAlert(client, "To play on the server, you will need to make a character.");
- 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);
-});
+
+ if(serverConfig.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);
+ } else {
+ messageClientAlert(client, `You have no characters. Use /newchar to make one.`);
+ }
+};
+addNetworkHandler("ag.checkRegistration", checkRegistration);
// ---------------------------------------------------------------------------
-addNetworkHandler("ag.checkNewCharacter", function(client, firstName, lastName, dateOfBirth, placeOfOrigin, skinId) {
+function checkNewCharacter(client, firstName, lastName, dateOfBirth, placeOfOrigin, skinId) {
if(areParamsEmpty(firstName)) {
triggerNetworkEvent("ag.newCharacterFailed", client, "First name cannot be blank!");
return false;
@@ -618,18 +716,21 @@ addNetworkHandler("ag.checkNewCharacter", function(client, firstName, lastName,
let subAccountData = createSubAccount(getClientData(client).accountData.databaseId, firstName, lastName, skinId, dateOfBirth, placeOfOrigin);
if(!subAccountData) {
- triggerNetworkEvent("ag.newCharacterFailed", client, "Something went wrong. Your character could not be created!");
+ 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);
- triggerNetworkEvent("ag.newCharacterSuccess", client);
-
getClientData(client).currentSubAccount = 0;
let tempSubAccount = getClientData(client).subAccounts[0];
- triggerNetworkEvent("ag.showCharacterSelect", client, tempSubAccount.firstName, tempSubAccount.lastName, tempSubAccount.placeOfOrigin, tempSubAccount.dateOfBirth, tempSubAccount.skin);
-});
+ showCharacterSelectToClient(client);
+}
+addNetworkHandler("ag.checkNewCharacter", checkNewCharacter);
// ---------------------------------------------------------------------------
@@ -665,17 +766,26 @@ addNetworkHandler("ag.nextCharacter", function(client) {
// ---------------------------------------------------------------------------
-addNetworkHandler("ag.selectCharacter", function(client) {
- triggerNetworkEvent("ag.characterSelectSuccess", client);
+function selectCharacter(client, characterId = -1) {
+ if(serverConfig.useGUI) {
+ triggerNetworkEvent("ag.characterSelectSuccess", client);
+ }
- let subAccountId = getClientData(client).currentSubAccount;
- let tempSubAccount = getClientData(client).subAccounts[subAccountId];
+ if(characterId != -1) {
+ getClientData(client).currentSubAccount = characterId;
+ }
+
+ console.log(getClientData(client).currentSubAccount);
+
+ let tempSubAccount = getClientCurrentSubAccount(client);
spawnPlayer(client, tempSubAccount.spawnPosition, tempSubAccount.spawnHeading, tempSubAccount.skin);
- messageClientNormal(client, "Welcome to Asshat Gaming Roleplay!", getColourByName("white"));
+ 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);
// ---------------------------------------------------------------------------
@@ -721,7 +831,10 @@ function saveClientToDatabase(client) {
// ---------------------------------------------------------------------------
function initClient(client) {
- triggerNetworkEvent("ag.connectCamera", client, serverConfig.connectCameraPosition[getServerGame()], serverConfig.connectCameraLookAt[getServerGame()]);
+ serverData.clients[client.index] = null;
+ triggerNetworkEvent("ag.logo", client, serverConfig.showLogo);
+ showConnectCameraToPlayer(client);
+ clearChatBox(client);
let tempAccountData = loadAccountFromName(client.name);
let tempSubAccounts = loadSubAccountsFromAccount(tempAccountData.databaseId);
@@ -729,14 +842,22 @@ function initClient(client) {
serverData.clients[client.index] = new serverClasses.clientData(client, tempAccountData, tempSubAccounts);
if(tempAccountData != false) {
- triggerNetworkEvent("ag.showLogin", client);
- //messageClient("Welcome back to Asshat Gaming RP, " + String(client.name) + "! Please /login to continue.", client, serverConfig.colour.byName["white"]);
+ if(serverConfig.useGUI) {
+ triggerNetworkEvent("ag.showLogin", client);
+ } else {
+ messageClient(`Welcome back to Asshat Gaming RP, ${client.name}! Please /login to continue.`, client, serverConfig.colour.byName.softGreen);
+ }
} else {
- triggerNetworkEvent("ag.showRegistration", client);
- //messageClient("Welcome to Asshat Gaming RP, " + String(client.name) + "! Please /register to continue.", client, serverConfig.colour.byName["white"]);
+ if(serverConfig.useGUI) {
+ triggerNetworkEvent("ag.showRegistration", client);
+ } else {
+ messageClient(`Welcome to Asshat Gaming RP, ${client.name}! Please /register to continue.`, client, serverConfig.colour.byName.softGreen);
+ }
}
- sendAllBlips(client);
+ if(server.game < GAME_GTA_IV) {
+ sendAllBlips(client);
+ }
}
// ---------------------------------------------------------------------------
@@ -745,4 +866,22 @@ function getClientData(client) {
return serverData.clients[client.index];
}
-// ---------------------------------------------------------------------------
\ No newline at end of file
+// ---------------------------------------------------------------------------
+
+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}`);
+ });
+ }
+}
+
+// ---------------------------------------------------------------------------
+
diff --git a/scripts/server/ammunation.js b/scripts/server/ammunation.js
index e7cab78b..44a2ba7f 100644
--- a/scripts/server/ammunation.js
+++ b/scripts/server/ammunation.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2020 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: ammunation.js
// DESC: Provides ammunation functions and usage
diff --git a/scripts/server/ban.js b/scripts/server/ban.js
index d66dc5e5..15ba5b87 100644
--- a/scripts/server/ban.js
+++ b/scripts/server/ban.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2020 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: bans.js
// DESC: Provides ban functions and usage
diff --git a/scripts/server/bitflag.js b/scripts/server/bitflag.js
index 0ffe8c59..bcf81f5d 100644
--- a/scripts/server/bitflag.js
+++ b/scripts/server/bitflag.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2020 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: bitflags.js
// DESC: Provides bitwise operations, functions and usage
diff --git a/scripts/server/business.js b/scripts/server/business.js
index 876e2c93..215ec63a 100644
--- a/scripts/server/business.js
+++ b/scripts/server/business.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2020 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: business.js
// DESC: Provides business functions and usage
@@ -53,12 +53,40 @@ function loadBusinessesFromDatabase() {
disconnectFromDatabase(dbConnection);
}
- console.log("[Asshat.Business]: " + String(tempBusinesses.length) + " businesses loaded from database successfully!");
+ console.log(`[Asshat.Business]: ${tempBusinesses.length} businesses loaded from database successfully!`);
return tempBusinesses;
}
// ---------------------------------------------------------------------------
+function loadLocationsFromDatabase() {
+ console.log("[Asshat.Business]: Loading locations from database ...");
+
+ let tempLocations = [];
+ let dbConnection = connectToDatabase();
+ let dbQuery = null;
+
+ if(dbConnection) {
+ dbQuery = queryDatabase(dbConnection, "SELECT * FROM `loc_main` WHERE `loc_server` = " + String(serverId));
+ if(dbQuery) {
+ if(dbQuery.numRows > 0) {
+ while(dbFetchAssoc = fetchQueryAssoc(dbQuery)) {
+ let tempLocationData = locationData(dbFetchAssoc);
+ tempLocations.push(tempLocationData);
+ console.log(`[Asshat.Business]: Location '${tempLocationData.name}' loaded from database successfully!`);
+ }
+ }
+ freeDatabaseQuery(dbQuery);
+ }
+ disconnectFromDatabase(dbConnection);
+ }
+
+ console.log(`[Asshat.Business]: ${tempBusinesses.length} locations loaded from database successfully!`);
+ return tempLocations;
+}
+
+// ---------------------------------------------------------------------------
+
function createBusinessCommand(command, params, client) {
if(getCommand(command).requireLogin) {
if(!isClientLoggedIn(client)) {
@@ -95,6 +123,45 @@ function createBusinessCommand(command, params, client) {
// ---------------------------------------------------------------------------
+function createBusinessLocationCommand(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(areParamsEmpty(params)) {
+ messageClientSyntax(client, getCommandSyntaxText(command));
+ return false;
+ }
+
+ if(isClientSpawned(client)) {
+ messageClientError("You must be spawned to use this command!");
+ return false;
+ }
+
+ let locationType = String(splitParams[0]);
+ let businessId = Number(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 + ")");
+}
+
+// ---------------------------------------------------------------------------
+
function createBusiness(name, entrancePosition, interiorId, virtualWorld) {
let dbConnection = connectToDatabase();
let escapedName = name;
@@ -140,15 +207,48 @@ function deleteBusinessCommand(command, params, client) {
return false;
}
- let businessId = Number(params);
-
- let tempBusinessData = serverData.businesses.filter(b => b.databaseId == businessId)[0];
+ let businessId = Number(splitParams[1]) || (isPlayerInAnyBusiness(client.player)) ? getPlayerBusiness(client.player) : getClosestBusinessEntrance(client.player.position);
deleteBusiness(businessId);
messageClientSuccess(client, `Business '${tempBusinessData.name} deleted!`);
}
// ---------------------------------------------------------------------------
+function deleteBusinessLocationCommand(command, params, client) {
+ messageClientError(client, "This command is under construction!");
+ return false;
+
+ 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(areParamsEmpty(params)) {
+ messageClientSyntax(client, getCommandSyntaxText(command));
+ return false;
+ }
+
+ //let businessId = Number(splitParams[1]);
+ //deleteBusinessLocation(businessId);
+ //messageClientSuccess(client, `Business '${tempBusinessData.name} deleted!`);
+}
+
+// ---------------------------------------------------------------------------
+
function setBusinessNameCommand(command, params, client) {
if(getCommand(command).requireLogin) {
if(!isClientLoggedIn(client)) {
@@ -177,12 +277,10 @@ 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).databaseId;
-
- let tempBusinessData = serverData.businesses.filter(b => b.databaseId == businessId)[0];
+ let businessId = Number(splitParams[1]) || (isPlayerInAnyBusiness(client.player)) ? getPlayerBusiness(client.player) : getClosestBusinessEntrance(client.player.position);
serverData.businesses[businessId].name = newBusinessName;
- messageClientSuccess(client, `Business '${tempBusinessData.name}' renamed to '${newBusinessName}'!`);
+ messageClientSuccess(client, `Business '${serverData.businesses[businessId].name}' renamed to '${newBusinessName}'!`);
}
// ---------------------------------------------------------------------------
@@ -220,7 +318,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).databaseId;
+ let businessId = Number(splitParams[1]) || (isPlayerInAnyBusiness(client.player)) ? getPlayerBusiness(client.player) : getClosestBusinessEntrance(client.player.position);
if(!newBusinessOwner) {
messageClientError("Player not found!");
@@ -270,7 +368,7 @@ function lockBusinessCommand(command, params, client) {
let splitParams = params.split(" ");
- let businessId = Number(splitParams[0]) || (isPlayerInAnyBusiness(client.player)) ? getPlayerBusiness(client.player) : getClosestBusinessEntrance(client.player.position).databaseId;
+ let businessId = Number(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" + "!");
@@ -278,6 +376,164 @@ function lockBusinessCommand(command, params, client) {
// ---------------------------------------------------------------------------
+function setBusinessEntranceFeeCommand(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(areParamsEmpty(params)) {
+ messageClientSyntax(client, getCommandSyntaxText(command));
+ return false;
+ }
+
+ 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);
+
+ serverData.businesses[businessId].entranceFee = entranceFee;
+ messageClientSuccess(client, `Business '${serverData.businesses[businessId].name}' entrance fee to $'${entranceFee}'!`);
+}
+
+// ---------------------------------------------------------------------------
+
+function withdrawFromBusinessCommand(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(areParamsEmpty(params)) {
+ messageClientSyntax(client, getCommandSyntaxText(command));
+ return false;
+ }
+
+ 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 tempBusinessData = serverData.businesses.filter(b => b.databaseId == businessId)[0];
+
+ if(serverData.businesses[businessId].till < amount) {
+ messageClientError(client, `Business '${tempBusinessData.name}' doesn't have that much money! Use /bizbalance.`);
+ return false;
+ }
+
+ serverData.businesses[businessId].till -= amount;
+ getClientCurrentSubAccount(client).cash += amount;
+ updatePlayerCash(client);
+ messageClientSuccess(client, `You withdrew $${amount} from business '${tempBusinessData.name}''s till'`);
+}
+
+// ---------------------------------------------------------------------------
+
+function depositIntoBusinessCommand(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(areParamsEmpty(params)) {
+ messageClientSyntax(client, getCommandSyntaxText(command));
+ return false;
+ }
+
+ 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);
+
+ 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;
+ getClientCurrentSubAccount(client).cash -= amount;
+ updatePlayerCash(client);
+ messageClientSuccess(client, `You deposited $${amount} into business '${tempBusinessData.name}''s till'`);
+}
+
+// ---------------------------------------------------------------------------
+
+function viewBusinessTillAmountCommand(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(areParamsEmpty(params)) {
+ // messageClientSyntax(client, getCommandSyntaxText(command));
+ // return false;
+ //}
+
+ let splitParams = params.split(" ");
+
+ let businessId = Number(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}'!`);
+}
+
+// ---------------------------------------------------------------------------
+
function getBusinessDataFromDatabaseId(databaseId) {
let matchingBusinesses = serverData.businesses.filter(b => b.databaseId == businessId)
if(matchingBusinesses.length == 1) {
@@ -315,7 +571,32 @@ function getPlayerBusiness(player) {
// ---------------------------------------------------------------------------
function saveAllBusinessesToDatabase() {
+ for(let i in serverData.businesses) {
+ saveBusinessToDatabase(i);
+ }
+}
+// ---------------------------------------------------------------------------
+
+function saveBusinessToDatabase(businessId) {
+ let tempBusinessData = serverData.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);
+ } 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);
+ }
+ disconnectFromDatabase(dbConnection);
+ return true;
+ }
+ console.log(`[Asshat.Business]: Saved business '${tempBusinessData.name}' to database!`);
+
+ return false;
}
// ---------------------------------------------------------------------------
@@ -326,4 +607,71 @@ function createAllBusinessPickups() {
serverData.businesses[i].pickup.setData("ag.ownerType", AG_PICKUP_BUSINESS, true);
serverData.businesses[i].pickup.setData("ag.ownerId", i, true);
}
-}
\ No newline at end of file
+}
+
+// ---------------------------------------------------------------------------
+
+function deleteBusiness(businessId) {
+ let tempBusinessData = serverData.businesses[businessId];
+
+ let dbConnection = connectToDatabase();
+ let dbQuery = null;
+
+ if(dbConnection) {
+ dbQuery = queryDatabase(dbConnection, `UPDATE biz_main SET biz_deleted = 1 AND biz_who_deleted = ${getClientData(client).accountData.databaseId} AND biz_when_deleted = UNIX_TIMESTAMP() WHERE biz_id = ${tempBusinessData.databaseId} LIMIT 1`);
+ if(dbQuery) {
+ freeDatabaseQuery(dbQuery);
+ }
+ disconnectFromDatabase(dbConnection);
+ }
+
+ destroyElement(tempBusinessData.pickup);
+ removePlayersFromBusiness(businessId);
+}
+
+// ---------------------------------------------------------------------------
+
+/*
+function deleteBusiness(businessId) {
+ let tempBusinessData = serverData.businesses[businessId];
+
+ let dbConnection = connectToDatabase();
+ let dbQuery = null;
+
+ if(dbConnection) {
+ dbQuery = queryDatabase(dbConnection, `UPDATE biz_main SET biz_deleted = 1 AND biz_who_deleted = ${getClientData(client).accountData.databaseId} AND biz_when_deleted = UNIX_TIMESTAMP() WHERE biz_id = ${tempBusinessData.databaseId} LIMIT 1`);
+ if(dbQuery) {
+ freeDatabaseQuery(dbQuery);
+ }
+ disconnectFromDatabase(dbConnection);
+ }
+
+ destroyElement(tempBusinessData.pickup);
+ removePlayersFromBusiness(businessId);
+}
+*/
+
+// ---------------------------------------------------------------------------
+
+function removePlayersFromBusiness(businessId) {
+ getClients().forEach(function(client) {
+ if(client.getData("ag.inBusiness")) {
+ if(client.getData("ag.inBusiness") == businessId) {
+ exitBusiness(client);
+ }
+ }
+ });
+}
+
+// ---------------------------------------------------------------------------
+
+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);
+ }
+}
+
+// ---------------------------------------------------------------------------
\ No newline at end of file
diff --git a/scripts/server/business/bakery.js b/scripts/server/business/bakery.js
index c8216b5d..e984a522 100644
--- a/scripts/server/business/bakery.js
+++ b/scripts/server/business/bakery.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2019 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: bakery.js
// DESC: Provides bakery business functions and usage
diff --git a/scripts/server/business/bar.js b/scripts/server/business/bar.js
index 0f3b8c9c..3adb630c 100644
--- a/scripts/server/business/bar.js
+++ b/scripts/server/business/bar.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2019 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: bar.js
// DESC: Provides bar/pub business functions and usage
diff --git a/scripts/server/business/burger.js b/scripts/server/business/burger.js
index 486c47f5..b955c4f1 100644
--- a/scripts/server/business/burger.js
+++ b/scripts/server/business/burger.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2019 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: burger.js
// DESC: Provides burger joint (McDonalds?) business functions and usage
diff --git a/scripts/server/business/clothing.js b/scripts/server/business/clothing.js
index 978a4a3b..9c1f54c6 100644
--- a/scripts/server/business/clothing.js
+++ b/scripts/server/business/clothing.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2019 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: clothing.js
// DESC: Provides clothing (skin) business functions and usage
diff --git a/scripts/server/business/club.js b/scripts/server/business/club.js
index 75e9498c..7508981a 100644
--- a/scripts/server/business/club.js
+++ b/scripts/server/business/club.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2019 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: club.js
// DESC: Provides club/nightclub business functions and usage
diff --git a/scripts/server/business/fuel.js b/scripts/server/business/fuel.js
index 531ce090..8fbd0c8e 100644
--- a/scripts/server/business/fuel.js
+++ b/scripts/server/business/fuel.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2019 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: fuel.js
// DESC: Provides fuel/petrol business functions and usage
diff --git a/scripts/server/business/mechanic.js b/scripts/server/business/mechanic.js
index 73c93806..f15290be 100644
--- a/scripts/server/business/mechanic.js
+++ b/scripts/server/business/mechanic.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2019 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: mechanic.js
// DESC: Provides mechanic/vehicle repair business functions and usage
diff --git a/scripts/server/business/pizza.js b/scripts/server/business/pizza.js
index ee5637c8..907e04b6 100644
--- a/scripts/server/business/pizza.js
+++ b/scripts/server/business/pizza.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2019 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: pizza.js
// DESC: Provides pizza restaurant business functions and usage
diff --git a/scripts/server/business/restaurant.js b/scripts/server/business/restaurant.js
index b0834683..2349a34c 100644
--- a/scripts/server/business/restaurant.js
+++ b/scripts/server/business/restaurant.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2019 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: restaurant.js
// DESC: Provides generic restaurant business functions and usage
diff --git a/scripts/server/business/vehicle.js b/scripts/server/business/vehicle.js
index 1b35b136..9c047c6c 100644
--- a/scripts/server/business/vehicle.js
+++ b/scripts/server/business/vehicle.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2019 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: vehicle.js
// DESC: Provides vehicle dealership business functions and usage
diff --git a/scripts/server/business/weapon.js b/scripts/server/business/weapon.js
index 2a8a2597..84e3dd22 100644
--- a/scripts/server/business/weapon.js
+++ b/scripts/server/business/weapon.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2019 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: weapon.js
// DESC: Provides weapon (ammu) business functions and usage
diff --git a/scripts/server/chat.js b/scripts/server/chat.js
index 267b8503..0c793be8 100644
--- a/scripts/server/chat.js
+++ b/scripts/server/chat.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2020 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: chat.js
// DESC: Provides chat functions and usage
diff --git a/scripts/server/clan.js b/scripts/server/clan.js
index 3d123ba2..8cfaf5af 100644
--- a/scripts/server/clan.js
+++ b/scripts/server/clan.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2020 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: clan.js
// DESC: Provides clan functions and usage
diff --git a/scripts/server/class.js b/scripts/server/class.js
index b7a22d54..e8f3cd4d 100644
--- a/scripts/server/class.js
+++ b/scripts/server/class.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2020 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: class.js
// DESC: Provides classes
@@ -92,12 +92,33 @@ function initClassTable() {
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.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.till = Number(businessAssoc["biz_till"]);
+ }
+ },
+ locationData: class {
+ constructor(locationAssoc) {
+ if(!locationAssoc) {
+ return;
+ }
+
+ this.databaseId = locationAssoc("biz_id");
+ this.name = locationAssoc("loc_name");
+ this.type = locationAssoc("loc_type");
+ this.business = locationAssoc("loc_biz");
+ this.enabled = locationAssoc("loc_enabled");
+
+ this.position = new Vec3(businessAssoc("loc_pos_x"), businessAssoc("loc__pos_y"), businessAssoc("loc_pos_z"));
+ this.interior = Number(businessAssoc["loc_int"]);
+ this.dimension = Number(businessAssoc["loc_vw"]);
}
},
houseData: class {
@@ -117,6 +138,7 @@ function initClassTable() {
this.model = vehicle.modelIndex;
this.vehicle = vehicle;
this.tempVehicle = false;
+ this.streamedBy = false; // For IV only
// Ownership
this.ownerType = AG_VEHOWNER_NONE;
diff --git a/scripts/server/client.js b/scripts/server/client.js
index cb8abf26..ce42ba02 100644
--- a/scripts/server/client.js
+++ b/scripts/server/client.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2020 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: client.js
// DESC: Provides client communication and cross-endpoint operations
diff --git a/scripts/server/colour.js b/scripts/server/colour.js
index 267b4f9d..e993bde6 100644
--- a/scripts/server/colour.js
+++ b/scripts/server/colour.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2020 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: colour.js
// DESC: Provides colours, functions and usage
diff --git a/scripts/server/command.js b/scripts/server/command.js
index b2d90e0c..7eb5630f 100644
--- a/scripts/server/command.js
+++ b/scripts/server/command.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2020 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: command.js
// DESC: Provides command data, functions and usage
@@ -24,6 +24,8 @@ function loadCommandData() {
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),
],
ammunation: [],
ban: [
@@ -33,8 +35,17 @@ function loadCommandData() {
],
bitFlag: [],
business: [
- commandData("addbiz", createBusinessCommand, "", getStaffFlagValue("manageBusinesses"), true, false),
+ commandData("addbiz", createBusinessCommand, "", getStaffFlagValue("manageBusinesses"), true, false),
commandData("delbiz", deleteBusinessCommand, "[id]", getStaffFlagValue("manageBusinesses"), true, true),
+ commandData("addloc", createBusinessLocationCommand, " ", getStaffFlagValue("manageBusinesses"), true, false),
+ commandData("delloc", deleteBusinessLocationCommand, "[id]", getStaffFlagValue("manageBusinesses"), true, false),
+ commandData("lockbiz", lockBusinessCommand, "", getStaffFlagValue("none"), true, true),
+ commandData("enterfee", setBusinessEntranceFeeCommand, "", getStaffFlagValue("none"), true, true),
+ commandData("till", viewBusinessTillAmountCommand, "", getStaffFlagValue("none"), true, true),
+ commandData("bizwithdraw", withdrawFromBusinessCommand, "", getStaffFlagValue("none"), true, true),
+ commandData("bizdeposit", depositIntoBusinessCommand, "", getStaffFlagValue("none"), true, true),
+ commandData("bizname", setBusinessNameCommand, "", getStaffFlagValue("none"), true, true),
+ commandData("bizowner", setBusinessOwnerCommand, "", getStaffFlagValue("none"), true, true),
],
chat: [
commandData("me", meActionCommand, "", getStaffFlagValue("none"), true, false),
@@ -104,7 +115,12 @@ function loadCommandData() {
],
locale: [],
messaging: [],
- misc: [],
+ misc: [
+ commandData("settime", setTimeCommand, " [minute]", getStaffFlagValue("manageServer"), true, true),
+ commandData("setweather", setWeatherCommand, "", getStaffFlagValue("manageServer"), true, true),
+ commandData("setsnow", setSnowingCommand, " ", getStaffFlagValue("manageServer"), true, true),
+ commandData("setlogo", toggleServerLogoCommand, "<0/1 state>", getStaffFlagValue("manageServer"), true, true),
+ ],
moderation: [
commandData("kick", kickClientCommand, " [reason]", getStaffFlagValue("basicModeration"), true, true),
commandData("mute", muteClientCommand, " [reason]", getStaffFlagValue("basicModeration"), true, true),
@@ -179,6 +195,12 @@ function getCommandRequiredPermissions(command) {
// ---------------------------------------------------------------------------
+function getCommandSyntaxText(command) {
+ return getCommand(command).syntaxString;
+}
+
+// ---------------------------------------------------------------------------
+
function isCommandAllowedOnDiscord(command) {
return getCommand(command).allowOnDiscord;
}
diff --git a/scripts/server/config.js b/scripts/server/config.js
index 2e2c06e9..dd46c50a 100644
--- a/scripts/server/config.js
+++ b/scripts/server/config.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2020 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: config.js
// DESC: Provides server configuration
@@ -9,6 +9,15 @@
// ===========================================================================
let serverConfig = {
+ useGUI: true,
+ name: "Asshat Gaming Roleplay",
+ password: "LockedForStartup*128",
+ hour: 0,
+ minute: 0,
+ weather: 1,
+ fallingSnow: 0,
+ groundSnow: 0,
+ showLogo: true,
colour: {
byType: {
talkMessage: toColour(200, 200, 200),
@@ -42,27 +51,16 @@ let serverConfig = {
burntYellow: toColour(210, 210, 0, 255),
burntOrange: toColour(210, 120, 0, 255),
bankGreen: toColour(0, 150, 0, 255),
+ softGreen: toColour(144, 255, 96, 255),
}
},
accountPasswordHash: "SHA512",
- connectCameraPosition: [
- false,
- new Vec3(-1176.481, -17.694, 95.992),
- false,
- false,
- false,
- ],
- connectCameraLookAt: [
- false,
- new Vec3(-1175.726, -17.055, 95.847),
- false,
- false,
- false,
- ],
+ connectCameraPosition: false,
+ connectCameraLookAt: false,
newCharacter: {
- spawnPosition: new Vec3(1038.40, -666.70, 14.97),
+ spawnPosition: false,
spawnHeading: 0.0,
- money: 1000,
+ money: 0,
},
npcFarProximity: 100,
npcMediumProximity: 40,
@@ -145,6 +143,58 @@ let serverConfig = {
vehicleLightsKey: SDLK_k,
vehicleLocksKey: SDLK_l,
},
+ discordBotToken: "",
+ discordEnabled: false,
};
+// ----------------------------------------------------------------------------
+
+function loadServerConfig() {
+ let dbConnection = connectToDatabase();
+ if(dbConnection) {
+ let dbQueryString = `SELECT * FROM svr_main WHERE svr_game = ${server.game} AND svr_port = ${server.port} LIMIT 1;`;
+ let dbQuery = queryDatabase(dbConnection, dbQueryString);
+ if(dbQuery) {
+ if(dbQuery.numRows > 0) {
+ 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"];
+
+ 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"]);
+
+ applyConfigToServer();
+
+ freeDatabaseQuery(dbQuery);
+ }
+ }
+ disconnectFromDatabase(dbConnection);
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+function applyConfigToServer() {
+ server.name = serverConfig.name;
+ server.password = serverConfig.password;
+ gta.time.hour = serverConfig.hour;
+ gta.time.minute = serverConfig.minute;
+ gta.forceWeather(serverConfig.weather);
+
+ updateServerRules();
+}
+
// ----------------------------------------------------------------------------
\ No newline at end of file
diff --git a/scripts/server/const.js b/scripts/server/const.js
index de054cd3..91d0fae7 100644
--- a/scripts/server/const.js
+++ b/scripts/server/const.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2020 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: const.js
// DESC: Provides constants
@@ -40,4 +40,26 @@ const AG_VEHOWNER_PLAYER = 1;
const AG_VEHOWNER_JOB = 2;
const AG_VEHOWNER_CLAN = 3;
const AG_VEHOWNER_FACTION = 4;
-const AG_VEHOWNER_PUBLIC = 5;
\ No newline at end of file
+const AG_VEHOWNER_PUBLIC = 5;
+
+// Business Owner Types
+const AG_BIZOWNER_NONE = 0;
+const AG_BIZOWNER_PLAYER = 1;
+const AG_BIZOWNER_JOB = 2;
+const AG_BIZOWNER_CLAN = 3;
+const AG_BIZOWNER_FACTION = 4;
+const AG_BIZOWNER_PUBLIC = 5;
+
+// House Owner Types
+const AG_HOUSEOWNER_NONE = 0;
+const AG_HOUSEOWNER_PLAYER = 1;
+const AG_HOUSEOWNER_JOB = 2;
+const AG_HOUSEOWNER_CLAN = 3;
+const AG_HOUSEOWNER_FACTION = 4;
+const AG_HOUSEOWNER_PUBLIC = 5;
+
+// Business Location Types
+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
diff --git a/scripts/server/core.js b/scripts/server/core.js
index 0a4f3bc3..22f619a0 100644
--- a/scripts/server/core.js
+++ b/scripts/server/core.js
@@ -1,14 +1,14 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2019 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: core.js
// DESC: Provides core data structures, function, and operations
// TYPE: Server (JavaScript)
// ===========================================================================
-let serverId = server.game;
+let serverId = 0;
// ----------------------------------------------------------------------------
@@ -260,16 +260,111 @@ let serverData = {
},
],
[ // GTA VC
-
+ {
+ position: new Vec3(399.77, -468.90, 11.73),
+ heading: 0.0,
+ blip: false,
+ name: "Washington Beach",
+ },
+ {
+ position: new Vec3(508.96, 512.07, 12.10),
+ heading: 0.0,
+ blip: false,
+ name: "Vice Point",
+ },
+ {
+ position: new Vec3(-657.43, 762.31, 11.59),
+ heading: 0.0,
+ blip: false,
+ name: "Downtown",
+ },
+ {
+ position: new Vec3(-885.08, -470.44, 13.11),
+ heading: 0.0,
+ blip: false,
+ name: "Little Havana",
+ },
],
[ // GTA SA
-
+ {
+ position: new Vec3(1545.53, -1675.64, 13.561),
+ heading: -1.575,
+ blip: false,
+ name: "Los Santos",
+ },
+
],
[ // GTA UG
],
[ // GTA IV
+ {
+ position: new Vec3(894.99, -357.39, 18.185),
+ heading: 2.923,
+ blip: false,
+ name: "Broker",
+ },
+ {
+ position: new Vec3(435.40, 1592.29, 17.353),
+ heading: 3.087,
+ blip: false,
+ name: "South Bohan",
+ },
+ {
+ position: new Vec3(974.93, 1870.45, 23.073),
+ heading: -1.621,
+ blip: false,
+ name: "Northern Gardens",
+ },
+ {
+ position: new Vec3(1233.25, -89.13, 28.034),
+ heading: 1.568,
+ blip: false,
+ name: "South Slopes",
+ },
+ {
+ position: new Vec3(50.12, 679.88, 15.316),
+ heading: 1.569,
+ blip: false,
+ name: "Middle Park East",
+ },
+ {
+ position: new Vec3(85.21, 1189.82, 14.755),
+ heading: 3.127,
+ blip: false,
+ name: "East Holland",
+ },
+ {
+ position: new Vec3(2170.87, 448.87, 6.085),
+ heading: 1.501,
+ blip: false,
+ name: "Francis International Airport",
+ },
+ {
+ position: new Vec3(213.12, -211.70, 10.752),
+ heading: 0.200,
+ blip: false,
+ name: "Chinatown",
+ },
+ {
+ position: new Vec3(-1714.95, 276.31, 22.134),
+ heading: 1.127,
+ blip: false,
+ name: "Acter",
+ },
+ {
+ position: new Vec3(-1220.73, -231.53, 3.024),
+ heading: 2.210,
+ blip: false,
+ name: "Port Tudor",
+ },
+ {
+ position: new Vec3(-927.66, 1263.63, 24.587),
+ heading: -0.913,
+ blip: false,
+ name: "Leftwood",
+ },
]
],
fireStations: [
@@ -304,8 +399,37 @@ let serverData = {
],
[ // GTA IV
-
- ]
+ {
+ position: new Vec3(953.13, 95.90, 35.004),
+ heading: 1.595,
+ blip: false,
+ name: "Broker",
+ },
+ {
+ position: new Vec3(-271.02, 1542.15, 20.420),
+ heading: -1.160,
+ blip: false,
+ name: "Northwood",
+ },
+ {
+ position: new Vec3(1120.47, 1712.36, 10.534),
+ heading: -0.682,
+ blip: false,
+ name: "Northern Gardens",
+ },
+ {
+ position: new Vec3(2364.87, 166.83, 5.813),
+ heading: 0.156,
+ blip: false,
+ name: "Francis International Airport",
+ },
+ {
+ position: new Vec3(295.40, -336.88, 4.963),
+ heading: 2.887,
+ blip: false,
+ name: "Chinatown",
+ },
+ ]
],
hospitals: [
false,
@@ -339,7 +463,30 @@ let serverData = {
],
[ // GTA IV
-
+ {
+ position: new Vec3(1199.59, 196.78, 33.554),
+ heading: 1.633,
+ blip: false,
+ name: "Schottler",
+ },
+ {
+ position: new Vec3(980.71, 1831.61, 23.898),
+ heading: -0.049,
+ blip: false,
+ name: "Northern Gardens",
+ },
+ {
+ position: new Vec3(-1317.27, 1277.20, 22.370),
+ heading: 2.246,
+ blip: false,
+ name: "Leftwood",
+ },
+ {
+ position: new Vec3(-1538.43, 344.58, 20.943),
+ heading: -0.156,
+ blip: false,
+ name: "Acter",
+ },
]
],
payAndSprays: [
@@ -737,4 +884,11 @@ function getServerId() {
return serverId;
}
-// ----------------------------------------------------------------------------
\ No newline at end of file
+// ----------------------------------------------------------------------------
+
+function getServerGame() {
+ return server.game;
+}
+
+// ----------------------------------------------------------------------------
+
diff --git a/scripts/server/database.js b/scripts/server/database.js
index 1b38d010..d70d7c28 100644
--- a/scripts/server/database.js
+++ b/scripts/server/database.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2020 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: database.js
// DESC: Provides database handling, functions and usage
diff --git a/scripts/server/developer.js b/scripts/server/developer.js
index 874df152..7f3199e0 100644
--- a/scripts/server/developer.js
+++ b/scripts/server/developer.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2020 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: developer.js
// DESC: Provides developer operation, commands, functions and usage
diff --git a/scripts/server/discord.js b/scripts/server/discord.js
index d96e7d8d..c2920870 100644
--- a/scripts/server/discord.js
+++ b/scripts/server/discord.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2020 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: discord.js
// DESC: Provides discord bridging and connection functions and usage
diff --git a/scripts/server/event.js b/scripts/server/event.js
index e896b903..a705500f 100644
--- a/scripts/server/event.js
+++ b/scripts/server/event.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2020 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: event.js
// DESC: Provides handlers for built in GTAC and Asshat-Gaming created events
@@ -10,24 +10,25 @@
addEventHandler("OnPlayerJoined", function(event, client) {
setTimeout(function() {
- triggerNetworkEvent("ag.connectCamera", client, serverConfig.connectCameraPosition[getServerGame()], serverConfig.connectCameraLookAt[getServerGame()]);
+ initClient(client);
+ //triggerNetworkEvent("ag.connectCamera", client, serverConfig.connectCameraPosition[getServerGame()], serverConfig.connectCameraLookAt[getServerGame()]);
- client.setData("ag.loginAttemptsRemaining", 3, false);
+ //client.setData("ag.loginAttemptsRemaining", 3, false);
- let tempAccountData = loadAccountFromName(client.name);
- let tempSubAccounts = loadSubAccountsFromAccount(tempAccountData.databaseId);
+ //let tempAccountData = loadAccountFromName(client.name);
+ //let tempSubAccounts = loadSubAccountsFromAccount(tempAccountData.databaseId);
- serverData.clients[client.index] = new serverClasses.clientData(client, tempAccountData, tempSubAccounts);
+ //serverData.clients[client.index] = new serverClasses.clientData(client, tempAccountData, tempSubAccounts);
- sendAllBlips(client);
+ //sendAllBlips(client);
- if(tempAccountData != false) {
- triggerNetworkEvent("ag.showLogin", client);
- //messageClient("Welcome back to Asshat Gaming RP, " + String(client.name) + "! Please /login to continue.", client, serverConfig.colour.byName["white"]);
- } else {
- triggerNetworkEvent("ag.showRegistration", client);
- //messageClient("Welcome to Asshat Gaming RP, " + String(client.name) + "! Please /register to continue.", client, serverConfig.colour.byName["white"]);
- }
+ //if(tempAccountData != false) {
+ // triggerNetworkEvent("ag.showLogin", client);
+ // //messageClient("Welcome back to Asshat Gaming RP, " + String(client.name) + "! Please /login to continue.", client, serverConfig.colour.byName["white"]);
+ //} else {
+ // triggerNetworkEvent("ag.showRegistration", client);
+ // //messageClient("Welcome to Asshat Gaming RP, " + String(client.name) + "! Please /register to continue.", client, serverConfig.colour.byName["white"]);
+ //}
}, 500);
});
@@ -52,9 +53,17 @@ addEventHandler("OnPedSpawn", function(event, ped) {
// ---------------------------------------------------------------------------
addEventHandler("OnPedWasted", function(event, wastedPed, killerPed, weaponId, pedPiece) {
- let closestHospital = getClosestHospital(wastedPed.position);
- let client = getClientFromPedElement(wastedPed);
- spawnPlayer(client, closestHospital.position, closestHospital.heading, getClientCurrentSubAccount(client).skin);
+ 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);
+ }
+ }
});
// ---------------------------------------------------------------------------
@@ -68,13 +77,7 @@ bindEventHandler("OnResourceStop", thisResource, function(event, resource) {
// ---------------------------------------------------------------------------
bindEventHandler("OnResourceStart", thisResource, function(event, resource) {
- getClients().forEach(function(client) {
- initClient(client);
- });
-
- //createAllLocationBlips();
-
-
+ //initAllClients();
});
// ---------------------------------------------------------------------------
diff --git a/scripts/server/faction.js b/scripts/server/faction.js
index c151cbab..79ee83ca 100644
--- a/scripts/server/faction.js
+++ b/scripts/server/faction.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2020 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: faction.js
// DESC: Provides faction functions and usage
diff --git a/scripts/server/help.js b/scripts/server/help.js
index 98866d03..ef329dfc 100644
--- a/scripts/server/help.js
+++ b/scripts/server/help.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2020 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: help.js
// DESC: Provides update info, help commands, and documentation
diff --git a/scripts/server/house.js b/scripts/server/house.js
index 022c3f38..5be96945 100644
--- a/scripts/server/house.js
+++ b/scripts/server/house.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2020 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: house.js
// DESC: Provides house commands, functions, and usage
diff --git a/scripts/server/item.js b/scripts/server/item.js
index 9ef86ea5..81e49c41 100644
--- a/scripts/server/item.js
+++ b/scripts/server/item.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2020 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: item.js
// DESC: Provides item functions and usage
diff --git a/scripts/server/job.js b/scripts/server/job.js
index 71ba64d3..6f4a31ed 100644
--- a/scripts/server/job.js
+++ b/scripts/server/job.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2020 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: job.js
// DESC: Provides job functions and usage
@@ -75,7 +75,7 @@ function sendAllJobSpheres() {
function createAllJobPickups() {
for(let i in serverData.jobs[getServerGame()]) {
- serverData.jobs[getServerGame()][i].pickup = createPickup(serverData.jobs[getServerGame()][i].pickupModel, serverData.jobs[getServerGame()][i].position);
+ serverData.jobs[getServerGame()][i].pickup = gta.createPickup(serverData.jobs[getServerGame()][i].pickupModel, serverData.jobs[getServerGame()][i].position);
serverData.jobs[getServerGame()][i].pickup.setData("ag.ownerType", AG_PICKUP_JOB, true);
serverData.jobs[getServerGame()][i].pickup.setData("ag.ownerId", i, true);
@@ -323,7 +323,7 @@ function startWorking(client) {
getClientCurrentSubAccount(client).isWorking = true;
let jobId = getClientCurrentSubAccount(client).job;
- switch(serverData.jobs[getServerGame()][jobId].jobType) {
+ switch(getJobType(jobId)) {
case AG_JOB_POLICE:
messageClientInfo(client, "Use /uniform and /equip to get your equipment.");
break;
@@ -370,7 +370,7 @@ function stopWorking(client) {
getClientCurrentSubAccount(client).isWorking = false;
- triggerNetworkEvent("ag.skin", null, client.player, getClientCurrentSubAccount(client).skin);
+ triggerNetworkEvent("ag.skin", client, getClientCurrentSubAccount(client).skin);
let jobVehicle = getClientCurrentSubAccount(client).lastJobVehicle;
if(jobVehicle) {
@@ -394,7 +394,7 @@ function stopWorking(client) {
triggerNetworkEvent("ag.clearWeapons", client);
let jobId = getClientCurrentSubAccount(client).job;
- switch(serverData.jobs[getServerGame()][jobId].jobType) {
+ switch(getJobType(jobId)) {
case AG_JOB_POLICE:
messageClientInfo(client, "Your uniform, equipment, and police car have been returned to the police station");
break;
@@ -456,41 +456,41 @@ function jobUniformCommand(command, params, client) {
let jobId = getClientCurrentSubAccount(client).job;
getClientCurrentSubAccount(client).jobUniform = uniformId-1;
-
- switch(serverData.jobs[getServerGame()][jobId].jobType) {
+
+ switch(getJobType(jobId)) {
case AG_JOB_POLICE:
- triggerNetworkEvent("ag.skin", null, client.player, serverData.policeJobSkins[getServerGame()][uniformId-1]);
+ triggerNetworkEvent("ag.skin", client, serverData.policeJobSkins[getServerGame()][uniformId-1]);
//client.player.modelIndex = serverData.policeJobSkins[getServerGame()][uniformId];
triggerNetworkEvent("ag.giveWeapon", client, 2, 200, false);
triggerNetworkEvent("ag.giveWeapon", client, 1, 1, false);
break;
case AG_JOB_MEDICAL:
- triggerNetworkEvent("ag.skin", null, client.player, serverData.medicalJobSkins[getServerGame()][uniformId-1]);
+ triggerNetworkEvent("ag.skin", client, serverData.medicalJobSkins[getServerGame()][uniformId-1]);
//client.player.modelIndex = serverData.medicalJobSkins[getServerGame()][uniformId];
messageClientInfo(client, "Your uniform and ambulance have been returned to the hospital");
break;
case AG_JOB_FIRE:
- triggerNetworkEvent("ag.skin", null, client.player, serverData.fireJobSkins[getServerGame()][uniformId-1]);
+ triggerNetworkEvent("ag.skin", client, serverData.fireJobSkins[getServerGame()][uniformId-1]);
//client.player.modelIndex = serverData.fireJobSkins[getServerGame()][uniformId];
messageClientInfo(client, "Your uniform and fire truck have been returned to the fire station");
break;
case AG_JOB_BUS:
- triggerNetworkEvent("ag.skin", null, client.player, serverData.busJobSkins[getServerGame()][uniformId-1]);
+ triggerNetworkEvent("ag.skin", client, serverData.busJobSkins[getServerGame()][uniformId-1]);
//client.player.modelIndex = serverData.busJobSkins[getServerGame()][uniformId];
messageClientInfo(client, "Your bus has been returned to the bus depot");
break;
case AG_JOB_TAXI:
- triggerNetworkEvent("ag.skin", null, client.player, serverData.taxiJobSkins[getServerGame()][uniformId-1]);
+ triggerNetworkEvent("ag.skin", client, serverData.taxiJobSkins[getServerGame()][uniformId-1]);
//client.player.modelIndex = serverData.taxiJobSkins[getServerGame()][uniformId];
messageClientInfo(client, "Your taxi has been returned to the taxi depot");
break;
case AG_JOB_GARBAGE:
- triggerNetworkEvent("ag.skin", null, client.player, serverData.garbageJobSkins[getServerGame()][uniformId-1]);
+ triggerNetworkEvent("ag.skin", client, serverData.garbageJobSkins[getServerGame()][uniformId-1]);
//client.player.modelIndex = serverData.garbageJobSkins[getServerGame()][uniformId];
messageClientInfo(client, "Your trash truck has been returned to the city landfill");
break;
diff --git a/scripts/server/job/bus.js b/scripts/server/job/bus.js
index 0496c9a0..8577d862 100644
--- a/scripts/server/job/bus.js
+++ b/scripts/server/job/bus.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2019 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: bus.js
// DESC: Provides bus driver job functions and usage
diff --git a/scripts/server/job/drug.js b/scripts/server/job/drug.js
index 8f521296..2148f519 100644
--- a/scripts/server/job/drug.js
+++ b/scripts/server/job/drug.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2019 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: drug.js
// DESC: Provides drug runner/dealer job functions and usage
diff --git a/scripts/server/job/fire.js b/scripts/server/job/fire.js
index b73a96d6..a93cf65f 100644
--- a/scripts/server/job/fire.js
+++ b/scripts/server/job/fire.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2019 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: fire.js
// DESC: Provides firefighter job functions and usage
diff --git a/scripts/server/job/garbage.js b/scripts/server/job/garbage.js
index 4a6b8876..810faea4 100644
--- a/scripts/server/job/garbage.js
+++ b/scripts/server/job/garbage.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2019 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: garbage.js
// DESC: Provides garbage collector job functions and usage
diff --git a/scripts/server/job/medic.js b/scripts/server/job/medic.js
index 9b5c5adb..44b73f05 100644
--- a/scripts/server/job/medic.js
+++ b/scripts/server/job/medic.js
@@ -1,9 +1,9 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2019 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: medic.js
-// DESC: Provides medic job functions and usage
+// DESC: Provides paramedic job functions and usage
// TYPE: Job (JavaScript)
// ===========================================================================
\ No newline at end of file
diff --git a/scripts/server/job/police.js b/scripts/server/job/police.js
index c1dd0dff..4da80731 100644
--- a/scripts/server/job/police.js
+++ b/scripts/server/job/police.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2019 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: police.js
// DESC: Provides police officer job functions and usage
diff --git a/scripts/server/job/taxi.js b/scripts/server/job/taxi.js
index 46bad640..2138be67 100644
--- a/scripts/server/job/taxi.js
+++ b/scripts/server/job/taxi.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2019 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: taxi.js
// DESC: Provides taxi driver job functions and usage
diff --git a/scripts/server/job/weapon.js b/scripts/server/job/weapon.js
index 71ad62b7..2f07fd3b 100644
--- a/scripts/server/job/weapon.js
+++ b/scripts/server/job/weapon.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2019 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: weapon.js
// DESC: Provides weapons dealer job functions and usage
diff --git a/scripts/server/locale.js b/scripts/server/locale.js
index 7855e61f..4fa4238a 100644
--- a/scripts/server/locale.js
+++ b/scripts/server/locale.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2020 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: locale.js
// DESC: Provides locale structures, functions and usage
diff --git a/scripts/server/messaging.js b/scripts/server/messaging.js
index 238bb16c..0438731d 100644
--- a/scripts/server/messaging.js
+++ b/scripts/server/messaging.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2020 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: messaging.js
// DESC: Provides messaging functions and usage
@@ -10,11 +10,28 @@
// ---------------------------------------------------------------------------
+function messageAdminAction(messageText) {
+ message(`⚠️ ${messageText}`, getColourByName("orange"));
+ messageDiscord(`:warning: ${messageText}`);
+}
+
+// ---------------------------------------------------------------------------
+
+function messageClientNormal(client, messageText, colour = COLOUR_WHITE) {
+ if(client instanceof Client) {
+ messageClient(`${messageText}`, client, colour);
+ } else {
+ messageDiscordUser(client, `:no_entry_sign: ${messageText}`);
+ }
+}
+
+// ---------------------------------------------------------------------------
+
function messageClientError(client, messageText) {
if(client instanceof Client) {
messageClientNormal(client, `🚫 ${messageText}`, getColourByType("errorMessage"));
} else {
- messageDiscordUser(client, `🚫 ${messageText}`);
+ messageDiscordUser(client, `:no_entry_sign: ${messageText}`);
}
}
@@ -24,7 +41,7 @@ function messageClientSyntax(client, messageText) {
if(client instanceof Client) {
messageClientNormal(client, `⌨️ [#FFFFFF] ${messageText}`, getColourByType("syntaxMessage"));
} else {
- messageDiscordUser(client, `⌨️ ${messageText}`);
+ messageDiscordUser(client, `:keyboard: ${messageText}`);
}
}
@@ -34,7 +51,7 @@ function messageClientAlert(client, messageText) {
if(client instanceof Client) {
messageClientNormal(client, `⚠️ [#FFFFFF] ${messageText}`, getColourByType("alertMessage"));
} else {
- messageDiscordUser(client, `⚠️ ${messageText}`);
+ messageDiscordUser(client, `:warning: ${messageText}`);
}
}
@@ -44,7 +61,7 @@ function messageClientSuccess(client, messageText) {
if(client instanceof Client) {
messageClientNormal(client, `👍 [#FFFFFF] ${messageText}`, getColourByType("successMessage"));
} else {
- messageDiscordUser(client, `👍 ${messageText}`);
+ messageDiscordUser(client, `:thumbsup: ${messageText}`);
}
}
@@ -54,7 +71,7 @@ function messageClientInfo(client, messageText) {
if(client instanceof Client) {
messageClientNormal(client, `ℹ️ [#FFFFFF] ${messageText}`, getColourByType("successMessage"));
} else {
- messageDiscordUser(client, `ℹ️ ${messageText}`);
+ messageDiscordUser(client, `:information_source: ${messageText}`);
}
}
diff --git a/scripts/server/misc.js b/scripts/server/misc.js
index 78de2809..d867aa9e 100644
--- a/scripts/server/misc.js
+++ b/scripts/server/misc.js
@@ -1,11 +1,169 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2020 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: misc.js
// DESC: Provides any uncategorized functions and usage
// TYPE: Server (JavaScript)
// ===========================================================================
-// FUCK
\ No newline at end of file
+// ---------------------------------------------------------------------------
+
+function initBusinessScript() {
+ console.log("[Asshat.Misc]: Initializing misc script ...");
+ addMiscCommandHandlers();
+ console.log("[Asshat.Misc]: Misc script initialized successfully!");
+ return true;
+}
+
+// ---------------------------------------------------------------------------
+
+function addMiscCommandHandlers() {
+ console.log("[Asshat.Misc]: Adding misc commands!");
+ let businessCommands = serverCommands.misc;
+ for(let i in businessCommands) {
+ addCommandHandler(businessCommands[i].command, businessCommands[i].handlerFunction);
+ }
+ console.log("[Asshat.Misc]: Misc commands added!");
+ return true;
+}
+
+// ---------------------------------------------------------------------------
+
+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(splitParams[0]) || 1;
+
+ serverConfig.useLogo = !!logoState;
+
+ messageAdminAction(`${client.name} turned the server logo image ${getOnOffFromBool(intToBool(fallingSnow))}`);
+ updateServerRules();
+ return true;
+}
+
+// ---------------------------------------------------------------------------
\ No newline at end of file
diff --git a/scripts/server/moderation.js b/scripts/server/moderation.js
index e4626d19..959113c0 100644
--- a/scripts/server/moderation.js
+++ b/scripts/server/moderation.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2020 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: moderation.js
// DESC: Provides moderation commands, functions and usage
diff --git a/scripts/server/native.js b/scripts/server/native.js
index a285e5ff..95ff7c01 100644
--- a/scripts/server/native.js
+++ b/scripts/server/native.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2020 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: native.js
// DESC: Provides util function to wrap mod-specific stuff
diff --git a/scripts/server/npc.js b/scripts/server/npc.js
index 9722c6a4..b11c4516 100644
--- a/scripts/server/npc.js
+++ b/scripts/server/npc.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2020 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: npc.js
// DESC: Provides NPC usage and functions
diff --git a/scripts/server/npc/biker.js b/scripts/server/npc/biker.js
index e69de29b..d077754b 100644
--- a/scripts/server/npc/biker.js
+++ b/scripts/server/npc/biker.js
@@ -0,0 +1,9 @@
+// ===========================================================================
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
+// ---------------------------------------------------------------------------
+// FILE: biker.js
+// DESC: Provides biker NPC interaction and functionality
+// TYPE: Server (JavaScript)
+// ===========================================================================
\ No newline at end of file
diff --git a/scripts/server/npc/drugdealer.js b/scripts/server/npc/drugdealer.js
index e69de29b..dbc6ec3a 100644
--- a/scripts/server/npc/drugdealer.js
+++ b/scripts/server/npc/drugdealer.js
@@ -0,0 +1,9 @@
+// ===========================================================================
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
+// ---------------------------------------------------------------------------
+// FILE: drugdealer.js
+// DESC: Provides drug dealer NPC interaction and functionality
+// TYPE: Server (JavaScript)
+// ===========================================================================
\ No newline at end of file
diff --git a/scripts/server/npc/firefighter.js b/scripts/server/npc/firefighter.js
index e69de29b..ee1186f9 100644
--- a/scripts/server/npc/firefighter.js
+++ b/scripts/server/npc/firefighter.js
@@ -0,0 +1,9 @@
+// ===========================================================================
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
+// ---------------------------------------------------------------------------
+// FILE: firefighter.js
+// DESC: Provides firefighter NPC interaction and functionality
+// TYPE: Server (JavaScript)
+// ===========================================================================
\ No newline at end of file
diff --git a/scripts/server/npc/gangsta.js b/scripts/server/npc/gangsta.js
index e69de29b..6caca9c8 100644
--- a/scripts/server/npc/gangsta.js
+++ b/scripts/server/npc/gangsta.js
@@ -0,0 +1,9 @@
+// ===========================================================================
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
+// ---------------------------------------------------------------------------
+// FILE: gangsta.js
+// DESC: Provides street gang/hoodlum NPC interaction and functionality
+// TYPE: Server (JavaScript)
+// ===========================================================================
\ No newline at end of file
diff --git a/scripts/server/npc/mafia.js b/scripts/server/npc/mafia.js
index e69de29b..f195d5c3 100644
--- a/scripts/server/npc/mafia.js
+++ b/scripts/server/npc/mafia.js
@@ -0,0 +1,9 @@
+// ===========================================================================
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
+// ---------------------------------------------------------------------------
+// FILE: mafia.js
+// DESC: Provides mafia/mafioso NPC interaction and functionality
+// TYPE: Server (JavaScript)
+// ===========================================================================
\ No newline at end of file
diff --git a/scripts/server/npc/normal.js b/scripts/server/npc/normal.js
index e69de29b..de7701da 100644
--- a/scripts/server/npc/normal.js
+++ b/scripts/server/npc/normal.js
@@ -0,0 +1,9 @@
+// ===========================================================================
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
+// ---------------------------------------------------------------------------
+// FILE: normal.js
+// DESC: Provides normal/generic civilian NPC interaction and functionality
+// TYPE: Server (JavaScript)
+// ===========================================================================
\ No newline at end of file
diff --git a/scripts/server/npc/paramedic.js b/scripts/server/npc/paramedic.js
index e69de29b..6a74d4ec 100644
--- a/scripts/server/npc/paramedic.js
+++ b/scripts/server/npc/paramedic.js
@@ -0,0 +1,9 @@
+// ===========================================================================
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
+// ---------------------------------------------------------------------------
+// FILE: paramedic.js
+// DESC: Provides paramedic NPC interaction and functionality
+// TYPE: Server (JavaScript)
+// ===========================================================================
\ No newline at end of file
diff --git a/scripts/server/npc/police.js b/scripts/server/npc/police.js
index e69de29b..5b7345a6 100644
--- a/scripts/server/npc/police.js
+++ b/scripts/server/npc/police.js
@@ -0,0 +1,9 @@
+// ===========================================================================
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
+// ---------------------------------------------------------------------------
+// FILE: police.js
+// DESC: Provides police officer NPC interaction and functionality
+// TYPE: Server (JavaScript)
+// ===========================================================================
\ No newline at end of file
diff --git a/scripts/server/security.js b/scripts/server/security.js
index 225fe1b1..5b924a38 100644
--- a/scripts/server/security.js
+++ b/scripts/server/security.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2020 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: security.js
// DESC: Provides security functions and usage
diff --git a/scripts/server/startup.js b/scripts/server/startup.js
index 2206d63f..ecac6902 100644
--- a/scripts/server/startup.js
+++ b/scripts/server/startup.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2020 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: startup.js
// DESC: Provides startup/shutdown procedures
@@ -9,6 +9,7 @@
// ===========================================================================
function initServerScripts() {
+
checkForAllRequiredModules();
initClassScript();
@@ -27,7 +28,13 @@ function initServerScripts() {
initVehicleScript();
initDeveloperScript();
- serverData.saveDataIntervalTimer = setInterval(saveAllServerDataToDatabase, 600000);
+ initTimers();
+
+ //gta.time.hour = serverConfig.startup.hour;
+ //gta.time.minute = serverConfig.startup.minute;
+ //gta.forceWeather(serverConfig.startup.weather);
+
+ initAllClients();
}
// ---------------------------------------------------------------------------
@@ -52,26 +59,27 @@ function checkForMySQLModule() {
// ---------------------------------------------------------------------------
function checkForAllRequiredModules() {
- console.log("[AsshatRP.Startup]: Checking for required modules ...");
+ console.log("[Asshat.Startup]: Checking for required modules ...");
if(!checkForHashingModule()) {
- console.warn("[AsshatRP.Startup]: Hashing module is not loaded!");
- console.warn("[AsshatRP.Startup]: This resource will now shutdown.");
+ console.warn("[Asshat.Startup]: Hashing module is not loaded!");
+ console.warn("[Asshat.Startup]: This resource will now shutdown.");
thisResource.stop();
}
if(!checkForMySQLModule()) {
- console.warn("[AsshatRP.Startup]: MySQL module is not loaded!");
- console.warn("[AsshatRP.Startup]: This resource will now shutdown.");
+ console.warn("[Asshat.Startup]: MySQL module is not loaded!");
+ console.warn("[Asshat.Startup]: This resource will now shutdown.");
thisResource.stop();
}
- console.log("[AsshatRP.Startup]: All required modules loaded!");
+ console.log("[Asshat.Startup]: All required modules loaded!");
return true;
}
// ---------------------------------------------------------------------------
+loadServerConfig();
initServerScripts();
-// ----------------------------------------------------------------------------
\ No newline at end of file
+// ---------------------------------------------------------------------------
\ No newline at end of file
diff --git a/scripts/server/timers.js b/scripts/server/timers.js
new file mode 100644
index 00000000..bba29d8b
--- /dev/null
+++ b/scripts/server/timers.js
@@ -0,0 +1,36 @@
+// ===========================================================================
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
+// ---------------------------------------------------------------------------
+// FILE: timers.js
+// DESC: Provides timer functions and features
+// TYPE: Server (JavaScript)
+// ===========================================================================
+
+let serverTimers = {};
+
+// ---------------------------------------------------------------------------
+
+function updateTimeRule() {
+ server.setRule("Time", makeReadableTime(gta.time.hour, gta.time.minute));
+}
+
+// ---------------------------------------------------------------------------
+
+function saveAllServerDataToDatabase() {
+ console.log("[Asshat.Utilities]: Saving all server data to database ...");
+ saveAllClientsToDatabase();
+ saveAllVehiclesToDatabase();;
+ saveAllHousesToDatabase();
+ saveAllBusinessesToDatabase();
+ saveAllClansToDatabase();
+ console.log("[Asshat.Utilities]: Saved all server data to database!");
+}
+
+// ---------------------------------------------------------------------------
+
+function initTimers() {
+ serverTimers.saveDataIntervalTimer = setInterval(saveAllServerDataToDatabase, 600000);
+ serverTimers.updateTimeRuleTimer = setInterval(updateTimeRule, 1000);
+}
\ No newline at end of file
diff --git a/scripts/server/translate.js b/scripts/server/translate.js
index 400d4c5c..32ccd106 100644
--- a/scripts/server/translate.js
+++ b/scripts/server/translate.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2020 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: translate.js
// DESC: Provides translation functions
diff --git a/scripts/server/utilities.js b/scripts/server/utilities.js
index 24d40822..eea6fd71 100644
--- a/scripts/server/utilities.js
+++ b/scripts/server/utilities.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2020 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: utilities.js
// DESC: Provides util functions and arrays with data
@@ -98,6 +98,18 @@ let gameData = {
"Sandstorm",
"Greenish/Foggy"
],
+ [ // GTA IV
+ "Extra Sunny",
+ "Sunny",
+ "Sunny/Windy",
+ "Cloudy",
+ "Rain",
+ "Light Rain",
+ "Foggy",
+ "Thunderstorm",
+ "Extra Sunny",
+ "Sunny/Windy",
+ ],
],
gameNames: [
"Unknown",
@@ -1972,6 +1984,354 @@ let gameData = {
// 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],
+ ],
};
// ---------------------------------------------------------------------------
@@ -3281,6 +3641,7 @@ function sendAllPayAndSprayBlips(client) {
function sendAllFuelStationBlips(client) {
if(serverConfig.blipSprites[getServerGame()].fuelStation != -1) {
+ let tempBlips = [];
for(let i in serverData.fuelStations[getServerGame()]) {
tempBlips.push([
serverConfig.blipSprites[getServerGame()].fuelStation,
@@ -3359,15 +3720,7 @@ function canClientUseGuns(client) {
// ---------------------------------------------------------------------------
-function saveAllServerDataToDatabase() {
- console.log("[Asshat.Utilities]: Saving all server data to database ...");
- saveAllClientsToDatabase();
- saveAllVehiclesToDatabase();;
- saveAllHousesToDatabase();
- saveAllBusinessesToDatabase();
- saveAllClansToDatabase();
- console.log("[Asshat.Utilities]: Saved all server data to database!");
-}
+
// ---------------------------------------------------------------------------
@@ -3458,7 +3811,7 @@ function processHoldVehicleEngineKey(client) {
function getClientChatColour(client) {
let tempJob = getClientCurrentSubAccount(client).job;
- if(job != -1) {
+ if(tempJob != -1) {
if(getClientData(client).isWorking) {
return getJobData(tempJob).jobColour;
}
@@ -3466,4 +3819,67 @@ function getClientChatColour(client) {
return getColourByName("white");
}
+// ---------------------------------------------------------------------------
+
+function showConnectCameraToPlayer(client) {
+ triggerNetworkEvent("ag.connectCamera", client, serverConfig.connectCameraPosition, serverConfig.connectCameraLookAt);
+ //triggerNetworkEvent("ag.showCharacterSelect", client, tempSubAccount.firstName, tempSubAccount.lastName, tempSubAccount.placeOfOrigin, tempSubAccount.dateOfBirth, tempSubAccount.skin);
+}
+
+// ---------------------------------------------------------------------------
+
+function initAllClients() {
+ getClients().forEach(function(client) {
+ initClient(client);
+ });
+}
+
+// ---------------------------------------------------------------------------
+
+function getYesNoFromBool(boolVal) {
+ return (boolVal) ? "Yes" : "No";
+}
+
+// ---------------------------------------------------------------------------
+
+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));
+}
+
+// ---------------------------------------------------------------------------
+
+function getWeatherFromParams(params) {
+ if(isNaN(params)) {
+ for(let i in weatherNames[server.game]) {
+ if(weatherNames[server.game][i].toLowerCase().indexOf(params.toLowerCase()) != -1) {
+ return i;
+ }
+ }
+ return false;
+ } else {
+ if(typeof weatherNames[server.game][i] != "undefined") {
+ return i;
+ }
+ return false;
+ }
+ return false;
+}
+
+// ---------------------------------------------------------------------------
+
+function updatePlayerCash(client) {
+ triggerNetworkEvent("ag.money", getClientCurrentSubAccount(client).cash);
+}
+
+// ---------------------------------------------------------------------------
+
+function clearChatBox(client) {
+ //gta.messages.clear();
+ for(let i = 0; i <= 20; i++) {
+ messageClient(" ", client, COLOUR_WHITE);
+ }
+}
+
// ---------------------------------------------------------------------------
\ No newline at end of file
diff --git a/scripts/server/vehicle.js b/scripts/server/vehicle.js
index 11917126..e5206289 100644
--- a/scripts/server/vehicle.js
+++ b/scripts/server/vehicle.js
@@ -1,7 +1,7 @@
// ===========================================================================
-// Asshat Gaming RP
-// http://asshatgaming.com
-// © 2020 Asshat Gaming
+// Asshat-Gaming Roleplay
+// https://github.com/VortrexFTW/gtac_asshat_rp
+// Copyright (c) 2020 Asshat-Gaming (https://asshatgaming.com)
// ---------------------------------------------------------------------------
// FILE: vehicle.js
// DESC: Provides vehicle functions and usage
@@ -38,7 +38,7 @@ function loadVehiclesFromDatabase() {
let tempVehicles = [];
let dbAssoc;
if(dbConnection) {
- let dbQueryString = `SELECT * FROM veh_main WHERE veh_server = ${serverId}`;
+ let dbQueryString = `SELECT * FROM veh_main WHERE veh_server = ${serverId} AND veh_deleted = 0`;
let dbQuery = queryDatabase(dbConnection, dbQueryString);
if(dbQuery) {
while(dbAssoc = fetchQueryAssoc(dbQuery)) {
@@ -75,25 +75,12 @@ function saveVehicleToDatabase(vehicleData) {
if(dbConnection) {
// If vehicle hasn't been added to database, ID will be 0
if(vehicleData.databaseId == 0) {
- //let dbQueryColourFields = "`veh_col1_id`, `veh_col2_id`, `veh_col3_id1, `veh_col4_id`";
- //if(vehicleData.colourType == AH_VEH_COLOURTYPE_RGBA) {
- // dbQueryColourFields = "`veh_col1_rgba`, `veh_col2_rgba`, `veh_col3_rgba`, `veh_col4_rgba`";
- // dbQueryColourValues = vehicleData.colour1Red, `veh_col1_g`, `veh_col1_b`, `veh_col1_a`, `veh_col2_r`, `veh_col2_g`, `veh_col2_b`, `veh_col2_a`, `veh_col3_r`, `veh_col3_g`, `veh_col3_b`, `veh_col3_a`, `veh_col4_r`, `veh_col4_g`, `veh_col4_b`, `veh_col4_a`,";
- //}
- 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) VALUES (${vehicleData.model}, ${vehicleData.spawnPosition.x}, ${vehicleData.spawnPosition.y}, ${vehicleData.spawnPosition.z}, ${vehicleData.spawnRotation}, ${vehicleData.ownerType}, ${vehicleData.ownerId})`;
+ 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})`;
queryDatabase(dbConnection, dbQueryString);
- //if(getDatabaseError(dbConnection)) {
- // console.warn(`[Asshat.Vehicle]: There was a problem saving vehicle ${vehicleData.vehicle.id} to the database (INSERT). Error: ${getDatabaseError(dbConnection)}`);
- // return false;
- //}
getVehicleData(vehicleData.vehicle).databaseId = getDatabaseInsertId(dbConnection);
} else {
- let dbQueryString = `UPDATE veh_main SET veh_model=${vehicleData.model}, veh_pos_x=${vehicleData.spawnPosition.x}, veh_pos_y=${vehicleData.spawnPosition.y}, veh_pos_z=${vehicleData.spawnPosition.z}, veh_rot_z=${vehicleData.spawnRotation}, veh_owner_type=${vehicleData.ownerType}, veh_owner_id=${vehicleData.ownerId} WHERE veh_id=${vehicleData.databaseId}`;
+ let dbQueryString = `UPDATE veh_main SET veh_model=${vehicleData.model}, veh_pos_x=${vehicleData.spawnPosition.x}, veh_pos_y=${vehicleData.spawnPosition.y}, veh_pos_z=${vehicleData.spawnPosition.z}, veh_rot_z=${vehicleData.spawnRotation}, veh_owner_type=${vehicleData.ownerType}, veh_owner_id=${vehicleData.ownerId}, veh_col1=${vehicleData.colour1}, veh_col2=${vehicleData.colour2}, veh_col3=${vehicleData.colour3}, veh_col4=${vehicleData.colour4} WHERE veh_id=${vehicleData.databaseId}`;
queryDatabase(dbConnection, dbQueryString);
- //if(getDatabaseError(dbConnection)) {
- // console.warn(`[Asshat.Vehicle]: There was a problem saving vehicle ${vehicleData.vehicle.id} to the database (UPDATE). Error: ${getDatabaseError(dbConnection)}`);
- // return false;
- //}
}
disconnectFromDatabase(dbConnection);
return true;
@@ -106,6 +93,10 @@ 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);
@@ -174,7 +165,7 @@ function createVehicleCommand(command, params, client) {
let frontPos = getPosInFrontOfPos(client.player.position, client.player.heading, serverConfig.spawnCarDistance);
- let vehicle = createVehicle(modelId, frontPos, client.player.heading);
+ let vehicle = gta.createVehicle(modelId, frontPos, client.player.heading);
vehicle.heading = client.player.heading;
let tempVehicleData = new serverClasses.vehicleData(false, vehicle);
@@ -493,8 +484,8 @@ function setVehicleClanCommand(command, params, 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!");
@@ -534,8 +525,8 @@ function setVehicleOwnerCommand(command, params, 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!");
@@ -732,4 +723,23 @@ function toggleVehicleSpawnLockCommand(command, params, client) {
messageClientInfo(client, `This vehicle will now spawn ${(getVehicleData(vehicle).spawnLocked) ? "here" : "wherever a player leaves it."}`);
}
+// ---------------------------------------------------------------------------
+
+function sendAllVehiclesToClient(client) {
+ /*
+ let tempVehicles = [];
+ for(let i in serverData.vehicles) {
+ let thisVehicle = serverData.vehicles[i];
+
+ tempVehicles.push({
+ model: thisVehicle.model,
+ spawnPosition: thisVehicle.spawnPosition,
+ spawnHeading: thisVehicle.spawnHeading,
+ colours: [thisVehicle.colour1, thisVehicle.colour2, thisVehicle.colour3, thisVehicle.colour4],
+ locked: thisVehicle.locked,
+ });
+ }
+ */
+}
+
// ---------------------------------------------------------------------------
\ No newline at end of file
diff --git a/third-party/config.json b/third-party/config.json
deleted file mode 100644
index c8b01851..00000000
--- a/third-party/config.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "database": {
- "host":"158.69.238.64",
- "user":"db24053",
- "pass":"G3At3d7BsA",
- "name":"db24053",
- "port":"3306"
- },
- "weather": {
- "appKey":""
- },
- "discord": {
- "token":"",
- "logChannel":""
- },
- "security": {
- "accountPasswordHashType":"SHA256",
- "saltFormat":"asshat.gaming.{HASH}.{NAME}.{PASS}"
- }
-}
\ 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 51cf85e1..c745e682 100644
--- a/third-party/mexui/Core/Component/Control.js
+++ b/third-party/mexui/Core/Component/Control.js
@@ -21,12 +21,15 @@ mexui.Component.Control.defaultStyles = mexui.util.linkStyles(mexui.Entity.Style
// input
mexui.Component.Control.prototype.onMouseDown = function(e)
{
- var hit = this.isCursorOverControl();
- if(hit)
+ if(e.button == 0)
{
- e.used = true;
- e.clickedAControl = true;
- mexui.focusedControl = this;
+ var hit = this.isCursorOverControl();
+ if(hit)
+ {
+ e.used = true;
+ e.clickedAControl = true;
+ mexui.focusedControl = this;
+ }
}
};
diff --git a/third-party/mexui/Core/Component/Window.js b/third-party/mexui/Core/Component/Window.js
index 5703accf..2f6cea5a 100644
--- a/third-party/mexui/Core/Component/Window.js
+++ b/third-party/mexui/Core/Component/Window.js
@@ -45,7 +45,7 @@ mexui.Component.Window.defaultStyles = mexui.util.linkStyles(mexui.Entity.Stylea
// input
mexui.Component.Window.prototype.onMouseDown = function(e)
{
- if(this.titleBarShown && this.titleBarIconShown && this.isCursorOverCloseIcon())
+ if(e.button == 0 && this.titleBarShown && this.titleBarIconShown && this.isCursorOverCloseIcon())
{
this.shown = false;
mexui.setInput(false);
@@ -240,7 +240,14 @@ mexui.Component.Window.prototype.triggerEvent = function(eventName, e, data, cal
{
this.controls[i][eventName].call(control, e, data);
if(e.used)
+ {
+ if(e.button == 0 && eventName == 'onMouseDown')
+ {
+ mexui.focusedControl = this.controls[i];
+ e.clickedAControl = true;
+ }
break;
+ }
if(mexui.Entity.Component.prototype[eventName])
{
@@ -360,6 +367,8 @@ mexui.Component.Window.prototype.minute = function(x, y, w, h, text, styles, c
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.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.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)); };
@@ -375,5 +384,6 @@ mexui.Component.Window.prototype.textInput = function(x, y, w, h, text, styles,
mexui.Component.Window.prototype.time = function(x, y, w, h, text, styles, callback) { return this.addControl(new mexui.Control.Time(this, x, y, w, h, text, styles, callback)); };
mexui.Component.Window.prototype.tree = function(x, y, w, h, styles, callback) { return this.addControl(new mexui.Control.Tree(this, x, y, w, h, styles, callback)); };
mexui.Component.Window.prototype.week = function(x, y, w, h, text, styles, callback) { return this.addControl(new mexui.Control.Week(this, x, y, w, h, text, styles, callback)); };
+mexui.Component.Window.prototype.weekDay = function(x, y, w, h, text, styles, callback) { return this.addControl(new mexui.Control.WeekDay(this, x, y, w, h, text, styles, callback)); };
mexui.Component.Window.prototype.year = function(x, y, w, h, text, styles, callback) { return this.addControl(new mexui.Control.Year(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 d1425c52..ef89836c 100644
--- a/third-party/mexui/Core/Control/Button.js
+++ b/third-party/mexui/Core/Control/Button.js
@@ -11,7 +11,16 @@ mexui.util.linkBaseControlStyles('Button', {});
// input
mexui.Control.Button.prototype.onMouseDown = function(e)
{
- if(this.isCursorOverControl())
+ if(e.button == 0 && this.isCursorOverControl())
+ {
+ e.used = true;
+ this.checkToCallCallback();
+ }
+};
+
+mexui.Control.Button.prototype.onKeyDown = function(e, key, mods)
+{
+ if(this.isFocused() && (key == SDLK_RETURN || key == SDLK_RETURN2 || key == SDLK_KP_ENTER || key == SDLK_SPACE))
{
e.used = true;
this.checkToCallCallback();
@@ -25,4 +34,7 @@ mexui.Control.Button.prototype.render = function()
mexui.native.drawRectangle(pos, this.size, this.getStyles('main'));
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'));
};
\ 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 9321af51..9404463a 100644
--- a/third-party/mexui/Core/Control/CheckBox.js
+++ b/third-party/mexui/Core/Control/CheckBox.js
@@ -19,11 +19,22 @@ mexui.util.linkBaseControlStyles('CheckBox', {
// input
mexui.Control.CheckBox.prototype.onMouseDown = function(e)
{
- if(this.isCursorOverControl())
+ if(e.button == 0 && this.isCursorOverControl())
{
e.used = true;
- this.checked = !this.checked;
- this.checkToCallCallback();
+ this.toggleChecked();
+ }
+};
+
+mexui.Control.CheckBox.prototype.onKeyDown = function(e, key, mods)
+{
+ if(this.isFocused())
+ {
+ if(key == SDLK_RETURN || key == SDLK_RETURN2 || key == SDLK_KP_ENTER || key == SDLK_SPACE)
+ {
+ e.used = true;
+ this.toggleChecked();
+ }
}
};
@@ -38,6 +49,9 @@ mexui.Control.CheckBox.prototype.render = function()
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.drawText(mexui.util.addVec2(pos, new Vec2(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'));
};
// model
@@ -45,4 +59,10 @@ 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);
+};
+
+mexui.Control.CheckBox.prototype.toggleChecked = function()
+{
+ this.checked = !this.checked;
+ this.checkToCallCallback();
};
\ No newline at end of file
diff --git a/third-party/mexui/Core/Control/Date.js b/third-party/mexui/Core/Control/Date.js
index 56989aaa..585a045d 100644
--- a/third-party/mexui/Core/Control/Date.js
+++ b/third-party/mexui/Core/Control/Date.js
@@ -9,6 +9,11 @@ mexui.util.createControlConstructor('Date', false, function(window, x, y, w, h,
this.inputShown = false;
this.valueBoxSize = new Vec2(50, 30);
this.arrowBoxSize = new Vec2(25, 22);
+
+ this.maxYearOffset = 10;
+ this.minYearCallback = ()=>{ return 1900; };
+ this.maxYearCallback = ()=>{ return new Date().getFullYear() + this.maxYearOffset; }
+ this.twoDigitYearCapOffset = 10;
});
mexui.util.extend(mexui.Control.Date, mexui.Control.TextInput);
@@ -51,10 +56,12 @@ mexui.Control.Date.prototype.onMouseDown = function(e)
else if(this.month == 13)
this.month = 1;
- if(this.year == 1899)
- this.year = 1900;
- else if(this.year == 2020)
- this.year = 2019;
+ var minYear = this.minYearCallback();
+ var maxYear = this.maxYearCallback();
+ if(this.year < minYear)
+ this.year = minYear;
+ else if(this.year > maxYear)
+ this.year = maxYear;
this.generateText();
@@ -113,31 +120,44 @@ mexui.Control.Date.prototype.renderAfter = function()
// model
mexui.Control.Date.prototype.generateText = function()
{
- this.text = (this.day < 10 ? '0'+this.day : this.day)
+ this.setText((this.day < 10 ? '0'+this.day : this.day)
+'/'+(this.month < 10 ? '0'+this.month : this.month)
- +'/'+(this.year < 10 ? '0'+this.year : this.year);
+ +'/'+(this.year < 10 ? '0'+this.year : this.year));
};
mexui.Control.Date.prototype.validateInputCallback = function(e, character)
{
- var text = this.getTextWithNewCharacter(character);
- var parts = text.split(':');
+ return mexui.util.isPositiveIntChar(character) || mexui.util.isLetter(character) || character == '/';
+};
+
+mexui.Control.Date.prototype.validateValueCallback = function(e)
+{
+ var parts = this.getText().split('/');
+
+ if(parts.length != 3)
+ return false;
for(var i in parts)
{
- if(i == 3)
+ var partAsStr = parts[i];
+ if(partAsStr === '')
return false;
- var part = parseInt(parts[i]);
-
- if(isNaN(part))
- return false;
-
- if(part < 0)
- return false;
-
- if(part > (i == 0 ? 23 : 59))
- return false;
+ if(i == 0)
+ {
+ if(!mexui.util.isDayIdWithOptionalSuffix(partAsStr))
+ return false;
+ }
+ else if(i == 1)
+ {
+ if(!mexui.util.isMonthIdOrName(partAsStr))
+ return false;
+ }
+ else if(i == 2)
+ {
+ if(!mexui.util.isYear(partAsStr, this.minYearCallback(), this.maxYearCallback(), this.twoDigitYearCapOffset))
+ return false;
+ }
}
return true;
diff --git a/third-party/mexui/Core/Control/Day.js b/third-party/mexui/Core/Control/Day.js
index 602b351d..6fd76806 100644
--- a/third-party/mexui/Core/Control/Day.js
+++ b/third-party/mexui/Core/Control/Day.js
@@ -7,13 +7,10 @@ mexui.util.extend(mexui.Control.Day, mexui.Control.TextInput);
// model
mexui.Control.Day.prototype.validateInputCallback = function(e, character)
{
- var _int = parseInt(character);
-
- if(isNaN(_int))
- return false;
-
- if(_int < 0 || _int > 31)
- return false;
-
- return true;
+ return mexui.util.isPositiveIntChar(character) || mexui.util.isLetter(character);
+};
+
+mexui.Control.Day.prototype.validateValueCallback = function(e)
+{
+ return mexui.util.isDayIdWithOptionalSuffix(this.getText());
};
\ No newline at end of file
diff --git a/third-party/mexui/Core/Control/DropDown.js b/third-party/mexui/Core/Control/DropDown.js
index a17c140e..ac394e3e 100644
--- a/third-party/mexui/Core/Control/DropDown.js
+++ b/third-party/mexui/Core/Control/DropDown.js
@@ -30,24 +30,25 @@ mexui.util.linkBaseControlStyles('DropDown', {
// input
mexui.Control.DropDown.prototype.onMouseDown = function(e)
{
- if(this.axis.y.entries.length == 0)
- return;
-
- var hitButton = this.isCursorOverControl();
- if(hitButton)
+ if(e.button == 0)
{
- e.used = true;
- this.setListShown(!this.axis.y.entriesShown);
- }
- else if(this.axis.y.entriesShown)
- {
- var selectedEntryIndex = this.axis.y.getEntryIndexByCursor();
- if(selectedEntryIndex != null)
+ if(this.axis.y.entries.length == 0)
+ return;
+
+ var hitButton = this.isCursorOverControl();
+ if(hitButton)
{
e.used = true;
- this.selectedEntryIndex = selectedEntryIndex;
- this.checkToCallCallback();
- this.setListShown(false);
+ this.setListShown(!this.axis.y.entriesShown);
+ }
+ else if(this.isListShown())
+ {
+ var selectedEntryIndex = this.axis.y.getEntryIndexByCursor();
+ if(selectedEntryIndex != null)
+ {
+ this.selectEntryByIndex(selectedEntryIndex);
+ e.used = true;
+ }
}
}
@@ -55,6 +56,27 @@ mexui.Control.DropDown.prototype.onMouseDown = function(e)
mexui.Entity.ControlWithEntries.prototype.onMouseDown.call(this, e);
};
+mexui.Control.DropDown.prototype.onKeyDown = function(e, key, mods)
+{
+ if(this.isFocused())
+ {
+ if(key == SDLK_RETURN || key == SDLK_RETURN2 || key == SDLK_KP_ENTER || key == SDLK_SPACE)
+ {
+ var selectedEntryIndex = this.axis.y.getEntryIndexByCursor();
+ if(selectedEntryIndex == null)
+ {
+ this.setListShown(!this.isListShown());
+ e.used = true;
+ }
+ else
+ {
+ this.selectEntryByIndex(selectedEntryIndex);
+ e.used = true;
+ }
+ }
+ }
+};
+
// render
mexui.Control.DropDown.prototype.render = function()
{
@@ -72,6 +94,9 @@ mexui.Control.DropDown.prototype.render = function()
}
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.Control.DropDown.prototype.renderAfter = function()
@@ -79,10 +104,14 @@ mexui.Control.DropDown.prototype.renderAfter = function()
if(this.axis.y.entriesShown)
{
var pos = this.getScreenPosition();
+ var pos2 = new Vec2(pos.x, pos.y);
pos.x += this.entriesPositionOffset.x;
pos.y += this.entriesPositionOffset.y;
+ pos2.x += this.entriesPositionOffset.x;
+ pos2.y += this.entriesPositionOffset.y;
+
for(var i=this.axis.y.getEntryStartIndex(),j=this.axis.y.getEntryEndIndex(); i 23)
+ if(_int < 1 || _int > 23)
return false;
return true;
diff --git a/third-party/mexui/Core/Control/Image.js b/third-party/mexui/Core/Control/Image.js
index f66c6a79..1231ab5f 100644
--- a/third-party/mexui/Core/Control/Image.js
+++ b/third-party/mexui/Core/Control/Image.js
@@ -14,4 +14,7 @@ mexui.Control.Image.prototype.render = function()
var pos = this.getScreenPosition();
mexui.native.drawImage(pos, this.size, this.image, 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'));
};
\ No newline at end of file
diff --git a/third-party/mexui/Core/Control/Integer.js b/third-party/mexui/Core/Control/Integer.js
index b8a4f7e9..ec00e46c 100644
--- a/third-party/mexui/Core/Control/Integer.js
+++ b/third-party/mexui/Core/Control/Integer.js
@@ -7,5 +7,10 @@ mexui.util.extend(mexui.Control.Integer, mexui.Control.TextInput);
// model
mexui.Control.Integer.prototype.validateInputCallback = function(e, character)
{
- return !isNaN(parseInt(this.getTextWithNewCharacter(character)));
+ return mexui.util.isIntChar(character);
+};
+
+mexui.Control.Integer.prototype.validateValueCallback = function(e)
+{
+ return mexui.util.isInt(this.getText());
};
\ No newline at end of file
diff --git a/third-party/mexui/Core/Control/List.js b/third-party/mexui/Core/Control/List.js
index 1819a850..4c6b82a6 100644
--- a/third-party/mexui/Core/Control/List.js
+++ b/third-party/mexui/Core/Control/List.js
@@ -23,7 +23,7 @@ mexui.util.linkBaseControlStyles('List', {
// input
mexui.Control.List.prototype.onMouseDown = function(e)
{
- if(this.isCursorOverControl())
+ if(e.button == 0 && this.isCursorOverControl())
{
this.activeRow = this.axis.y.getEntryByCursor();
this.checkToCallCallback();
@@ -34,6 +34,7 @@ mexui.Control.List.prototype.onMouseDown = function(e)
mexui.Control.List.prototype.render = function()
{
var pos = this.getScreenPosition();
+ var pos2 = new Vec2(pos.x, pos.y);
for(var i in this.axis.y.entries)
{
@@ -46,6 +47,9 @@ mexui.Control.List.prototype.render = function()
pos.y += this.rowHeight;
mexui.native.drawAALine(pos, new Vec2(pos.x + this.size.x, pos.y), this.getStyles('rowLine'));
}
+
+ if(this.isFocused())
+ mexui.native.drawRectangleBorder(mexui.util.subtractVec2(pos2,new Vec2(2,2)), mexui.util.addVec2(this.size,new Vec2(3,3)), this.getStyles('focused'));
};
// model
diff --git a/third-party/mexui/Core/Control/Minute.js b/third-party/mexui/Core/Control/Minute.js
index 2be5f2a7..432f5227 100644
--- a/third-party/mexui/Core/Control/Minute.js
+++ b/third-party/mexui/Core/Control/Minute.js
@@ -7,12 +7,14 @@ mexui.util.extend(mexui.Control.Minute, mexui.Control.TextInput);
// model
mexui.Control.Minute.prototype.validateInputCallback = function(e, character)
{
- var _int = parseInt(character);
+ return mexui.util.isPositiveIntChar(character);
+};
+
+mexui.Control.Minute.prototype.validateValueCallback = function(e)
+{
+ var _int = parseInt(this.getText());
- if(isNaN(_int))
- return false;
-
- if(_int < 0 || _int > 59)
+ if(_int < 1 || _int > 59)
return false;
return true;
diff --git a/third-party/mexui/Core/Control/Month.js b/third-party/mexui/Core/Control/Month.js
index 35656518..c23a1da4 100644
--- a/third-party/mexui/Core/Control/Month.js
+++ b/third-party/mexui/Core/Control/Month.js
@@ -7,13 +7,10 @@ mexui.util.extend(mexui.Control.Month, mexui.Control.TextInput);
// model
mexui.Control.Month.prototype.validateInputCallback = function(e, character)
{
- var _int = parseInt(character);
-
- if(isNaN(_int))
- return false;
-
- if(_int < 0 || _int > 11)
- return false;
-
- return true;
+ return mexui.util.isPositiveIntChar(character) || mexui.util.isLetter(character);
+};
+
+mexui.Control.Month.prototype.validateValueCallback = function(e)
+{
+ return mexui.util.isMonthIdOrName(this.getText());
};
\ No newline at end of file
diff --git a/third-party/mexui/Core/Control/Number.js b/third-party/mexui/Core/Control/Number.js
index 6fcc3a3c..f7e4ed28 100644
--- a/third-party/mexui/Core/Control/Number.js
+++ b/third-party/mexui/Core/Control/Number.js
@@ -7,5 +7,10 @@ mexui.util.extend(mexui.Control.Number, mexui.Control.TextInput);
// model
mexui.Control.Number.prototype.validateInputCallback = function(e, character)
{
- return !isNaN(parseFloat(this.getTextWithNewCharacter(character)));
+ return mexui.util.isFloatChar(character);
+};
+
+mexui.Control.Number.prototype.validateValueCallback = function(e)
+{
+ return mexui.util.isFloat(this.getText());
};
\ No newline at end of file
diff --git a/third-party/mexui/Core/Control/PositiveInteger.js b/third-party/mexui/Core/Control/PositiveInteger.js
new file mode 100644
index 00000000..6cb46e86
--- /dev/null
+++ b/third-party/mexui/Core/Control/PositiveInteger.js
@@ -0,0 +1,16 @@
+mexui.util.createControlConstructor('PositiveInteger', false, function(window, x, y, w, h, text, styles, callback)
+{
+ mexui.Control.TextInput.call(this, window, x, y, w, h, text, this.linkControlStyles('PositiveInteger', styles), callback, false, false);
+});
+mexui.util.extend(mexui.Control.PositiveInteger, mexui.Control.TextInput);
+
+// model
+mexui.Control.PositiveInteger.prototype.validateInputCallback = function(e, character)
+{
+ return mexui.util.isPositiveIntChar(character);
+};
+
+mexui.Control.PositiveInteger.prototype.validateValueCallback = function(e)
+{
+ return mexui.util.isPositiveInt(this.getText());
+};
\ No newline at end of file
diff --git a/third-party/mexui/Core/Control/PositiveNumber.js b/third-party/mexui/Core/Control/PositiveNumber.js
new file mode 100644
index 00000000..626d25ad
--- /dev/null
+++ b/third-party/mexui/Core/Control/PositiveNumber.js
@@ -0,0 +1,16 @@
+mexui.util.createControlConstructor('PositiveNumber', false, function(window, x, y, w, h, text, styles, callback)
+{
+ mexui.Control.TextInput.call(this, window, x, y, w, h, text, this.linkControlStyles('PositiveNumber', styles), callback, false, false);
+});
+mexui.util.extend(mexui.Control.PositiveNumber, mexui.Control.TextInput);
+
+// model
+mexui.Control.PositiveNumber.prototype.validateInputCallback = function(e, character)
+{
+ return mexui.util.isPositiveFloatChar(character);
+};
+
+mexui.Control.PositiveNumber.prototype.validateValueCallback = function(e)
+{
+ return mexui.util.isPositiveFloat(this.getText());
+};
\ No newline at end of file
diff --git a/third-party/mexui/Core/Control/RadioButton.js b/third-party/mexui/Core/Control/RadioButton.js
index 793511ff..87d686c8 100644
--- a/third-party/mexui/Core/Control/RadioButton.js
+++ b/third-party/mexui/Core/Control/RadioButton.js
@@ -20,13 +20,21 @@ mexui.util.linkBaseControlStyles('RadioButton', {
// input
mexui.Control.RadioButton.prototype.onMouseDown = function(e)
{
- if(this.isCursorOverControl())
+ if(e.button == 0 && this.isCursorOverControl())
{
- var checkedRadio = this.getCheckedRadio();
- if(checkedRadio != this.checked)
- checkedRadio.checked = false;
- this.checked = !this.checked;
- this.checkToCallCallback();
+ this.setChecked();
+ }
+};
+
+mexui.Control.RadioButton.prototype.onKeyDown = function(e, key, mods)
+{
+ if(this.isFocused())
+ {
+ if(key == SDLK_RETURN || key == SDLK_RETURN2 || key == SDLK_KP_ENTER || key == SDLK_SPACE)
+ {
+ e.used = true;
+ this.setChecked();
+ }
}
};
@@ -41,6 +49,9 @@ mexui.Control.RadioButton.prototype.render = function()
mexui.native.drawRectangle(mexui.util.addVec2(pos, new Vec2(2, 2)), new Vec2(this.size.x - 4, this.size.y - 4), 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'));
+
+ 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'));
};
// model
@@ -85,4 +96,14 @@ mexui.Control.RadioButton.prototype.getCheckedRadio = function()
mexui.Control.RadioButton.prototype.isFirstRadioInGroup = function()
{
return this.getGroupRadios().length == 0;
+};
+
+mexui.Control.RadioButton.prototype.setChecked = function()
+{
+ var checkedRadio = this.getCheckedRadio();
+ if(checkedRadio != this.checked)
+ checkedRadio.checked = false;
+
+ this.checked = !this.checked;
+ this.checkToCallCallback();
};
\ No newline at end of file
diff --git a/third-party/mexui/Core/Control/RangedInteger.js b/third-party/mexui/Core/Control/RangedInteger.js
index f8d07923..dafa0946 100644
--- a/third-party/mexui/Core/Control/RangedInteger.js
+++ b/third-party/mexui/Core/Control/RangedInteger.js
@@ -10,13 +10,15 @@ mexui.util.extend(mexui.Control.RangedInteger, mexui.Control.TextInput);
// model
mexui.Control.RangedInteger.prototype.validateInputCallback = function(e, character)
{
- var number = parseInt(this.getTextWithNewCharacter(character));
-
- if(!isNaN(number))
+ return mexui.util.isIntChar(character);
+};
+
+mexui.Control.RangedInteger.prototype.validateValueCallback = function(e)
+{
+ var text = this.getText();
+ if(!mexui.util.isInt(text))
return false;
- if(number < this.min || number > this.max)
- return false;
-
- return true;
+ var _int = parseInt(text);
+ return _int >= this.min && _int <= this.max;
};
\ No newline at end of file
diff --git a/third-party/mexui/Core/Control/RangedNumber.js b/third-party/mexui/Core/Control/RangedNumber.js
index 280ea2b9..45e16b05 100644
--- a/third-party/mexui/Core/Control/RangedNumber.js
+++ b/third-party/mexui/Core/Control/RangedNumber.js
@@ -10,13 +10,15 @@ mexui.util.extend(mexui.Control.RangedNumber, mexui.Control.TextInput);
// model
mexui.Control.RangedNumber.prototype.validateInputCallback = function(e, character)
{
- var number = parseFloat(this.getTextWithNewCharacter(character));
-
- if(!isNaN(number))
+ return mexui.util.isFloatChar(character);
+};
+
+mexui.Control.RangedNumber.prototype.validateValueCallback = function(e)
+{
+ var text = this.getText();
+ if(!mexui.util.isFloat(text))
return false;
- if(number < this.min || number > this.max)
- return false;
-
- return true;
+ var number = parseFloat(text);
+ return number >= this.min && number <= this.max;
};
\ No newline at end of file
diff --git a/third-party/mexui/Core/Control/ScrollBar.js b/third-party/mexui/Core/Control/ScrollBar.js
index f366c8a5..579fb037 100644
--- a/third-party/mexui/Core/Control/ScrollBar.js
+++ b/third-party/mexui/Core/Control/ScrollBar.js
@@ -36,22 +36,25 @@ mexui.util.linkBaseControlStyles('ScrollBar', {
// input
mexui.Control.ScrollBar.prototype.onMouseDown = function(e)
{
- if(mexui.util.isCursorInRectangle(this.getInnerBarPosition(), this.getInnerBarSize()))
+ if(e.button == 0)
{
- e.used = true;
- this.isScrolling = true;
- }
- else if(this.isCursorOverControl())
- {
- e.used = true;
- this.scrolledRatio += this.getScrolledRatioOuterBarClickIncrease();
- this.clampScrolledRatio();
+ if(mexui.util.isCursorInRectangle(this.getInnerBarPosition(), this.getInnerBarSize()))
+ {
+ e.used = true;
+ this.isScrolling = true;
+ }
+ else if(this.isCursorOverControl())
+ {
+ e.used = true;
+ this.scrolledRatio += this.getScrolledRatioOuterBarClickIncrease();
+ this.clampScrolledRatio();
+ }
}
};
mexui.Control.ScrollBar.prototype.onMouseUp = function(e)
{
- if(this.isScrolling)
+ if(e.button == 0 && this.isScrolling)
{
this.isScrolling = false;
e.used = true;
diff --git a/third-party/mexui/Core/Control/Second.js b/third-party/mexui/Core/Control/Second.js
index 3e9cb0bc..650e8125 100644
--- a/third-party/mexui/Core/Control/Second.js
+++ b/third-party/mexui/Core/Control/Second.js
@@ -7,12 +7,14 @@ mexui.util.extend(mexui.Control.Second, mexui.Control.TextInput);
// model
mexui.Control.Second.prototype.validateInputCallback = function(e, character)
{
- var _int = parseInt(character);
+ return mexui.util.isPositiveIntChar(character);
+};
+
+mexui.Control.Second.prototype.validateValueCallback = function(e)
+{
+ var _int = parseInt(this.getText());
- if(isNaN(_int))
- return false;
-
- if(_int < 0 || _int > 59)
+ if(_int < 1 || _int > 59)
return false;
return true;
diff --git a/third-party/mexui/Core/Control/Slider.js b/third-party/mexui/Core/Control/Slider.js
index bc6183a9..1abfebc6 100644
--- a/third-party/mexui/Core/Control/Slider.js
+++ b/third-party/mexui/Core/Control/Slider.js
@@ -36,7 +36,7 @@ mexui.util.linkBaseControlStyles('Slider', {
// input
mexui.Control.Slider.prototype.onMouseDown = function(e)
{
- if(this.isCursorOverInnerBar())
+ if(e.button == 0 && this.isCursorOverInnerBar())
{
this.sliding = true;
e.used = true;
@@ -45,7 +45,7 @@ mexui.Control.Slider.prototype.onMouseDown = function(e)
mexui.Control.Slider.prototype.onMouseUp = function(e)
{
- if(this.sliding)
+ if(e.button == 0 && this.sliding)
{
this.sliding = false;
this.checkToCallCallback();
@@ -67,6 +67,7 @@ mexui.Control.Slider.prototype.onMouseMove = function(e, offset)
mexui.Control.Slider.prototype.render = function()
{
var pos = this.getScreenPosition();
+ var pos2 = new Vec2(pos.x, pos.y);
mexui.native.drawRectangle(pos, this.size, this.getStyles('main'));
mexui.native.drawRectangle(this.getInnerBarPosition(), this.innerBarSize, this.getStyles('innerBar'));
@@ -81,6 +82,9 @@ mexui.Control.Slider.prototype.render = function()
pos.x += this.size.x - mexui.native.getTextWidth(this.maxText, this.getStyles('maxText'));
mexui.native.drawText(pos, this.size, this.maxText, this.getStyles('maxText'));
+
+ if(this.isFocused())
+ mexui.native.drawRectangleBorder(mexui.util.subtractVec2(pos2,new Vec2(2,2)), mexui.util.addVec2(this.size,new Vec2(3,3)), this.getStyles('focused'));
};
// model
diff --git a/third-party/mexui/Core/Control/TabPanel.js b/third-party/mexui/Core/Control/TabPanel.js
index 1d24020a..aa83369c 100644
--- a/third-party/mexui/Core/Control/TabPanel.js
+++ b/third-party/mexui/Core/Control/TabPanel.js
@@ -26,30 +26,33 @@ mexui.util.linkBaseControlStyles('TabPanel', {
// input
mexui.Control.TabPanel.prototype.onMouseDown = function(e)
{
- var pos = this.getScreenPosition();
-
- var tabX = pos.x;
- for(var i in this.axis.x.entries)
+ if(e.button == 0)
{
- var tab = this.axis.x.entries[i];
+ var pos = this.getScreenPosition();
- var tabPos = new Vec2(tabX, pos.y);
- var tabSize = new Vec2(mexui.native.getTextWidth(tab.text, this.getStyles('tab')) + 10, 25);
-
- if(mexui.util.isCursorInRectangle(tabPos, tabSize))
+ var tabX = pos.x;
+ for(var i in this.axis.x.entries)
{
- tab.setActive();
- break;
+ var tab = this.axis.x.entries[i];
+
+ var tabPos = new Vec2(tabX, pos.y);
+ var tabSize = new Vec2(mexui.native.getTextWidth(tab.text, this.getStyles('tab')) + 10, 25);
+
+ if(mexui.util.isCursorInRectangle(tabPos, tabSize))
+ {
+ tab.setActive();
+ break;
+ }
+
+ tabX += tabSize.x;
}
- tabX += tabSize.x;
+ /*
+ var tab = this.axis.x.getEntryByCursor();
+ if(tab)
+ tab.setActive();
+ */
}
-
- /*
- var tab = this.axis.x.getEntryByCursor();
- if(tab)
- tab.setActive();
- */
};
// render
@@ -71,6 +74,9 @@ mexui.Control.TabPanel.prototype.render = function()
tabX += tabSize.x;
}
+
+ 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'));
};
// model
diff --git a/third-party/mexui/Core/Control/Text.js b/third-party/mexui/Core/Control/Text.js
index bc045dc5..92532fc6 100644
--- a/third-party/mexui/Core/Control/Text.js
+++ b/third-party/mexui/Core/Control/Text.js
@@ -14,4 +14,7 @@ mexui.Control.Text.prototype.render = function()
var pos = this.getScreenPosition();
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'));
};
\ No newline at end of file
diff --git a/third-party/mexui/Core/Control/TextInput.js b/third-party/mexui/Core/Control/TextInput.js
index 824b4e3f..ea1e445b 100644
--- a/third-party/mexui/Core/Control/TextInput.js
+++ b/third-party/mexui/Core/Control/TextInput.js
@@ -17,6 +17,8 @@ mexui.util.createControlConstructor('TextInput', false, function(window, x, y, w
this.caretShownForBlink = true;
this.lineHeight = 25;
this.maxLength = this.singleCharacter ? 1 : false;
+
+ this.validValue = true;
});
// default styles
@@ -34,10 +36,13 @@ mexui.util.linkBaseControlStyles('TextInput', {
// input
mexui.Control.TextInput.prototype.onMouseDown = function(e)
{
- var hit = this.isCursorOverControl();
- if(hit)
+ if(e.button == 0)
{
- this.caretPosition = this.getCaretPositionByCursor();
+ var hit = this.isCursorOverControl();
+ if(hit)
+ {
+ this.caretPosition = this.getCaretPositionByCursor();
+ }
}
mexui.Component.Control.prototype.onMouseDown.call(this, e);
@@ -70,6 +75,7 @@ mexui.Control.TextInput.prototype.onCharacter = function(e, character)
}
this.checkToCallCallback();
+ this.validateValue(e);
}
};
@@ -193,12 +199,16 @@ mexui.Control.TextInput.prototype.onKeyDown = function(e, key, mods)
break;
}
}
+
+ this.validateValue(e);
};
// render
mexui.Control.TextInput.prototype.render = function()
{
var pos = this.getScreenPosition();
+ var pos2 = new Vec2(pos.x, pos.y);
+
mexui.native.drawRectangle(pos, this.size, this.getStyles('main'));
if(this.isEmpty())
@@ -217,22 +227,31 @@ mexui.Control.TextInput.prototype.render = function()
}
}
- if(mexui.focusedControl == this && this.caretShownForBlink)
+ var valueIsInvalid = !this.isEmpty() && !this.validValue;
+
+ if(this.isFocused())
{
- var pos = this.getScreenPosition();
- var text = this.lines[this.caretPosition.y].substr(0, this.caretPosition.x);
- var displayedText = this.masked ? '*'.repeat(text.length) : text;
- var textWidth = mexui.native.getTextWidth(displayedText, this.getStyles('main'));
- var caretPosOffset = new Vec2(5 + textWidth, (this.caretPosition.y * this.lineHeight) + 1);
- var caretPoint1 = mexui.util.addVec2(pos, caretPosOffset);
- var caretPoint2 = new Vec2(caretPoint1.x, caretPoint1.y + 22);
- mexui.native.drawAALine(caretPoint1, caretPoint2, this.getStyles('caret'));
+ if(!valueIsInvalid)
+ mexui.native.drawRectangleBorder(mexui.util.subtractVec2(pos2,new Vec2(2,2)), mexui.util.addVec2(this.size,new Vec2(3,3)), this.getStyles('focused'));
+
+ if(this.caretShownForBlink)
+ {
+ var pos = this.getScreenPosition();
+ var text = this.lines[this.caretPosition.y].substr(0, this.caretPosition.x);
+ var displayedText = this.masked ? '*'.repeat(text.length) : text;
+ var textWidth = mexui.native.getTextWidth(displayedText, this.getStyles('main'));
+ var caretPosOffset = new Vec2(5 + textWidth, (this.caretPosition.y * this.lineHeight) + 1);
+ var caretPoint1 = mexui.util.addVec2(pos, caretPosOffset);
+ var caretPoint2 = new Vec2(caretPoint1.x, caretPoint1.y + 22);
+ mexui.native.drawAALine(caretPoint1, caretPoint2, this.getStyles('caret'));
+ }
}
+
+ if(valueIsInvalid)
+ mexui.native.drawRectangleBorder(mexui.util.subtractVec2(pos2,new Vec2(2,2)), mexui.util.addVec2(this.size,new Vec2(3,3)), this.getStyles('invalidValue'));
};
// model
-
-
mexui.Control.TextInput.prototype.getTextWithNewCharacter = function(character)
{
return this.lines[this.caretPosition.y].substr(0, this.caretPosition.x) + character + this.lines[this.caretPosition.y].substr(this.caretPosition.x);
@@ -335,6 +354,16 @@ mexui.Control.TextInput.prototype.deleteCharacter = function(charPos)
};
// text overall
+mexui.Control.TextInput.prototype.setText = function(text)
+{
+ this.lines = mexui.util.splitLines(text);
+};
+
+mexui.Control.TextInput.prototype.getText = function()
+{
+ return this.lines.join("\r\n");
+};
+
mexui.Control.TextInput.prototype.resetText = function()
{
this.lines = [''];
@@ -345,3 +374,8 @@ mexui.Control.TextInput.prototype.isEmpty = function()
return this.lines.length == 1 && this.lines[0] == '';
};
+// validation
+mexui.Control.TextInput.prototype.validateValue = function(e)
+{
+ this.validValue = this.validateValueCallback ? this.validateValueCallback(e) : true;
+};
\ No newline at end of file
diff --git a/third-party/mexui/Core/Control/Time.js b/third-party/mexui/Core/Control/Time.js
index a326d649..597bb39c 100644
--- a/third-party/mexui/Core/Control/Time.js
+++ b/third-party/mexui/Core/Control/Time.js
@@ -102,24 +102,35 @@ mexui.Control.Time.prototype.renderAfter = function()
// model
mexui.Control.Time.prototype.generateText = function()
{
- this.text = (this.hour < 10 ? '0'+this.hour : this.hour)
+ this.setText((this.hour < 10 ? '0'+this.hour : this.hour)
+':'+(this.minute < 10 ? '0'+this.minute : this.minute)
- +':'+(this.second < 10 ? '0'+this.second : this.second);
+ +':'+(this.second < 10 ? '0'+this.second : this.second));
};
mexui.Control.Time.prototype.validateInputCallback = function(e, character)
{
- var text = this.getTextWithNewCharacter(character);
- var parts = text.split(':');
+ return mexui.util.isPositiveIntChar(character) || character == ':';
+};
+
+mexui.Control.Time.prototype.validateValueCallback = function(e)
+{
+ var parts = this.getText().split(':');
+
+ if(parts.length != 3)
+ return false;
for(var i in parts)
{
- if(i == 3)
+ var partAsStr = parts[i];
+ if(partAsStr === '')
return false;
- var part = parseInt(parts[i]);
+ var part = parseInt(partAsStr);
- if(isNaN(part))
+ if(partAsStr.length == 2 && partAsStr.substr(0, 1) == '0')
+ partAsStr = partAsStr.substr(1);
+
+ if(!mexui.util.isPositiveInt(partAsStr))
return false;
if(part < 0)
diff --git a/third-party/mexui/Core/Control/Tree.js b/third-party/mexui/Core/Control/Tree.js
index 1dc2e2cf..a6e5d56b 100644
--- a/third-party/mexui/Core/Control/Tree.js
+++ b/third-party/mexui/Core/Control/Tree.js
@@ -28,10 +28,13 @@ mexui.util.linkBaseControlStyles('Tree', {
// input
mexui.Control.Tree.prototype.onMouseDown = function(e)
{
- var pos = this.getScreenPosition();
- pos.y -= this.axis.y.getScrolledOffset();
-
- this.testRowClick(e, this.axis.y.entries, pos);
+ if(e.button == 0)
+ {
+ var pos = this.getScreenPosition();
+ pos.y -= this.axis.y.getScrolledOffset();
+
+ this.testRowClick(e, this.axis.y.entries, pos);
+ }
if(!e.used)
mexui.Entity.ControlWithEntries.prototype.onMouseDown.call(this, e);
@@ -44,6 +47,9 @@ mexui.Control.Tree.prototype.render = function()
pos.y -= this.axis.y.getScrolledOffset();
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.Control.Tree.prototype.renderRows = function(rows, level, pos)
diff --git a/third-party/mexui/Core/Control/Week.js b/third-party/mexui/Core/Control/Week.js
index 2ccb03b4..a141b319 100644
--- a/third-party/mexui/Core/Control/Week.js
+++ b/third-party/mexui/Core/Control/Week.js
@@ -7,12 +7,14 @@ mexui.util.extend(mexui.Control.Week, mexui.Control.TextInput);
// model
mexui.Control.Week.prototype.validateInputCallback = function(e, character)
{
- var _int = parseInt(character);
+ return mexui.util.isPositiveIntChar(character);
+};
+
+mexui.Control.Week.prototype.validateValueCallback = function(e)
+{
+ var _int = parseInt(this.getText());
- if(isNaN(_int))
- return false;
-
- if(_int < 0 || _int > 51)
+ if(_int < 1 || _int > 52)
return false;
return true;
diff --git a/third-party/mexui/Core/Control/WeekDay.js b/third-party/mexui/Core/Control/WeekDay.js
new file mode 100644
index 00000000..2e4115b2
--- /dev/null
+++ b/third-party/mexui/Core/Control/WeekDay.js
@@ -0,0 +1,16 @@
+mexui.util.createControlConstructor('WeekDay', false, function(window, x, y, w, h, text, styles, callback)
+{
+ mexui.Control.TextInput.call(this, window, x, y, w, h, text, this.linkControlStyles('WeekDay', styles), callback, false, false);
+});
+mexui.util.extend(mexui.Control.WeekDay, mexui.Control.TextInput);
+
+// model
+mexui.Control.WeekDay.prototype.validateInputCallback = function(e, character)
+{
+ return mexui.util.isPositiveIntChar(character) || mexui.util.isLetter(character);
+};
+
+mexui.Control.WeekDay.prototype.validateValueCallback = function(e)
+{
+ return mexui.util.isWeekDayIdOrName(this.getText());
+};
\ No newline at end of file
diff --git a/third-party/mexui/Core/Control/Year.js b/third-party/mexui/Core/Control/Year.js
index 85956a06..b1921ec4 100644
--- a/third-party/mexui/Core/Control/Year.js
+++ b/third-party/mexui/Core/Control/Year.js
@@ -1,19 +1,21 @@
mexui.util.createControlConstructor('Year', false, function(window, x, y, w, h, text, styles, callback)
{
mexui.Control.TextInput.call(this, window, x, y, w, h, text, this.linkControlStyles('Year', styles), callback, false, false);
+
+ this.maxYearOffset = 10;
+ this.minYearCallback = ()=>{ return 1900; };
+ this.maxYearCallback = ()=>{ return new Date().getFullYear() + this.maxYearOffset; }
+ this.twoDigitYearCapOffset = 10;
});
mexui.util.extend(mexui.Control.Year, mexui.Control.TextInput);
// model
mexui.Control.Year.prototype.validateInputCallback = function(e, character)
{
- var _int = parseInt(character);
-
- if(isNaN(_int))
- return false;
-
- if(_int < 1900 || _int > 2019)
- return false;
-
- return true;
+ return mexui.util.isPositiveIntChar(character);
+};
+
+mexui.Control.Year.prototype.validateValueCallback = function(e)
+{
+ return mexui.util.isYear(this.getText(), this.minYearCallback(), this.maxYearCallback(), this.twoDigitYearCapOffset);
};
\ No newline at end of file
diff --git a/third-party/mexui/Core/Entity/Component.js b/third-party/mexui/Core/Entity/Component.js
index 5160d833..e0afae23 100644
--- a/third-party/mexui/Core/Entity/Component.js
+++ b/third-party/mexui/Core/Entity/Component.js
@@ -9,7 +9,7 @@ mexui.util.extend(mexui.Entity.Component, mexui.Entity.StyleableEntity);
// input
mexui.Entity.Component.prototype.onMouseDown = function(e)
{
- if(this.moveable && this.isCursorOverComponent())
+ if(e.button == 0 && this.moveable && this.isCursorOverComponent())
{
this.moving = true;
e.used = true;
@@ -18,7 +18,7 @@ mexui.Entity.Component.prototype.onMouseDown = function(e)
mexui.Entity.Component.prototype.onMouseUp = function(e)
{
- if(this.moving)
+ if(e.button == 0 && this.moving)
{
this.moving = false;
e.used = true;
diff --git a/third-party/mexui/Core/Entity/StyleableEntity.js b/third-party/mexui/Core/Entity/StyleableEntity.js
index 1b6f8791..ea25df16 100644
--- a/third-party/mexui/Core/Entity/StyleableEntity.js
+++ b/third-party/mexui/Core/Entity/StyleableEntity.js
@@ -53,6 +53,14 @@ mexui.Entity.StyleableEntity.defaultStyles = mexui.util.linkGlobalStyles(mexui.E
textColour: toColour(0, 0, 0, 255)
}
*/
+ },
+ focused:
+ {
+ borderColour: toColour(28, 119, 198, 255)
+ },
+ invalidValue:
+ {
+ borderColour: toColour(250, 5, 5, 255)
}
});
diff --git a/third-party/mexui/Core/Native.js b/third-party/mexui/Core/Native.js
index c07fd6d8..efe3c32a 100644
--- a/third-party/mexui/Core/Native.js
+++ b/third-party/mexui/Core/Native.js
@@ -10,7 +10,19 @@ mexui.native.loadImage = function(imageFilePath, imageName)
return false;
}
- var image = drawing.loadPNG(file);
+ var image = null;
+ var parts = imageFilePath.split('.');
+ var ext = parts[parts.length - 1].toLowerCase();
+ if(ext == 'png')
+ image = drawing.loadPNG(file);
+ else if(ext == 'bmp')
+ image = drawing.loadBMP(file);
+ else
+ {
+ console.log('ERROR [IMAGE LOAD] - Unsupported image file path extension. Currently only supports PNG or BMP.');
+ return false;
+ }
+
if(!image)
{
file.close();
@@ -121,9 +133,6 @@ mexui.native.drawAALine = function(point1, point2, styles)
if(lineColour == null || lineColour == 'none')
return;
- //console.log(typeof lineColour);
- //console.log(lineColour);
-
drawing.drawRectangle(null, point1, new Vec2((point2.x - point1.x) + styles.lineWeight, (point2.y - point1.y) + styles.lineWeight), lineColour, lineColour, lineColour, lineColour);
};
diff --git a/third-party/mexui/Core/Utility.js b/third-party/mexui/Core/Utility.js
index 331d5cdf..25098920 100644
--- a/third-party/mexui/Core/Utility.js
+++ b/third-party/mexui/Core/Utility.js
@@ -1,5 +1,10 @@
mexui.util = {};
+// static
+mexui.util.monthNames = ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'];
+mexui.util.weekDayNames = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'];
+
+// functions
mexui.util.extend = function(d, b)
{
d.prototype = Object.create(b.prototype);
@@ -24,6 +29,11 @@ mexui.util.addVec2 = function(vec2a, vec2b)
return new Vec2(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);
+};
+
mexui.util.addVec3 = function(vec3a, vec3b)
{
return new Vec3(vec3a.x + vec3b.x, vec3a.y + vec3b.y, vec3a.z + vec3b.z);
@@ -469,3 +479,226 @@ mexui.util.time = function()
return gta.tickCount;
};
+mexui.util.isIntChar = function(character)
+{
+ return mexui.util.isPositiveIntChar(character);
+};
+
+mexui.util.isPositiveIntChar = function(character)
+{
+ return mexui.util.isDigit(character) || character == '-' || character == '+' || character == 'e' || character == 'E';
+};
+
+mexui.util.isFloatChar = function(character)
+{
+ return mexui.util.isIntChar(character) || character == '.';
+};
+
+mexui.util.isPositiveFloatChar = function(character)
+{
+ return mexui.util.isPositiveIntChar(character) || character == '.';
+};
+
+mexui.util.isInt = function(str)
+{
+ var strInt = parseInt(str);
+ return !isNaN(strInt) && str.length == (strInt+'').length;
+};
+
+mexui.util.isPositiveInt = function(str)
+{
+ var strInt = parseInt(str);
+ return !isNaN(strInt) && strInt >= 0 && str.length == (strInt+'').length;
+};
+
+mexui.util.isFloat = function(str)
+{
+ var strFloat = parseFloat(str);
+ var firstDot = str.indexOf('.');
+ var addOffset = (str.substr(str.length - 2, 2) == '.0' && firstDot == (str.length - 2)) ? 2 : 0;
+ if(firstDot == 0)
+ addOffset--;
+ return !isNaN(strFloat) && str.length == ((strFloat+'').length + addOffset);
+};
+
+mexui.util.isPositiveFloat = function(str)
+{
+ var strFloat = parseFloat(str);
+ var firstDot = str.indexOf('.');
+ var addOffset = (str.substr(str.length - 2, 2) == '.0' && firstDot == (str.length - 2)) ? 2 : 0;
+ if(firstDot == 0)
+ addOffset--;
+ return !isNaN(strFloat) && strFloat >= 0.0 && str.length == ((strFloat+'').length + addOffset);
+};
+
+mexui.util.isMonthName = function(text)
+{
+ return mexui.util.inArrayOrStartsWithInArray(text, mexui.util.monthNames, 3);
+};
+
+mexui.util.isWeekDayName = function(text)
+{
+ return mexui.util.inArrayOrStartsWithInArray(text, mexui.util.weekDayNames, 3);
+};
+
+mexui.util.isDayIdSuffix = function(text)
+{
+ switch(text.toLowerCase())
+ {
+ case 'st':
+ case 'nd':
+ case 'rd':
+ case 'th':
+ return true;
+ }
+ return false;
+};
+
+mexui.util.isDayIdSuffixForDayId = function(dayId, text)
+{
+ switch(text.toLowerCase())
+ {
+ case 'st': return dayId == 1 || dayId == 21 || dayId == 31;
+ case 'nd': return dayId == 2 || dayId == 22;
+ case 'rd': return dayId == 3 || dayId == 23;
+ case 'th': return !(dayId >= 1 && dayId <= 3) && !(dayId >= 21 && dayId <= 23) && dayId != 31;
+ default: return false;
+ }
+};
+
+mexui.util.isDayId = function(text)
+{
+ if(text.length == 2 && text.substr(0, 1) == '0')
+ text = text.substr(1);
+
+ if(mexui.util.isPositiveInt(text))
+ {
+ var _int = parseInt(text);
+ if(_int >= 1 && _int <= 31)
+ return true;
+ }
+
+ return false;
+};
+
+mexui.util.isDayIdWithOptionalSuffix = function(text)
+{
+ if(mexui.util.isDayId(text))
+ return true;
+
+ if(text.length > 2)
+ {
+ var last2Chars = text.substr(text.length - 2, 2);
+ if(mexui.util.isDayIdSuffix(last2Chars))
+ {
+ var textWithoutLast2Chars = text.substr(0, text.length - 2);
+ if(mexui.util.isDayId(textWithoutLast2Chars) && mexui.util.isDayIdSuffixForDayId(parseInt(textWithoutLast2Chars), last2Chars))
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+};
+
+mexui.util.inArrayOrStartsWithInArray = function(text, arr, startsWithCharCount)
+{
+ text = text.toLowerCase();
+
+ for(var i in arr)
+ {
+ if(text === arr[i])
+ {
+ return true;
+ }
+ }
+
+ if(text.length == startsWithCharCount)
+ {
+ for(var i in arr)
+ {
+ if(text === arr[i].substr(0, startsWithCharCount))
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+};
+
+mexui.util.isMonthIdOrName = function(text)
+{
+ var text2 = text;
+ if(text2.length == 2 && text2.substr(0, 1) == '0')
+ text2 = text2.substr(1);
+
+ if(mexui.util.isPositiveInt(text2))
+ {
+ var _int = parseInt(text2);
+ if(_int >= 1 && _int <= 12)
+ return true;
+ }
+
+ return mexui.util.isMonthName(text);
+};
+
+mexui.util.isWeekDayId = function(text)
+{
+ var text2 = text;
+ if(text2.length == 2 && text2.substr(0, 1) == '0')
+ text2 = text2.substr(1);
+
+ if(mexui.util.isPositiveInt(text2))
+ {
+ var _int = parseInt(text2);
+ if(_int >= 1 && _int <= 7)
+ return true;
+ }
+
+ return false;
+};
+
+mexui.util.isWeekDayIdOrName = function(text)
+{
+ var text2 = text;
+ if(text2.length == 2 && text2.substr(0, 1) == '0')
+ text2 = text2.substr(1);
+
+ if(mexui.util.isPositiveInt(text2))
+ {
+ var _int = parseInt(text2);
+ if(_int >= 1 && _int <= 7)
+ return true;
+ }
+
+ return mexui.util.isWeekDayName(text);
+};
+
+mexui.util.expand2DigitYear = function(year, twoDigitYearCapOffset)
+{
+ var currentFullYear = new Date().getFullYear();
+ var currentTwoDigitYearPlusCapOffset = parseInt((currentFullYear+'').substr(2, 2)) + twoDigitYearCapOffset;
+ if(year <= currentTwoDigitYearPlusCapOffset)
+ year += currentFullYear - (currentFullYear % 100);
+ else
+ year += (currentFullYear - (currentFullYear % 100)) - 100;
+ return year;
+};
+
+mexui.util.isYear = function(text, minYear, maxYear, twoDigitYearCapOffset)
+{
+ var _int = parseInt(text);
+
+ if(isNaN(_int))
+ return false;
+
+ if(_int >= 0 && _int <= 99)
+ _int = mexui.util.expand2DigitYear(_int, twoDigitYearCapOffset);
+
+ if(_int < minYear || _int > maxYear)
+ return false;
+
+ return true;
+};
\ No newline at end of file
diff --git a/third-party/mexui/Images/down-arrow-bak.png b/third-party/mexui/Images/down-arrow-bak.png
new file mode 100644
index 00000000..63fe7a57
Binary files /dev/null and b/third-party/mexui/Images/down-arrow-bak.png differ
diff --git a/third-party/mexui/mexui.js b/third-party/mexui/mexui.js
index 422fb45f..9829f4eb 100644
--- a/third-party/mexui/mexui.js
+++ b/third-party/mexui/mexui.js
@@ -17,7 +17,7 @@ mexui.hoveredComponent = null;
// initialization
mexui.init = function()
{
- mexui.native.loadImage('third-party/mexui/Images/down-arrow.png', 'downArrow');
+ mexui.native.loadImage('mexui/Images/down-arrow.png', 'downArrow');
mexui.bindEvents();
mexui.startTimers();
};
@@ -25,24 +25,26 @@ mexui.init = function()
// events
mexui.bindEvents = function()
{
- addEventHandler('onMouseDown', function(event)
+ addEventHandler('onMouseDown', function(event, mouse, button)
{
- var e = mexui.triggerEvent('onMouseDown');
+ var e = mexui.triggerEvent('onMouseDown', {button: button});
if(!e.clickedAControl)
{
mexui.focusedControl = null;
}
});
- addEventHandler('onMouseUp', function(event)
+ addEventHandler('onMouseUp', function(event, mouse, button)
{
- mexui.triggerEvent('onMouseUp');
+ mexui.triggerEvent('onMouseUp', {button: button});
});
addEventHandler('onMouseMove', function(event, mouse, isAbsolute, position)
{
- var mouseSpeed = gta.getMouseSpeed();
- mexui.triggerEvent('onMouseMove', new Vec2(mouseSpeed.x, -mouseSpeed.y), true);
+ if(isAbsolute)
+ return;
+
+ mexui.triggerEvent('onMouseMove', new Vec2(position.x, position.y), true);
});
addEventHandler('onMouseWheel', function(event, mouse, offset, flipped)
@@ -116,6 +118,10 @@ mexui.render = function()
mexui.triggerEvent = function(eventName, data, callBaseMethodFirst)
{
var e = new mexui.Component.Event();
+
+ if(data.button !== undefined)
+ e.button = data.button;
+
var windows = mexui.windows.slice(0, mexui.windows.length).reverse();
for(var i in windows)
{
@@ -281,12 +287,12 @@ mexui.isAnyWindowShown = function()
mexui.setInput = function(showInput)
{
gui.showCursor(showInput, !showInput);
- if(localPlayer)
- {
- if(showInput)
- setCameraLookAtEntity(new Vec3(cameraMatrix.m41, cameraMatrix.m42, cameraMatrix.m43), localPlayer, false);
- else
- restoreCamera(false);
- }
+ //if(localPlayer)
+ //{
+ // if(showInput)
+ // gta.setCameraLookAtEntity(new Vec3(gta.cameraMatrix.m41, gta.cameraMatrix.m42, gta.cameraMatrix.m43), localPlayer, false);
+ // else
+ // gta.restoreCamera(false);
+ //}
};