Compare commits
211 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
be29c02960 | ||
|
|
79e351cf8f | ||
|
|
1cc54d4dd9 | ||
|
|
b4aca0257f | ||
|
|
a11560b5b9 | ||
|
|
0368ea3371 | ||
|
|
ea4cd87202 | ||
|
|
af2de3455e | ||
|
|
785e506d69 | ||
|
|
eb30c616af | ||
|
|
a2eca84f52 | ||
|
|
a92fc14570 | ||
|
|
063b2aab4f | ||
|
|
242210bc9d | ||
|
|
9ab6bf2700 | ||
|
|
99da6df3ee | ||
|
|
bf88a14b23 | ||
|
|
72adf16515 | ||
|
|
f6cb20b4ff | ||
|
|
9a06d7e7ba | ||
|
|
3de60247c6 | ||
|
|
36c074ee3d | ||
|
|
cbb820ec9f | ||
|
|
cf38abac7f | ||
|
|
f0d0384a41 | ||
|
|
37d485a7c3 | ||
|
|
1b04c60576 | ||
|
|
0fcd38dd51 | ||
|
|
5c2320adea | ||
|
|
9713ecaf63 | ||
|
|
c1aaf8af53 | ||
|
|
5dbc93f38c | ||
|
|
96586f6be0 | ||
|
|
4b63689f6e | ||
|
|
5d3119f051 | ||
|
|
ec4a35d7bb | ||
|
|
4e10158b29 | ||
|
|
b15964e763 | ||
|
|
0a9866ac9e | ||
|
|
7bb7775898 | ||
|
|
c664e40d1e | ||
|
|
0d9388afa7 | ||
|
|
07cd95b861 | ||
|
|
dbef2a2d5d | ||
|
|
4cb1639461 | ||
|
|
f70021a4f2 | ||
|
|
c54b0abf07 | ||
|
|
f843e43d66 | ||
|
|
38e60a4837 | ||
|
|
90caff03a6 | ||
|
|
eb7512f75c | ||
|
|
cdb67fa7e6 | ||
|
|
d8b35d9aa9 | ||
|
|
e0ae0793db | ||
|
|
d87dfb0b05 | ||
|
|
7193e349df | ||
|
|
7f6945f402 | ||
|
|
ef4c64f722 | ||
|
|
992cc53dfd | ||
|
|
c6e1fb7f6d | ||
|
|
16549d5042 | ||
|
|
e34d24033e | ||
|
|
738cd55e75 | ||
|
|
1d0cbbd176 | ||
|
|
d01a413ecc | ||
|
|
72ae8aeead | ||
|
|
6b3651f660 | ||
|
|
77ef9dab35 | ||
|
|
802a489fee | ||
|
|
f1d53734d3 | ||
|
|
1da6b82af5 | ||
|
|
fef84bf75b | ||
|
|
1782b6af2c | ||
|
|
c61eee4197 | ||
|
|
b695b3d9d0 | ||
|
|
2ee939cc2c | ||
|
|
732940e56f | ||
|
|
19b433e7fb | ||
|
|
1d281256a1 | ||
|
|
e1137b728b | ||
|
|
908c5980e7 | ||
|
|
a8637692ee | ||
|
|
e2f7b5403a | ||
|
|
880de94677 | ||
|
|
ef62513115 | ||
|
|
f2166cc804 | ||
|
|
b7cd14c654 | ||
|
|
c4a2f0aeda | ||
|
|
e27521761f | ||
|
|
0c936d4a8f | ||
|
|
ea8efdc70a | ||
|
|
23c8acae21 | ||
|
|
868bb10091 | ||
|
|
453a946a1c | ||
|
|
8a206bcaf8 | ||
|
|
588359ef27 | ||
|
|
b27305e788 | ||
|
|
f6ce6105e2 | ||
|
|
ff2d416539 | ||
|
|
9f8d4cf034 | ||
|
|
3f925a4a44 | ||
|
|
b4d8acc07b | ||
|
|
623434d70f | ||
|
|
f603d71062 | ||
|
|
f9d6f9eff3 | ||
|
|
793b764469 | ||
|
|
3da2507cf7 | ||
|
|
d7bbe1748e | ||
|
|
e36d366f84 | ||
|
|
b7eac224c5 | ||
|
|
67b8266a71 | ||
|
|
f39697bf29 | ||
|
|
abea95a909 | ||
|
|
a9007338af | ||
|
|
d55ae9ea6b | ||
|
|
16a8014920 | ||
|
|
cb54cc9aa5 | ||
|
|
b463c9f71f | ||
|
|
c8b2dca8de | ||
|
|
4e0565eefe | ||
|
|
edcc063d8c | ||
|
|
da578f40d9 | ||
|
|
0900b0637a | ||
|
|
84a55d76fb | ||
|
|
12f9a66349 | ||
|
|
081f78e53b | ||
|
|
272cfd9a3f | ||
|
|
d15ed19401 | ||
|
|
57d274b334 | ||
|
|
1c5d2669fc | ||
|
|
896cb75591 | ||
|
|
920cfbd2ae | ||
|
|
9205f07dbe | ||
|
|
a388d94244 | ||
|
|
0c7b25d0a8 | ||
|
|
f4a2425fce | ||
|
|
796072daab | ||
|
|
085173d807 | ||
|
|
11f034698b | ||
|
|
0762e4ac52 | ||
|
|
3fdc038242 | ||
|
|
9c9d242ae4 | ||
|
|
69317b3b1f | ||
|
|
e14d7170aa | ||
|
|
d7b911004b | ||
|
|
14fe451c83 | ||
|
|
9c86ad0e2c | ||
|
|
a8802c0c7e | ||
|
|
c4fc123d75 | ||
|
|
64a9280fe6 | ||
|
|
b11510005a | ||
|
|
85b934064e | ||
|
|
542d1384db | ||
|
|
93e48df39a | ||
|
|
52e8d6c1db | ||
|
|
b632e1d26b | ||
|
|
efea8a015f | ||
|
|
a0d03a0aab | ||
|
|
c225c4d130 | ||
|
|
8532aa74ca | ||
|
|
0f788068c1 | ||
|
|
d07a890a10 | ||
|
|
b746970b9f | ||
|
|
64a3d2daf8 | ||
|
|
56ce5b7846 | ||
|
|
d940d6033e | ||
|
|
49026b7faf | ||
|
|
b9f47539a8 | ||
|
|
51194882c1 | ||
|
|
998dbf33f8 | ||
|
|
dff8b8b8db | ||
|
|
21b2429536 | ||
|
|
520164269b | ||
|
|
44cbdc07ac | ||
|
|
ac397a9011 | ||
|
|
8e11b9337b | ||
|
|
d2335e7bec | ||
|
|
b39abaab6c | ||
|
|
150d3f10b0 | ||
|
|
810acd8036 | ||
|
|
339ec0808c | ||
|
|
d1e9b6f08b | ||
|
|
f6d1ee189c | ||
|
|
549f8a3c59 | ||
|
|
e8d7b9312a | ||
|
|
fcdf8542d6 | ||
|
|
5401bb33c2 | ||
|
|
7b9a41f8d1 | ||
|
|
a5008bdbf5 | ||
|
|
e3a0b27c4e | ||
|
|
697ccd860f | ||
|
|
9536ed9aa9 | ||
|
|
5ebbe17920 | ||
|
|
d8dde07845 | ||
|
|
9c16ceeb3a | ||
|
|
faf4a1569c | ||
|
|
d70a8d451a | ||
|
|
a0477b10fe | ||
|
|
700e98768e | ||
|
|
adb8975c6a | ||
|
|
c76459e777 | ||
|
|
961670687f | ||
|
|
eaa0f3a563 | ||
|
|
4dcbcf5658 | ||
|
|
77fbc48f4e | ||
|
|
b4ac02f9ec | ||
|
|
1cb02b9ab1 | ||
|
|
b42f98917d | ||
|
|
62a4581c55 | ||
|
|
0607057f3f | ||
|
|
ab4cd7a212 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
.vs/
|
||||
.git/
|
||||
*.code-workspace
|
||||
config
|
||||
|
||||
41
ECONOMY.md
Normal file
41
ECONOMY.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# Economy Information
|
||||
|
||||
### Basic Information
|
||||
Each server has it's own independent economy with simulated inflation and is designed to slowly self-repair over time, assuming nothing is affecting it too heavily.
|
||||
|
||||
---
|
||||
|
||||
### Asset Ownership
|
||||
Any player or clan is allowed to own as many businesses, vehicles, and houses as they want. However, it should be noted that the more you own, the more upkeep (via taxes, insurance, etc) is required. Failure to maintain this upkeep for too long will automatically force you to lose the unmaintained assets. Vehicle owners can park their car anywhere (subject to IC parking laws), store items in the trunk or dash compartment, give anybody access, and set the price if they want to make it available to buy, and more. Business owners can stock their store with any item they want, set what prices they want for any item for sale, close/open the business, keep a stock of items in the business's storage, force people to pay a fee to enter, and more. House owners can store items in their house, purchase a safe, decorate with furniture, give anybody access, and more.
|
||||
|
||||
---
|
||||
|
||||
### Ordering Items for a Business
|
||||
Ordering items is simple: just use the /bizorder command.
|
||||
You'll need to specify which item you want to order and how many.
|
||||
Remember, the prices will vary depending on certain circumstances.
|
||||
|
||||
The formula is as follows:
|
||||
> Base price * server inflation * demand * risk * amount
|
||||
|
||||
**Here's a breakdown on how the above formula works:**
|
||||
* First, each item has a base price. This value will never change.
|
||||
|
||||
* Next, the base price is multiplied by the server's current inflation value. When the servers were first opened, the inflation value is 100%, which means no inflation. Everything cost 100% of it's calculated price. However, the inflation will slowly increase over time, simulating realistic economy inflation.
|
||||
|
||||
* Next, the inflated price is then multiplied by the demand factor, which is determined by how much demand there is for the item you want. Every 10 of the item ordered increases the demand value by 10%, and this will slowly go back down over time. If another business just ordered 100 of the item you want, the demand has forced the item's order price to increase by 100%, which means it's now double the original price. This simulates the things involved with increased demand, such as the extra manufacturing and shipping needed to get this item imported to your business.
|
||||
|
||||
* Next, the cost is multiplied by a risk value. This value never changes, and varies depending on the item. For illegal items, the risk value will be lower for less-risky items and higher as they get worse. For example, a shotgun versus an AK-47 have different risk levels, as an AK-47 is a far deadlier and a harder to get weapon, and is more difficult to conceal through customs. This simulates the "risk" of ordering items like these. For legal items, there is no risk so the risk price won't increase for those.
|
||||
|
||||
* Finally, the order cost is multiplied by the amount you want to order.
|
||||
|
||||
|
||||
**An example of this formula in action is below ... shown for an order for 10 AK-47's with no inflation**
|
||||
*The demand is increased by 10% since you're ordering 10 of them. 1 = 100% of the normal cost, 1.1 = 110%, and so on.*
|
||||
> Base price $1000
|
||||
> x inflation 1 = $1000
|
||||
> x demand 1.1 = $1100
|
||||
> x risk 5 = $5500
|
||||
> x amount 10 = $55000
|
||||
|
||||
So as you can see, the total cost to order 10 AK-47's in this scenario is $55,000. Remember, an AK-47 is a deadly and uncommon weapon (and highly illegal!) so it's a very risky and costly thing to do business with.
|
||||
25
README.md
25
README.md
@@ -1,7 +1,7 @@
|
||||
# Vortrex's Roleplay Resource
|
||||
|
||||
### Description
|
||||
This is Vortrex's Roleplay Resource
|
||||
This is Vortrex's Roleplay Resource. Originally created for [GTA Connected](https://gtaconnected.com/) but support for other multiplayer mods coming soon!
|
||||
|
||||
### Supported Games and Multiplayer Mods
|
||||
* GTA III (on [GTA Connected](https://gtaconnected.com/))
|
||||
@@ -9,6 +9,29 @@ This is Vortrex's Roleplay Resource
|
||||
* GTA SA (on [GTA Connected](https://gtaconnected.com/))
|
||||
* GTA IV (on [GTA Connected](https://gtaconnected.com/))
|
||||
* Mafia: The City of Lost Heaven (on [Mafia Connected](https://mafiaconnected.com/))
|
||||
* **(Coming Soon!)** GTA V (on [RAGEMP](https://rage.mp/))
|
||||
* **(Coming Soon!)** Mafia Definitive Edition (on MafiaMP)
|
||||
|
||||
### Features
|
||||
*Some features may be disabled on specific multiplayer mods depending on functionality*
|
||||
* Works on multiple server instances sharing the same database
|
||||
* Jobs operate as factions but leader can make ranks "public" so anybody can use those if enabled.
|
||||
* Clans with custom ranks, permissions, pay, titles, and more
|
||||
* Custom inventory system where everything is an item: food, weapons, devices, etc
|
||||
* All items can be dropped, given, used, picked up, or stored in certain places (other items, vehicles, etc)
|
||||
* Ownable vehicles, houses, businesses, and more
|
||||
* No "hard cap" to how many things you can own, but the more you own the more you pay in tax
|
||||
* Stock your business with any items you want, and set custom prices
|
||||
* Extra storage for businesses (floor items for sale, stockroom in back for hidden stuff)
|
||||
* Security features like two-factor login, email alerts for login attempts, and more
|
||||
* Animations and ped speech for extra RP goodness
|
||||
* Players can make aliases for commands
|
||||
* Choosable levels of GUI: Simple (input, list, message like SA-MP), Full (whole app layouts), or None (commands only)
|
||||
* Custom keybinds. Server can set defaults, but players can bind/unbind keys for personalization
|
||||
* *Everything* is dynamically changable in the server using commands and/or GUI
|
||||
* Community-provided translations for GUI and server messages
|
||||
* Automatic translator for chat (players can turn it on/off for themselves)
|
||||
* Way too many other things to list here
|
||||
|
||||
## Setup
|
||||
* Download the server from the [downloads page](https://gtaconnected.com/downloads) of the GTA Connected website.
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
[
|
||||
"English",
|
||||
"French",
|
||||
"Russian",
|
||||
"Scottish",
|
||||
"Irish",
|
||||
"Spanish",
|
||||
"Southern American",
|
||||
"Italian",
|
||||
"Australian",
|
||||
"Jamaican",
|
||||
"Israeli",
|
||||
"Dutch",
|
||||
"Brazilian",
|
||||
"Portuguese",
|
||||
"German",
|
||||
"Canadian",
|
||||
"Chinese",
|
||||
"Japanese",
|
||||
"Turkish",
|
||||
"Korean",
|
||||
"Estonian",
|
||||
"Sicilian",
|
||||
"Indian",
|
||||
"Rough",
|
||||
"Swedish"
|
||||
[
|
||||
"English",
|
||||
"French",
|
||||
"Russian",
|
||||
"Scottish",
|
||||
"Irish",
|
||||
"Spanish",
|
||||
"Southern American",
|
||||
"Italian",
|
||||
"Australian",
|
||||
"Jamaican",
|
||||
"Israeli",
|
||||
"Dutch",
|
||||
"Brazilian",
|
||||
"Portuguese",
|
||||
"German",
|
||||
"Canadian",
|
||||
"Chinese",
|
||||
"Japanese",
|
||||
"Turkish",
|
||||
"Korean",
|
||||
"Estonian",
|
||||
"Sicilian",
|
||||
"Indian",
|
||||
"Rough",
|
||||
"Swedish"
|
||||
]
|
||||
@@ -1,145 +1,145 @@
|
||||
[
|
||||
{
|
||||
"id": 0,
|
||||
"englishName": "English",
|
||||
"stringsFile": "english.json",
|
||||
"isoCode": "en",
|
||||
"flagImageFile": "uk.png",
|
||||
"countries": ["gb", "us", "au", "bz", "ca", "ie", "jm", "nz", "za", "tt"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "Vortrex",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"englishName": "Russian",
|
||||
"stringsFile": "russian.json",
|
||||
"isoCode": "ru",
|
||||
"flagImageFile": "ru.png",
|
||||
"countries": ["ru", "ua"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "VNDTTS",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"englishName": "Polish",
|
||||
"stringsFile": "polish.json",
|
||||
"isoCode": "pl",
|
||||
"flagImageFile": "pl.png",
|
||||
"countries": ["pl"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "Suprise444",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"englishName": "Spanish",
|
||||
"stringsFile": "spanish.json",
|
||||
"isoCode": "es",
|
||||
"flagImageFile": "es.png",
|
||||
"countries": ["es", "ar", "bo", "cl", "co", "cr", "do", "ec", "sv", "gt", "hn", "mx", "ni", "pa", "py", "pe", "pr", "uy", "ve"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "PerikiyoXD",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"englishName": "Chinese",
|
||||
"stringsFile": "chinese.json",
|
||||
"isoCode": "zh",
|
||||
"flagImageFile": "cn.png",
|
||||
"countries": ["cn", "hk", "sg", "tw"],
|
||||
"requiresUnicode": true,
|
||||
"contributor": "Renzuko_Ctone",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"englishName": "Arabic",
|
||||
"stringsFile": "arabic.json",
|
||||
"isoCode": "ar",
|
||||
"flagImageFile": "sa.png",
|
||||
"countries": ["dz", "bh", "eg", "iq", "jo", "kw", "lb", "ly", "ma", "om", "qa", "sa", "sy", "tn", "ae", "ye"],
|
||||
"requiresUnicode": true,
|
||||
"contributor": "! KASIR",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"englishName": "Slovak",
|
||||
"stringsFile": "slovak.json",
|
||||
"isoCode": "sk",
|
||||
"flagImageFile": "sk.png",
|
||||
"countries": ["sk"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "UAKLAUS",
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"englishName": "German",
|
||||
"stringsFile": "german.json",
|
||||
"isoCode": "de",
|
||||
"flagImageFile": "de.png",
|
||||
"countries": ["de", "at", "be", "ch", "li", "lu"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "Sladernimo",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"englishName": "French",
|
||||
"stringsFile": "french.json",
|
||||
"isoCode": "fr",
|
||||
"flagImageFile": "fr.png",
|
||||
"countries": ["fr", "cd", "bj", "bf", "cd", "cg", "ga", "gn", "ml", "mc", "ne", "sn"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "Cocam",
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"englishName": "Japanese",
|
||||
"stringsFile": "japanese.json",
|
||||
"isoCode": "jp",
|
||||
"flagImageFile": "jp.png",
|
||||
"countries": ["jp"],
|
||||
"requiresUnicode": true,
|
||||
"contributor": "Cocam",
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"englishName": "Finnish",
|
||||
"stringsFile": "finnish.json",
|
||||
"isoCode": "fi",
|
||||
"flagImageFile": "fi.png",
|
||||
"countries": ["fi"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "SIMBA_MEOW",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"englishName": "Lithuanian",
|
||||
"stringsFile": "lithuanian.json",
|
||||
"isoCode": "lt",
|
||||
"flagImageFile": "lt.png",
|
||||
"countries": ["lt"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "dovis",
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"englishName": "Latvian",
|
||||
"stringsFile": "latvian.json",
|
||||
"isoCode": "lv",
|
||||
"flagImageFile": "lv.png",
|
||||
"countries": ["lv"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "YuOn",
|
||||
"enabled": false
|
||||
}
|
||||
[
|
||||
{
|
||||
"id": 0,
|
||||
"englishName": "English",
|
||||
"stringsFile": "english.json",
|
||||
"isoCode": "en",
|
||||
"flagImageFile": "uk.png",
|
||||
"countries": ["gb", "us", "au", "bz", "ca", "ie", "jm", "nz", "za", "tt"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "Vortrex",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"englishName": "Russian",
|
||||
"stringsFile": "russian.json",
|
||||
"isoCode": "ru",
|
||||
"flagImageFile": "ru.png",
|
||||
"countries": ["ru", "ua"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "VNDTTS",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"englishName": "Polish",
|
||||
"stringsFile": "polish.json",
|
||||
"isoCode": "pl",
|
||||
"flagImageFile": "pl.png",
|
||||
"countries": ["pl"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "Suprise444",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"englishName": "Spanish",
|
||||
"stringsFile": "spanish.json",
|
||||
"isoCode": "es",
|
||||
"flagImageFile": "es.png",
|
||||
"countries": ["es", "ar", "bo", "cl", "co", "cr", "do", "ec", "sv", "gt", "hn", "mx", "ni", "pa", "py", "pe", "pr", "uy", "ve"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "PerikiyoXD",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"englishName": "Chinese",
|
||||
"stringsFile": "chinese.json",
|
||||
"isoCode": "zh",
|
||||
"flagImageFile": "cn.png",
|
||||
"countries": ["cn", "hk", "sg", "tw"],
|
||||
"requiresUnicode": true,
|
||||
"contributor": "Renzuko_Ctone",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"englishName": "Arabic",
|
||||
"stringsFile": "arabic.json",
|
||||
"isoCode": "ar",
|
||||
"flagImageFile": "sa.png",
|
||||
"countries": ["dz", "bh", "eg", "iq", "jo", "kw", "lb", "ly", "ma", "om", "qa", "sa", "sy", "tn", "ae", "ye"],
|
||||
"requiresUnicode": true,
|
||||
"contributor": "! KASIR",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"englishName": "Slovak",
|
||||
"stringsFile": "slovak.json",
|
||||
"isoCode": "sk",
|
||||
"flagImageFile": "sk.png",
|
||||
"countries": ["sk"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "UAKLAUS",
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"englishName": "German",
|
||||
"stringsFile": "german.json",
|
||||
"isoCode": "de",
|
||||
"flagImageFile": "de.png",
|
||||
"countries": ["de", "at", "be", "ch", "li", "lu"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "Sladernimo",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"englishName": "French",
|
||||
"stringsFile": "french.json",
|
||||
"isoCode": "fr",
|
||||
"flagImageFile": "fr.png",
|
||||
"countries": ["fr", "cd", "bj", "bf", "cd", "cg", "ga", "gn", "ml", "mc", "ne", "sn"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "Cocam",
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"englishName": "Japanese",
|
||||
"stringsFile": "japanese.json",
|
||||
"isoCode": "jp",
|
||||
"flagImageFile": "jp.png",
|
||||
"countries": ["jp"],
|
||||
"requiresUnicode": true,
|
||||
"contributor": "Cocam",
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"englishName": "Finnish",
|
||||
"stringsFile": "finnish.json",
|
||||
"isoCode": "fi",
|
||||
"flagImageFile": "fi.png",
|
||||
"countries": ["fi"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "SIMBA_MEOW",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"englishName": "Lithuanian",
|
||||
"stringsFile": "lithuanian.json",
|
||||
"isoCode": "lt",
|
||||
"flagImageFile": "lt.png",
|
||||
"countries": ["lt"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "dovis",
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"englishName": "Latvian",
|
||||
"stringsFile": "latvian.json",
|
||||
"isoCode": "lv",
|
||||
"flagImageFile": "lv.png",
|
||||
"countries": ["lv"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "YuOn",
|
||||
"enabled": false
|
||||
}
|
||||
]
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"host": "",
|
||||
"user": "",
|
||||
"pass": "",
|
||||
"name": "",
|
||||
"port": 3306,
|
||||
"usePersistentConnection": false
|
||||
{
|
||||
"host": "",
|
||||
"user": "",
|
||||
"pass": "",
|
||||
"name": "",
|
||||
"port": 3306,
|
||||
"usePersistentConnection": false
|
||||
}
|
||||
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"sendChat": false,
|
||||
"sendEvents": false,
|
||||
"sendConnectEvents": false,
|
||||
"sendVehicleEvents": false,
|
||||
"sendDeathEvents": false,
|
||||
"sendAdmin": false,
|
||||
"sendClan": false,
|
||||
"sendAction": false,
|
||||
"webhook": {
|
||||
"enabled": false,
|
||||
"webhookBaseURL": "",
|
||||
"pass": ""
|
||||
}
|
||||
{
|
||||
"sendChat": false,
|
||||
"sendEvents": false,
|
||||
"sendConnectEvents": false,
|
||||
"sendVehicleEvents": false,
|
||||
"sendDeathEvents": false,
|
||||
"sendAdmin": false,
|
||||
"sendClan": false,
|
||||
"sendAction": false,
|
||||
"webhook": {
|
||||
"enabled": false,
|
||||
"webhookBaseURL": "",
|
||||
"pass": ""
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
{
|
||||
"passiveIncomePerPayDay": 2000,
|
||||
"applyTax": true,
|
||||
"applyUpkeep": true,
|
||||
"grossIncomeMultiplier": 1.0,
|
||||
"incomeTaxRate": 0.7,
|
||||
"currencyString": "${AMOUNT}",
|
||||
"upKeepCosts": {
|
||||
"upKeepPerVehicle": 250,
|
||||
"upKeepPerHouse": 350,
|
||||
"upKeepPerBusiness": 600
|
||||
}
|
||||
}
|
||||
@@ -1,27 +1,27 @@
|
||||
{
|
||||
"enabled": false,
|
||||
"method": "http",
|
||||
"smtp": {
|
||||
"host": "",
|
||||
"port": 0,
|
||||
"username": "",
|
||||
"password": "",
|
||||
"from": "",
|
||||
"fromName": "",
|
||||
"useTLS": true
|
||||
},
|
||||
"http": {
|
||||
"password": "",
|
||||
"baseURL": ""
|
||||
},
|
||||
"bodyContent": {
|
||||
"confirmEmail": "Welcome to {SERVERNAME}!\nPlease confirm your email by using the command /verifyemail in-game.\n\nYour verification code is: {VERIFICATIONCODE}",
|
||||
"emailConfirmed": "Your email has been confirmed on {SERVERNAME}!\nYou may now use this email to reset your password, require two-factor authentication on login, receive offline notifications, and more!",
|
||||
"twoFactorAuthentication": "Please enter the following code to login on {SERVERNAME} for {GAMENAME}: {2FACODE}",
|
||||
"accountAuthSuccessAlert": "You or someone else has successfully logged in to your account on {SERVERNAME} for {GAMENAME}.\nIP Address: {IPADDRESS}\nLocation: {LOCATION}\nTimestamp: {TIMESTAMP}",
|
||||
"accountAuthFailAlert": "You or someone else has failed to login to your account on {SERVERNAME} for {GAMENAME}.\nIP Address: {IPADDRESS}\nLocation: {LOCATION}\nTimestamp: {TIMESTAMP}",
|
||||
"offlineMessageAlert": "You have received a private message on {SERVERNAME} for {GAMENAME}. \nYou are receiving this notification because you enabled email message notifications when you're not connected to the server.\nFrom: {FROMNAME}\nTimestamp: {TIMESTAMP}\nMessage: {MESSAGE}",
|
||||
"confirmPasswordReset": "You (or someone else) requested to reset your password on {SERVERNAME}!\nPlease confirm this request by entering the code below into the password reset window in-game.\n\nYour verification code is: {VERIFICATIONCODE}\n\n\nIf you did not request a password reset, then there's nothing to worry about since your password can only be reset with the code above.",
|
||||
"passwordChanged": "Your password on {SERVERNAME} has been changed successfully!"
|
||||
}
|
||||
{
|
||||
"enabled": false,
|
||||
"method": "http",
|
||||
"smtp": {
|
||||
"host": "",
|
||||
"port": 0,
|
||||
"username": "",
|
||||
"password": "",
|
||||
"from": "",
|
||||
"fromName": "",
|
||||
"useTLS": true
|
||||
},
|
||||
"http": {
|
||||
"password": "",
|
||||
"baseURL": ""
|
||||
},
|
||||
"bodyContent": {
|
||||
"confirmEmail": "Welcome to {SERVERNAME}!\nPlease confirm your email by using the command /verifyemail in-game.\n\nYour verification code is: {VERIFICATIONCODE}",
|
||||
"emailConfirmed": "Your email has been confirmed on {SERVERNAME}!\nYou may now use this email to reset your password, require two-factor authentication on login, receive offline notifications, and more!",
|
||||
"twoFactorAuthentication": "Please enter the following code to login on {SERVERNAME} for {GAMENAME}: {2FACODE}",
|
||||
"accountAuthSuccessAlert": "You or someone else has successfully logged in to your account on {SERVERNAME} for {GAMENAME}.\nIP Address: {IPADDRESS}\nLocation: {LOCATION}\nTimestamp: {TIMESTAMP}",
|
||||
"accountAuthFailAlert": "You or someone else has failed to login to your account on {SERVERNAME} for {GAMENAME}.\nIP Address: {IPADDRESS}\nLocation: {LOCATION}\nTimestamp: {TIMESTAMP}",
|
||||
"offlineMessageAlert": "You have received a private message on {SERVERNAME} for {GAMENAME}. \nYou are receiving this notification because you enabled email message notifications when you're not connected to the server.\nFrom: {FROMNAME}\nTimestamp: {TIMESTAMP}\nMessage: {MESSAGE}",
|
||||
"confirmPasswordReset": "You (or someone else) requested to reset your password on {SERVERNAME}!\nPlease confirm this request by entering the code below into the password reset window in-game.\n\nYour verification code is: {VERIFICATIONCODE}\n\n\nIf you did not request a password reset, then there's nothing to worry about since your password can only be reset with the code above.",
|
||||
"passwordChanged": "Your password on {SERVERNAME} has been changed successfully!"
|
||||
}
|
||||
}
|
||||
@@ -1,109 +1,114 @@
|
||||
{
|
||||
"config": {
|
||||
"shortHoldDuration": 500,
|
||||
"longHoldDuration": 1500,
|
||||
"coolDownBetweenUse": 500
|
||||
},
|
||||
"defaultKeyBinds": [
|
||||
{
|
||||
"keyName": "k",
|
||||
"commandString": "engine",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "l",
|
||||
"commandString": "lights",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "j",
|
||||
"commandString": "lock",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "f",
|
||||
"commandString": "enter",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "g",
|
||||
"commandString": "passenger",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "m",
|
||||
"commandString": "cursor",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "o",
|
||||
"commandString": "drop",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "p",
|
||||
"commandString": "pickup",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "u",
|
||||
"commandString": "use",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "i",
|
||||
"commandString": "inv",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "0",
|
||||
"commandString": "item 0",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "1",
|
||||
"commandString": "item 1",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "2",
|
||||
"commandString": "item 2",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "3",
|
||||
"commandString": "item 3",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "4",
|
||||
"commandString": "item 4",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "5",
|
||||
"commandString": "item 5",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "6",
|
||||
"commandString": "item 6",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "7",
|
||||
"commandString": "item 7",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "8",
|
||||
"commandString": "item 8",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "9",
|
||||
"commandString": "item 9",
|
||||
"keyState": 1
|
||||
}
|
||||
]
|
||||
{
|
||||
"config": {
|
||||
"shortHoldDuration": 500,
|
||||
"longHoldDuration": 1500,
|
||||
"coolDownBetweenUse": 500
|
||||
},
|
||||
"defaultKeyBinds": [
|
||||
{
|
||||
"keyName": "k",
|
||||
"commandString": "engine",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "l",
|
||||
"commandString": "lights",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "j",
|
||||
"commandString": "lock",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "f",
|
||||
"commandString": "enter",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "g",
|
||||
"commandString": "passenger",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "m",
|
||||
"commandString": "cursor",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "o",
|
||||
"commandString": "drop",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "p",
|
||||
"commandString": "pickup",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "u",
|
||||
"commandString": "use",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "i",
|
||||
"commandString": "inv",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "0",
|
||||
"commandString": "item 0",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "1",
|
||||
"commandString": "item 1",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "2",
|
||||
"commandString": "item 2",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "3",
|
||||
"commandString": "item 3",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "4",
|
||||
"commandString": "item 4",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "5",
|
||||
"commandString": "item 5",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "6",
|
||||
"commandString": "item 6",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "7",
|
||||
"commandString": "item 7",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "8",
|
||||
"commandString": "item 8",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "9",
|
||||
"commandString": "item 9",
|
||||
"keyState": 1
|
||||
},
|
||||
{
|
||||
"keyName": "f5",
|
||||
"commandString": "scoreboard",
|
||||
"keyState": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,150 +1,150 @@
|
||||
{
|
||||
"apiEmail": "example@example.com",
|
||||
"defaultLanguageId": 0,
|
||||
"translateURL": "http://api.mymemory.translated.net/get?de={3}&q={0}&langpair={1}|{2}",
|
||||
"locales": [
|
||||
{
|
||||
"id": 0,
|
||||
"englishName": "English",
|
||||
"stringsFile": "english.json",
|
||||
"isoCode": "en",
|
||||
"flagImageFile": "uk.png",
|
||||
"countries": ["gb", "us", "au", "bz", "ca", "ie", "jm", "nz", "za", "tt"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "Vortrex",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"englishName": "Russian",
|
||||
"stringsFile": "russian.json",
|
||||
"isoCode": "ru",
|
||||
"flagImageFile": "ru.png",
|
||||
"countries": ["ru", "ua"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "VNDTTS",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"englishName": "Polish",
|
||||
"stringsFile": "polish.json",
|
||||
"isoCode": "pl",
|
||||
"flagImageFile": "pl.png",
|
||||
"countries": ["pl"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "Suprise444",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"englishName": "Spanish",
|
||||
"stringsFile": "spanish.json",
|
||||
"isoCode": "es",
|
||||
"flagImageFile": "es.png",
|
||||
"countries": ["es", "ar", "bo", "cl", "co", "cr", "do", "ec", "sv", "gt", "hn", "mx", "ni", "pa", "py", "pe", "pr", "uy", "ve"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "PerikiyoXD",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"englishName": "Chinese",
|
||||
"stringsFile": "chinese.json",
|
||||
"isoCode": "zh",
|
||||
"flagImageFile": "cn.png",
|
||||
"countries": ["cn", "hk", "sg", "tw"],
|
||||
"requiresUnicode": true,
|
||||
"contributor": "Renzuko_Ctone",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"englishName": "Arabic",
|
||||
"stringsFile": "arabic.json",
|
||||
"isoCode": "ar",
|
||||
"flagImageFile": "sa.png",
|
||||
"countries": ["dz", "bh", "eg", "iq", "jo", "kw", "lb", "ly", "ma", "om", "qa", "sa", "sy", "tn", "ae", "ye"],
|
||||
"requiresUnicode": true,
|
||||
"contributor": "! KASIR",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"englishName": "Slovak",
|
||||
"stringsFile": "slovak.json",
|
||||
"isoCode": "sk",
|
||||
"flagImageFile": "sk.png",
|
||||
"countries": ["sk"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "UAKLAUS",
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"englishName": "German",
|
||||
"stringsFile": "german.json",
|
||||
"isoCode": "de",
|
||||
"flagImageFile": "de.png",
|
||||
"countries": ["de", "at", "be", "ch", "li", "lu"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "Sladernimo",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"englishName": "French",
|
||||
"stringsFile": "french.json",
|
||||
"isoCode": "fr",
|
||||
"flagImageFile": "fr.png",
|
||||
"countries": ["fr", "cd", "bj", "bf", "cd", "cg", "ga", "gn", "ml", "mc", "ne", "sn"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "Cocam",
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"englishName": "Japanese",
|
||||
"stringsFile": "japanese.json",
|
||||
"isoCode": "jp",
|
||||
"flagImageFile": "jp.png",
|
||||
"countries": ["jp"],
|
||||
"requiresUnicode": true,
|
||||
"contributor": "Cocam",
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"englishName": "Finnish",
|
||||
"stringsFile": "finnish.json",
|
||||
"isoCode": "fi",
|
||||
"flagImageFile": "fi.png",
|
||||
"countries": ["fi"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "SIMBA_MEOW",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"englishName": "Lithuanian",
|
||||
"stringsFile": "lithuanian.json",
|
||||
"isoCode": "lt",
|
||||
"flagImageFile": "lt.png",
|
||||
"countries": ["lt"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "dovis",
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"englishName": "Latvian",
|
||||
"stringsFile": "latvian.json",
|
||||
"isoCode": "lv",
|
||||
"flagImageFile": "lv.png",
|
||||
"countries": ["lv"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "YuOn",
|
||||
"enabled": false
|
||||
}
|
||||
]
|
||||
{
|
||||
"apiEmail": "example@example.com",
|
||||
"defaultLanguageId": 0,
|
||||
"translateURL": "http://api.mymemory.translated.net/get?de={3}&q={0}&langpair={1}|{2}",
|
||||
"locales": [
|
||||
{
|
||||
"id": 0,
|
||||
"englishName": "English",
|
||||
"stringsFile": "english.json",
|
||||
"isoCode": "en",
|
||||
"flagImageFile": "uk.png",
|
||||
"countries": ["gb", "us", "au", "bz", "ca", "ie", "jm", "nz", "za", "tt"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "Vortrex",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"englishName": "Russian",
|
||||
"stringsFile": "russian.json",
|
||||
"isoCode": "ru",
|
||||
"flagImageFile": "ru.png",
|
||||
"countries": ["ru", "ua"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "VNDTTS",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"englishName": "Polish",
|
||||
"stringsFile": "polish.json",
|
||||
"isoCode": "pl",
|
||||
"flagImageFile": "pl.png",
|
||||
"countries": ["pl"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "Suprise444",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"englishName": "Spanish",
|
||||
"stringsFile": "spanish.json",
|
||||
"isoCode": "es",
|
||||
"flagImageFile": "es.png",
|
||||
"countries": ["es", "ar", "bo", "cl", "co", "cr", "do", "ec", "sv", "gt", "hn", "mx", "ni", "pa", "py", "pe", "pr", "uy", "ve"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "PerikiyoXD",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"englishName": "Chinese",
|
||||
"stringsFile": "chinese.json",
|
||||
"isoCode": "zh",
|
||||
"flagImageFile": "cn.png",
|
||||
"countries": ["cn", "hk", "sg", "tw"],
|
||||
"requiresUnicode": true,
|
||||
"contributor": "Renzuko_Ctone",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"englishName": "Arabic",
|
||||
"stringsFile": "arabic.json",
|
||||
"isoCode": "ar",
|
||||
"flagImageFile": "sa.png",
|
||||
"countries": ["dz", "bh", "eg", "iq", "jo", "kw", "lb", "ly", "ma", "om", "qa", "sa", "sy", "tn", "ae", "ye"],
|
||||
"requiresUnicode": true,
|
||||
"contributor": "! KASIR",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"englishName": "Slovak",
|
||||
"stringsFile": "slovak.json",
|
||||
"isoCode": "sk",
|
||||
"flagImageFile": "sk.png",
|
||||
"countries": ["sk"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "UAKLAUS",
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"englishName": "German",
|
||||
"stringsFile": "german.json",
|
||||
"isoCode": "de",
|
||||
"flagImageFile": "de.png",
|
||||
"countries": ["de", "at", "be", "ch", "li", "lu"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "Sladernimo",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"englishName": "French",
|
||||
"stringsFile": "french.json",
|
||||
"isoCode": "fr",
|
||||
"flagImageFile": "fr.png",
|
||||
"countries": ["fr", "cd", "bj", "bf", "cd", "cg", "ga", "gn", "ml", "mc", "ne", "sn"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "Cocam",
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"englishName": "Japanese",
|
||||
"stringsFile": "japanese.json",
|
||||
"isoCode": "jp",
|
||||
"flagImageFile": "jp.png",
|
||||
"countries": ["jp"],
|
||||
"requiresUnicode": true,
|
||||
"contributor": "Cocam",
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"englishName": "Finnish",
|
||||
"stringsFile": "finnish.json",
|
||||
"isoCode": "fi",
|
||||
"flagImageFile": "fi.png",
|
||||
"countries": ["fi"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "SIMBA_MEOW",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"englishName": "Lithuanian",
|
||||
"stringsFile": "lithuanian.json",
|
||||
"isoCode": "lt",
|
||||
"flagImageFile": "lt.png",
|
||||
"countries": ["lt"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "dovis",
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"englishName": "Latvian",
|
||||
"stringsFile": "latvian.json",
|
||||
"isoCode": "lv",
|
||||
"flagImageFile": "lv.png",
|
||||
"countries": ["lv"],
|
||||
"requiresUnicode": false,
|
||||
"contributor": "YuOn",
|
||||
"enabled": false
|
||||
}
|
||||
]
|
||||
}
|
||||
8
config/security.json
Normal file
8
config/security.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"accountSaltHash": [
|
||||
"LGj6w8SRwJEJ95XH"
|
||||
],
|
||||
"accountPasswordSaltAlgorithm": [
|
||||
"v.roleplay.{SALTHASH}.{NAME}.{PASSWORD}"
|
||||
]
|
||||
}
|
||||
16
database.sql
16
database.sql
@@ -66,6 +66,22 @@ CREATE TABLE IF NOT EXISTS `acct_contact` (
|
||||
|
||||
-- Dumping data for table v-roleplay.acct_contact: ~0 rows (approximately)
|
||||
|
||||
-- Dumping structure for table v-roleplay.acct_cmd
|
||||
CREATE TABLE `acct_cmd` (
|
||||
`acct_cmd_id` int(11) NOT NULL,
|
||||
`acct_cmd_acct` int(11) NOT NULL DEFAULT '1',
|
||||
`acct_cmd_for_cmd` varchar(128) NOT NULL DEFAULT '',
|
||||
`acct_cmd_alias_cmd` varchar(128) NOT NULL DEFAULT '',
|
||||
`acct_cmd_deleted` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`acct_cmd_enabled` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`acct_cmd_when_added` bigint(32) NOT NULL DEFAULT '0'
|
||||
PRIMARY KEY (`acct_cmd_id`),
|
||||
KEY `acct_cmd_acct` (`acct_cmd_acct`),
|
||||
CONSTRAINT `fk_acct_cmd_acct` FOREIGN KEY (`acct_cmd_acct`) REFERENCES `acct_main` (`acct_id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='Account - Command Aliases';
|
||||
|
||||
-- Dumping data for table v-roleplay.acct_cmd: ~0 rows (approximately)
|
||||
|
||||
-- Dumping structure for table v-roleplay.acct_hotkey
|
||||
CREATE TABLE IF NOT EXISTS `acct_hotkey` (
|
||||
`acct_hotkey_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
|
||||
BIN
files/images/icons/business-icon.png
Normal file
BIN
files/images/icons/business-icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.6 KiB |
BIN
files/images/icons/house-icon.png
Normal file
BIN
files/images/icons/house-icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.6 KiB |
BIN
files/images/icons/job-icon.png
Normal file
BIN
files/images/icons/job-icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.6 KiB |
BIN
files/images/icons/objective-icon.png
Normal file
BIN
files/images/icons/objective-icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 41 KiB |
BIN
files/sounds/payphone/old-payphone-dial.mp3
Normal file
BIN
files/sounds/payphone/old-payphone-dial.mp3
Normal file
Binary file not shown.
BIN
files/sounds/payphone/old-payphone-hangup.mp3
Normal file
BIN
files/sounds/payphone/old-payphone-hangup.mp3
Normal file
Binary file not shown.
BIN
files/sounds/payphone/old-payphone-pickup.mp3
Normal file
BIN
files/sounds/payphone/old-payphone-pickup.mp3
Normal file
Binary file not shown.
BIN
files/sounds/payphone/old-payphone-ring.mp3
Normal file
BIN
files/sounds/payphone/old-payphone-ring.mp3
Normal file
Binary file not shown.
41
info/ECONOMY.md
Normal file
41
info/ECONOMY.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# Economy Information
|
||||
|
||||
### Basic Information
|
||||
Each server has it's own independent economy with simulated inflation and is designed to slowly self-repair over time, assuming nothing is affecting it too heavily.
|
||||
|
||||
---
|
||||
|
||||
### Asset Ownership
|
||||
Any player or clan is allowed to own as many businesses, vehicles, and houses as they want. However, it should be noted that the more you own, the more upkeep (via taxes, insurance, etc) is required. Failure to maintain this upkeep for too long will automatically force you to lose the unmaintained assets. Vehicle owners can park their car anywhere (subject to IC parking laws), store items in the trunk or dash compartment, give anybody access, and set the price if they want to make it available to buy, and more. Business owners can stock their store with any item they want, set what prices they want for any item for sale, close/open the business, keep a stock of items in the business's storage, force people to pay a fee to enter, and more. House owners can store items in their house, purchase a safe, decorate with furniture, give anybody access, and more.
|
||||
|
||||
---
|
||||
|
||||
### Ordering Items for a Business
|
||||
Ordering items is simple: just use the /bizorder command.
|
||||
You'll need to specify which item you want to order and how many.
|
||||
Remember, the prices will vary depending on certain circumstances.
|
||||
|
||||
The formula is as follows:
|
||||
> Base price * server inflation * demand * risk * amount
|
||||
|
||||
**Here's a breakdown on how the above formula works:**
|
||||
* First, each item has a base price. This value will never change.
|
||||
|
||||
* Next, the base price is multiplied by the server's current inflation value. When the servers were first opened, the inflation value is 100%, which means no inflation. Everything cost 100% of it's calculated price. However, the inflation will slowly increase over time, simulating realistic economy inflation.
|
||||
|
||||
* Next, the inflated price is then multiplied by the demand factor, which is determined by how much demand there is for the item you want. Every 10 of the item ordered increases the demand value by 10%, and this will slowly go back down over time. If another business just ordered 100 of the item you want, the demand has forced the item's order price to increase by 100%, which means it's now double the original price. This simulates the things involved with increased demand, such as the extra manufacturing and shipping needed to get this item imported to your business.
|
||||
|
||||
* Next, the cost is multiplied by a risk value. This value never changes, and varies depending on the item. For illegal items, the risk value will be lower for less-risky items and higher as they get worse. For example, a shotgun versus an AK-47 have different risk levels, as an AK-47 is a far deadlier and a harder to get weapon, and is more difficult to conceal through customs. This simulates the "risk" of ordering items like these. For legal items, there is no risk so the risk price won't increase for those.
|
||||
|
||||
* Finally, the order cost is multiplied by the amount you want to order.
|
||||
|
||||
|
||||
**An example of this formula in action is below ... shown for an order for 10 AK-47's with no inflation**
|
||||
*The demand is increased by 10% since you're ordering 10 of them. 1 = 100% of the normal cost, 1.1 = 110%, and so on.*
|
||||
> Base price $1000
|
||||
> x inflation 1 = $1000
|
||||
> x demand 1.1 = $1100
|
||||
> x risk 5 = $5500
|
||||
> x amount 10 = $55000
|
||||
|
||||
So as you can see, the total cost to order 10 AK-47's in this scenario is $55,000. Remember, an AK-47 is a deadly and uncommon weapon (and highly illegal!) so it's a very risky and costly thing to do business with.
|
||||
@@ -17,12 +17,9 @@
|
||||
"AnimationStopCommandTip": "استخدم {1} لإيقاف الرسوم المتحركة",
|
||||
"CantBanClient": "لا يمكنك حظر هذا الإعب",
|
||||
"PlayerAccountBanned": "تم حظر حساب {1}",
|
||||
"ClanNotFound": "لم يتم العثور على المجموعة",
|
||||
"ClanNameTaken": "توجد مجموعة بهذا الاسم بالفعل",
|
||||
"PlayerNotFound": "الاعب غير موجود",
|
||||
"ClanCantRemoveRanks": "لا يمكنك إزالة رتب المجموعة",
|
||||
"ClanCantAddRanks": "لأ يمكنك إضافة رتب",
|
||||
"ClanRankNotFound": "رتبة غير موجودهـ",
|
||||
"ClanCantChangeMemberTag": "ليس لديك الصلاحيات لتعديل على علامات رتب الاعضاء",
|
||||
"ClanPlayerNotInSameClan": "الاعب غير موجود بمجموعتك",
|
||||
"ClanCantChangeRankLevel": "ليس لديك صلاحيات لتغيير مستوى رتبة المجموعة",
|
||||
@@ -655,28 +652,6 @@
|
||||
"LeftWrist": "معصم اليد اليسرى",
|
||||
"RightWrist": "معصم اليد اليمنى"
|
||||
},
|
||||
"ActionTips": {
|
||||
"VehicleEngineOffWhenEnteringKey": "استخدم {1} لتشغيل أو إيقاف تشغيل محرك السيارة",
|
||||
"VehicleLockedAfterEntryAttempt": "استخدم {1} لقفل أو إلغاء تأمين مركبة",
|
||||
"ShowItemsAfterPurchase": "استخدم {1} لمشاهدة مخزونك",
|
||||
"BuyCommandAfterEnterBusiness": "استخدم {1} لشراء عناصر من شركة",
|
||||
"UseItemKeyAfterEquipping": "استخدم {1} لاستخدام العنصر المجهز الخاص بك",
|
||||
"UseItemKeyAfterEquippingWalkieTalkie": "استخدم {1} لتشغيل الراديو أو إيقاف تشغيله",
|
||||
"RadioCommandAfterEnablingWalkieTalkie": "استخدم {1} للتحدث في الراديو الخاص بك",
|
||||
"ReplyToDirectMessage": "استخدم {1} للرد بسهولة على رسالة خاصة",
|
||||
"UseItemKeyAmmoAfterEquippingWeapon": "استخدم {1} لتحميل ذخيرة في سلاحك المجهز",
|
||||
"AnimationStop": "استخدم {1} لإيقاف الرسم المتحرك",
|
||||
"JobEquipmentInventory": "معدات العمل موجودة في مخزونك. استخدم {1} لمشاهدتها.",
|
||||
"ViewInventory": "استخدم {1} لمشاهدة عناصرك",
|
||||
"VehicleRepairItemUsage": "قف بجانب سيارة واستخدم {1} لإصلاحها",
|
||||
"VehicleColourItemUsage": "قف بجوار سيارة واستخدم {1} لتغيير لونها",
|
||||
"VehiclePartItemUsage": "قف بجوار سيارة واستخدم {1} للترقية باستخدام {2}",
|
||||
"AmmoClipItemUsage": "جهز السلاح واستخدم {1} لتحميل الذخيرة فيه",
|
||||
"GenericItemUsage": "استخدم {1} لاستخدام {2}",
|
||||
"EnterJobVehicleForRoute": "أدخل سيارة عمل قريبة لبدء مسار عمل",
|
||||
"JobLocations": "قم بزيارة موقع العمل للحصول على وظيفة. استخدم {1} للعثور على موقع عمل",
|
||||
"JobRouteStart": "استخدم {1} لبدء مسار عمل بهذه السيارة"
|
||||
},
|
||||
"DisconnectReasons": {
|
||||
"Unknown": "غير معروف",
|
||||
"LostConnection": "انقطع الإتصال",
|
||||
@@ -752,5 +727,60 @@
|
||||
"Cancel": "Cancel",
|
||||
"AlreadyOwnVehicle": "You already own this vehicle!",
|
||||
"PropertyEntranceFeeLabel": "Entrance Fee: {1}",
|
||||
"NeedToBeInJobVehicle": "You need to be in a job vehicle!"
|
||||
}
|
||||
"NeedToBeInJobVehicle": "You need to be in a job vehicle!",
|
||||
"InvalidJobRank": "Job rank not found!",
|
||||
"PayPhoneRecipientAnswered": "Somebody answered the call. Use normal chat to talk to them.",
|
||||
"PayPhoneAnswered": "You answered the phone. Use normal chat to talk to the caller.",
|
||||
"PayPhoneRecipientHangup": "The line was disconnected. You have been charged {1}",
|
||||
"PayPhoneHangup": "You hung up the phone.",
|
||||
"AlreadyUsingPayPhone": "You are already using a payphone!",
|
||||
"NotUsingPayPhone": "You are not using a payphone!",
|
||||
"NoPayPhoneCloseEnough": "There is no payphone close enough!",
|
||||
"PayPhoneNotRinging": "This payphone is not ringing!",
|
||||
"PayPhoneOccupied": "This payphone is already being used by someone else!",
|
||||
"PayPhoneOccupantSwitched": "A different voice is now on the line",
|
||||
"PayPhoneGiven": "You gave the phone to {1}",
|
||||
"PayPhoneReceived": "{1} gave you the phone",
|
||||
"PayPhoneUnableToCallPlayer": "You can't call {1} at this time. Please try again later.",
|
||||
"ActionTips": {
|
||||
"VehicleEngineOffWhenEnteringKey": "استخدم {1} لتشغيل أو إيقاف تشغيل محرك السيارة",
|
||||
"VehicleLockedAfterEntryAttempt": "استخدم {1} لقفل أو إلغاء تأمين مركبة",
|
||||
"ShowItemsAfterPurchase": "استخدم {1} لمشاهدة مخزونك",
|
||||
"BuyCommandAfterEnterBusiness": "استخدم {1} لشراء عناصر من شركة",
|
||||
"UseItemKeyAfterEquipping": "استخدم {1} لاستخدام العنصر المجهز الخاص بك",
|
||||
"UseItemKeyAfterEquippingWalkieTalkie": "استخدم {1} لتشغيل الراديو أو إيقاف تشغيله",
|
||||
"RadioCommandAfterEnablingWalkieTalkie": "استخدم {1} للتحدث في الراديو الخاص بك",
|
||||
"ReplyToDirectMessage": "استخدم {1} للرد بسهولة على رسالة خاصة",
|
||||
"UseItemKeyAmmoAfterEquippingWeapon": "استخدم {1} لتحميل ذخيرة في سلاحك المجهز",
|
||||
"AnimationStop": "استخدم {1} لإيقاف الرسم المتحرك",
|
||||
"JobEquipmentInventory": "معدات العمل موجودة في مخزونك. استخدم {1} لمشاهدتها.",
|
||||
"ViewInventory": "استخدم {1} لمشاهدة عناصرك",
|
||||
"VehicleRepairItemUsage": "قف بجانب سيارة واستخدم {1} لإصلاحها",
|
||||
"VehicleColourItemUsage": "قف بجوار سيارة واستخدم {1} لتغيير لونها",
|
||||
"VehiclePartItemUsage": "قف بجوار سيارة واستخدم {1} للترقية باستخدام {2}",
|
||||
"AmmoClipItemUsage": "جهز السلاح واستخدم {1} لتحميل الذخيرة فيه",
|
||||
"GenericItemUsage": "استخدم {1} لاستخدام {2}",
|
||||
"EnterJobVehicleForRoute": "أدخل سيارة عمل قريبة لبدء مسار عمل",
|
||||
"JobLocations": "قم بزيارة موقع العمل للحصول على وظيفة. استخدم {1} للعثور على موقع عمل",
|
||||
"JobRouteStart": "استخدم {1} لبدء مسار عمل بهذه السيارة",
|
||||
"PayPhoneFirstUse": "Use {1} to end the call, and {2} to give the phone to somebody nearby"
|
||||
},
|
||||
"NoBusinessesWithinRange": "There are no businesses within {1} meters",
|
||||
"NoHousesWithinRange": "There are no houses within {1} meters",
|
||||
"NoPayPhonesWithinRange": "There are no payphones within {1} meters",
|
||||
"HeaderBusinessesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderHousesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderPayPhonesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderCommandsForStaffFlagList": "Admin Commands ({1})",
|
||||
"PlayerLocateDistanceAndDirection": "{1} is {2} meters {3}",
|
||||
"MustBeNumber": "You need to use a number!",
|
||||
"HeaderJobRoutesList": "Job Routes ({1})",
|
||||
"HeaderJobRouteInfo": "Job Route Information (${1})",
|
||||
"InvalidJobRoute": "Job route not found!",
|
||||
"PayPhoneDeleted": "The payphone was deleted",
|
||||
"PayPhoneAnswer": "Use {1} to answer the payphone",
|
||||
"ResetActionTipsConfirm": "Are you sure you want to reset all seen action tips?",
|
||||
"ActionTipsReset": "All seen action tips have been reset.",
|
||||
"NormalChatDisabled": "Normal chat is disabled by server admin. Use chat commands instead.",
|
||||
"GlobalChatDisabled": "Global out-of-character chat is disabled by server admin"
|
||||
}
|
||||
@@ -16,12 +16,9 @@
|
||||
"InvalidAnimationDistance": "The distance must be between 0 and 3",
|
||||
"CantBanClient": "You cannot ban this person",
|
||||
"PlayerAccountBanned": "{1} has been account banned",
|
||||
"ClanNotFound": "Clan not found",
|
||||
"ClanNameTaken": "A clan with that name already exists",
|
||||
"PlayerNotFound": "Player not found",
|
||||
"ClanCantRemoveRanks": "You can't remove clan ranks",
|
||||
"ClanCantAddRanks": "You can't add clan ranks",
|
||||
"ClanRankNotFound": "Clan rank not found",
|
||||
"ClanCantChangeMemberTag": "You can not change clan member's tags",
|
||||
"ClanPlayerNotInSameClan": "That player is not in your clan",
|
||||
"ClanCantChangeRankLevel": "You can not change clan rank's level",
|
||||
@@ -653,28 +650,6 @@
|
||||
"LeftWrist": "Left Wrist",
|
||||
"RightWrist": "Right Wrist"
|
||||
},
|
||||
"ActionTips": {
|
||||
"VehicleEngineOffWhenEnteringKey": "Use {1} to turn on or off a vehicle's engine",
|
||||
"VehicleLockedAfterEntryAttempt": "Use {1} to lock or unlock a vehicle",
|
||||
"ShowItemsAfterPurchase": "Use {1} to see your inventory",
|
||||
"BuyCommandAfterEnterBusiness": "Use {1} to buy items from a business",
|
||||
"UseItemKeyAfterEquipping": "Use {1} to use your equipped item",
|
||||
"UseItemKeyAfterEquippingWalkieTalkie": "Use {1} to turn on or off your radio",
|
||||
"RadioCommandAfterEnablingWalkieTalkie": "Use {1} to talk on your radio",
|
||||
"ReplyToDirectMessage": "Use {1} to easily reply to a private message",
|
||||
"UseItemKeyAmmoAfterEquippingWeapon": "Use {1} to load an ammo item into your equipped weapon",
|
||||
"AnimationStop": "Use {1} to stop your animation",
|
||||
"JobEquipmentInventory": "The job equipment is in your inventory. Use {1} to see them.",
|
||||
"ViewInventory": "Use {1} to see your items",
|
||||
"VehicleRepairItemUsage": "Stand next to a vehicle and use {1} to repair it",
|
||||
"VehicleColourItemUsage": "Stand next to a vehicle and use {1} to change it's colour",
|
||||
"VehiclePartItemUsage": "Stand next to a vehicle and use {1} to upgrade with {2}",
|
||||
"AmmoClipItemUsage": "Equip the weapon and use {1} to load ammo into it",
|
||||
"GenericItemUsage": "Use {1} to use the {2}",
|
||||
"EnterJobVehicleForRoute": "Enter a job vehicle nearby to start a job route",
|
||||
"JobLocations": "Visit a job location to get a job. Use {1} to find a job location",
|
||||
"JobRouteStart": "Use {1} to start a job route with this vehicle"
|
||||
},
|
||||
"DisconnectReasons": {
|
||||
"Unknown": "Unknown",
|
||||
"LostConnection": "Lost Connection",
|
||||
@@ -750,5 +725,60 @@
|
||||
"Cancel": "Cancel",
|
||||
"AlreadyOwnVehicle": "You already own this vehicle!",
|
||||
"PropertyEntranceFeeLabel": "Entrance Fee: {1}",
|
||||
"NeedToBeInJobVehicle": "You need to be in a job vehicle!"
|
||||
}
|
||||
"NeedToBeInJobVehicle": "You need to be in a job vehicle!",
|
||||
"InvalidJobRank": "Job rank not found!",
|
||||
"PayPhoneRecipientAnswered": "Somebody answered the call. Use normal chat to talk to them.",
|
||||
"PayPhoneAnswered": "You answered the phone. Use normal chat to talk to the caller.",
|
||||
"PayPhoneRecipientHangup": "The line was disconnected. You have been charged {1}",
|
||||
"PayPhoneHangup": "You hung up the phone.",
|
||||
"AlreadyUsingPayPhone": "You are already using a payphone!",
|
||||
"NotUsingPayPhone": "You are not using a payphone!",
|
||||
"NoPayPhoneCloseEnough": "There is no payphone close enough!",
|
||||
"PayPhoneNotRinging": "This payphone is not ringing!",
|
||||
"PayPhoneOccupied": "This payphone is already being used by someone else!",
|
||||
"PayPhoneOccupantSwitched": "A different voice is now on the line",
|
||||
"PayPhoneGiven": "You gave the phone to {1}",
|
||||
"PayPhoneReceived": "{1} gave you the phone",
|
||||
"PayPhoneUnableToCallPlayer": "You can't call {1} at this time. Please try again later.",
|
||||
"ActionTips": {
|
||||
"VehicleEngineOffWhenEnteringKey": "Use {1} to turn on or off a vehicle's engine",
|
||||
"VehicleLockedAfterEntryAttempt": "Use {1} to lock or unlock a vehicle",
|
||||
"ShowItemsAfterPurchase": "Use {1} to see your inventory",
|
||||
"BuyCommandAfterEnterBusiness": "Use {1} to buy items from a business",
|
||||
"UseItemKeyAfterEquipping": "Use {1} to use your equipped item",
|
||||
"UseItemKeyAfterEquippingWalkieTalkie": "Use {1} to turn on or off your radio",
|
||||
"RadioCommandAfterEnablingWalkieTalkie": "Use {1} to talk on your radio",
|
||||
"ReplyToDirectMessage": "Use {1} to easily reply to a private message",
|
||||
"UseItemKeyAmmoAfterEquippingWeapon": "Use {1} to load an ammo item into your equipped weapon",
|
||||
"AnimationStop": "Use {1} to stop your animation",
|
||||
"JobEquipmentInventory": "The job equipment is in your inventory. Use {1} to see them.",
|
||||
"ViewInventory": "Use {1} to see your items",
|
||||
"VehicleRepairItemUsage": "Stand next to a vehicle and use {1} to repair it",
|
||||
"VehicleColourItemUsage": "Stand next to a vehicle and use {1} to change it's colour",
|
||||
"VehiclePartItemUsage": "Stand next to a vehicle and use {1} to upgrade with {2}",
|
||||
"AmmoClipItemUsage": "Equip the weapon and use {1} to load ammo into it",
|
||||
"GenericItemUsage": "Use {1} to use the {2}",
|
||||
"EnterJobVehicleForRoute": "Enter a job vehicle nearby to start a job route",
|
||||
"JobLocations": "Visit a job location to get a job. Use {1} to find a job location",
|
||||
"JobRouteStart": "Use {1} to start a job route with this vehicle",
|
||||
"PayPhoneFirstUse": "Use {1} to end the call, and {2} to give the phone to somebody nearby"
|
||||
},
|
||||
"NoBusinessesWithinRange": "There are no businesses within {1} meters",
|
||||
"NoHousesWithinRange": "There are no houses within {1} meters",
|
||||
"NoPayPhonesWithinRange": "There are no payphones within {1} meters",
|
||||
"HeaderBusinessesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderHousesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderPayPhonesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderCommandsForStaffFlagList": "Admin Commands ({1})",
|
||||
"PlayerLocateDistanceAndDirection": "{1} is {2} meters {3}",
|
||||
"MustBeNumber": "You need to use a number!",
|
||||
"HeaderJobRoutesList": "Job Routes ({1})",
|
||||
"HeaderJobRouteInfo": "Job Route Information (${1})",
|
||||
"InvalidJobRoute": "Job route not found!",
|
||||
"PayPhoneDeleted": "The payphone was deleted",
|
||||
"PayPhoneAnswer": "Use {1} to answer the payphone",
|
||||
"ResetActionTipsConfirm": "Are you sure you want to reset all seen action tips?",
|
||||
"ActionTipsReset": "All seen action tips have been reset.",
|
||||
"NormalChatDisabled": "Normal chat is disabled by server admin. Use chat commands instead.",
|
||||
"GlobalChatDisabled": "Global out-of-character chat is disabled by server admin"
|
||||
}
|
||||
@@ -16,12 +16,9 @@
|
||||
"AnimationStopCommandTip": "使用 {1} 以停止当前动作",
|
||||
"CantBanClient": "你无法封禁该玩家",
|
||||
"PlayerAccountBanned": "{1} 的账户已被封禁",
|
||||
"ClanNotFound": "帮派不存在",
|
||||
"ClanNameTaken": "该帮派名称已被占用",
|
||||
"PlayerNotFound": "玩家不存在",
|
||||
"ClanCantRemoveRanks": "无法清除帮派等级",
|
||||
"ClanCantAddRanks": "无法增加帮派等级",
|
||||
"ClanRankNotFound": "帮派等级不存在",
|
||||
"ClanCantChangeMemberTag": "你无法更改帮派成员的标签",
|
||||
"ClanPlayerNotInSameClan": "该玩家并不属于你的帮派",
|
||||
"ClanCantChangeRankLevel": "你无法更改帮派等级",
|
||||
@@ -651,28 +648,6 @@
|
||||
"LeftWrist": "Left Wrist",
|
||||
"RightWrist": "Right Wrist"
|
||||
},
|
||||
"ActionTips": {
|
||||
"VehicleEngineOffWhenEnteringKey": "Use {1} to turn on or off a vehicle's engine",
|
||||
"VehicleLockedAfterEntryAttempt": "Use {1} to lock or unlock a vehicle",
|
||||
"ShowItemsAfterPurchase": "Use {1} to see your inventory",
|
||||
"BuyCommandAfterEnterBusiness": "Use {1} to buy items from a business",
|
||||
"UseItemKeyAfterEquipping": "Use {1} to use your equipped item",
|
||||
"UseItemKeyAfterEquippingWalkieTalkie": "Use {1} to turn on or off your radio",
|
||||
"RadioCommandAfterEnablingWalkieTalkie": "Use {1} to talk on your radio",
|
||||
"ReplyToDirectMessage": "Use {1} to easily reply to a private message",
|
||||
"UseItemKeyAmmoAfterEquippingWeapon": "Use {1} to load an ammo item into your equipped weapon",
|
||||
"AnimationStop": "Use {1} to stop your animation",
|
||||
"JobEquipmentInventory": "The job equipment is in your inventory. Use {1} to see them.",
|
||||
"ViewInventory": "Use {1} to see your items",
|
||||
"VehicleRepairItemUsage": "Stand next to a vehicle and use {1} to repair it",
|
||||
"VehicleColourItemUsage": "Stand next to a vehicle and use {1} to change it's colour",
|
||||
"VehiclePartItemUsage": "Stand next to a vehicle and use {1} to upgrade with {2}",
|
||||
"AmmoClipItemUsage": "Equip the weapon and use {1} to load ammo into it",
|
||||
"GenericItemUsage": "Use {1} to use the {2}",
|
||||
"EnterJobVehicleForRoute": "Enter a job vehicle nearby to start a job route",
|
||||
"JobLocations": "Visit a job location to get a job. Use {1} to find a job location",
|
||||
"JobRouteStart": "Use {1} to start a job route with this vehicle"
|
||||
},
|
||||
"DisconnectReasons": {
|
||||
"Unknown": "Unknown",
|
||||
"LostConnection": "Lost Connection",
|
||||
@@ -748,5 +723,60 @@
|
||||
"Cancel": "Cancel",
|
||||
"AlreadyOwnVehicle": "You already own this vehicle!",
|
||||
"PropertyEntranceFeeLabel": "Entrance Fee: {1}",
|
||||
"NeedToBeInJobVehicle": "You need to be in a job vehicle!"
|
||||
"NeedToBeInJobVehicle": "You need to be in a job vehicle!",
|
||||
"InvalidJobRank": "Job rank not found!",
|
||||
"PayPhoneRecipientAnswered": "Somebody answered the call. Use normal chat to talk to them.",
|
||||
"PayPhoneAnswered": "You answered the phone. Use normal chat to talk to the caller.",
|
||||
"PayPhoneRecipientHangup": "The line was disconnected. You have been charged {1}",
|
||||
"PayPhoneHangup": "You hung up the phone.",
|
||||
"AlreadyUsingPayPhone": "You are already using a payphone!",
|
||||
"NotUsingPayPhone": "You are not using a payphone!",
|
||||
"NoPayPhoneCloseEnough": "There is no payphone close enough!",
|
||||
"PayPhoneNotRinging": "This payphone is not ringing!",
|
||||
"PayPhoneOccupied": "This payphone is already being used by someone else!",
|
||||
"PayPhoneOccupantSwitched": "A different voice is now on the line",
|
||||
"PayPhoneGiven": "You gave the phone to {1}",
|
||||
"PayPhoneReceived": "{1} gave you the phone",
|
||||
"PayPhoneUnableToCallPlayer": "You can't call {1} at this time. Please try again later.",
|
||||
"ActionTips": {
|
||||
"VehicleEngineOffWhenEnteringKey": "Use {1} to turn on or off a vehicle's engine",
|
||||
"VehicleLockedAfterEntryAttempt": "Use {1} to lock or unlock a vehicle",
|
||||
"ShowItemsAfterPurchase": "Use {1} to see your inventory",
|
||||
"BuyCommandAfterEnterBusiness": "Use {1} to buy items from a business",
|
||||
"UseItemKeyAfterEquipping": "Use {1} to use your equipped item",
|
||||
"UseItemKeyAfterEquippingWalkieTalkie": "Use {1} to turn on or off your radio",
|
||||
"RadioCommandAfterEnablingWalkieTalkie": "Use {1} to talk on your radio",
|
||||
"ReplyToDirectMessage": "Use {1} to easily reply to a private message",
|
||||
"UseItemKeyAmmoAfterEquippingWeapon": "Use {1} to load an ammo item into your equipped weapon",
|
||||
"AnimationStop": "Use {1} to stop your animation",
|
||||
"JobEquipmentInventory": "The job equipment is in your inventory. Use {1} to see them.",
|
||||
"ViewInventory": "Use {1} to see your items",
|
||||
"VehicleRepairItemUsage": "Stand next to a vehicle and use {1} to repair it",
|
||||
"VehicleColourItemUsage": "Stand next to a vehicle and use {1} to change it's colour",
|
||||
"VehiclePartItemUsage": "Stand next to a vehicle and use {1} to upgrade with {2}",
|
||||
"AmmoClipItemUsage": "Equip the weapon and use {1} to load ammo into it",
|
||||
"GenericItemUsage": "Use {1} to use the {2}",
|
||||
"EnterJobVehicleForRoute": "Enter a job vehicle nearby to start a job route",
|
||||
"JobLocations": "Visit a job location to get a job. Use {1} to find a job location",
|
||||
"JobRouteStart": "Use {1} to start a job route with this vehicle",
|
||||
"PayPhoneFirstUse": "Use {1} to end the call, and {2} to give the phone to somebody nearby"
|
||||
},
|
||||
"NoBusinessesWithinRange": "There are no businesses within {1} meters",
|
||||
"NoHousesWithinRange": "There are no houses within {1} meters",
|
||||
"NoPayPhonesWithinRange": "There are no payphones within {1} meters",
|
||||
"HeaderBusinessesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderHousesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderPayPhonesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderCommandsForStaffFlagList": "Admin Commands ({1})",
|
||||
"PlayerLocateDistanceAndDirection": "{1} is {2} meters {3}",
|
||||
"MustBeNumber": "You need to use a number!",
|
||||
"HeaderJobRoutesList": "Job Routes ({1})",
|
||||
"HeaderJobRouteInfo": "Job Route Information (${1})",
|
||||
"InvalidJobRoute": "Job route not found!",
|
||||
"PayPhoneDeleted": "The payphone was deleted",
|
||||
"PayPhoneAnswer": "Use {1} to answer the payphone",
|
||||
"ResetActionTipsConfirm": "Are you sure you want to reset all seen action tips?",
|
||||
"ActionTipsReset": "All seen action tips have been reset.",
|
||||
"NormalChatDisabled": "Normal chat is disabled by server admin. Use chat commands instead.",
|
||||
"GlobalChatDisabled": "Global out-of-character chat is disabled by server admin"
|
||||
}
|
||||
|
||||
@@ -16,9 +16,7 @@
|
||||
"InvalidAnimationDistance": "The distance must be between 0 and 3",
|
||||
"CantBanClient": "You cannot ban this person",
|
||||
"PlayerAccountBanned": "{1} has been account banned",
|
||||
"ClanNotFound": "Clan not found",
|
||||
"ClanNameTaken": "A clan with that name already exists",
|
||||
"PlayerNotFound": "Player not found",
|
||||
"ClanCantRemoveRanks": "You can't remove clan ranks",
|
||||
"ClanCantAddRanks": "You can't add clan ranks",
|
||||
"ClanRankNotFound": "Clan rank not found",
|
||||
@@ -653,28 +651,6 @@
|
||||
"LeftWrist": "Left Wrist",
|
||||
"RightWrist": "Right Wrist"
|
||||
},
|
||||
"ActionTips": {
|
||||
"VehicleEngineOffWhenEnteringKey": "Use {1} to turn on or off a vehicle's engine",
|
||||
"VehicleLockedAfterEntryAttempt": "Use {1} to lock or unlock a vehicle",
|
||||
"ShowItemsAfterPurchase": "Use {1} to see your inventory",
|
||||
"BuyCommandAfterEnterBusiness": "Use {1} to buy items from a business",
|
||||
"UseItemKeyAfterEquipping": "Use {1} to use your equipped item",
|
||||
"UseItemKeyAfterEquippingWalkieTalkie": "Use {1} to turn on or off your radio",
|
||||
"RadioCommandAfterEnablingWalkieTalkie": "Use {1} to talk on your radio",
|
||||
"ReplyToDirectMessage": "Use {1} to easily reply to a private message",
|
||||
"UseItemKeyAmmoAfterEquippingWeapon": "Use {1} to load an ammo item into your equipped weapon",
|
||||
"AnimationStop": "Use {1} to stop your animation",
|
||||
"JobEquipmentInventory": "The job equipment is in your inventory. Use {1} to see them.",
|
||||
"ViewInventory": "Use {1} to see your items",
|
||||
"VehicleRepairItemUsage": "Stand next to a vehicle and use {1} to repair it",
|
||||
"VehicleColourItemUsage": "Stand next to a vehicle and use {1} to change it's colour",
|
||||
"VehiclePartItemUsage": "Stand next to a vehicle and use {1} to upgrade with {2}",
|
||||
"AmmoClipItemUsage": "Equip the weapon and use {1} to load ammo into it",
|
||||
"GenericItemUsage": "Use {1} to use the {2}",
|
||||
"EnterJobVehicleForRoute": "Enter a job vehicle nearby to start a job route",
|
||||
"JobLocations": "Visit a job location to get a job. Use {1} to find a job location",
|
||||
"JobRouteStart": "Use {1} to start a job route with this vehicle"
|
||||
},
|
||||
"DisconnectReasons": {
|
||||
"Unknown": "Unknown",
|
||||
"LostConnection": "Lost Connection",
|
||||
@@ -750,5 +726,68 @@
|
||||
"Cancel": "Cancel",
|
||||
"AlreadyOwnVehicle": "You already own this vehicle!",
|
||||
"PropertyEntranceFeeLabel": "Entrance Fee: {1}",
|
||||
"NeedToBeInJobVehicle": "You need to be in a job vehicle!"
|
||||
"NeedToBeInJobVehicle": "You need to be in a job vehicle!",
|
||||
"InvalidJobRank": "Job rank not found!",
|
||||
"NoPlayerCloseEnough": "There is no player close enough!",
|
||||
"PayPhoneRecipientAnswered": "Somebody answered the call. Use normal chat to talk to them.",
|
||||
"PayPhoneAnswered": "You answered the phone. Use normal chat to talk to the caller.",
|
||||
"PayPhoneRecipientHangup": "The line was disconnected. You have been charged {1}",
|
||||
"PayPhoneHangup": "You hung up the phone.",
|
||||
"AlreadyUsingPayPhone": "You are already using a payphone!",
|
||||
"NotUsingPayPhone": "You are not using a payphone!",
|
||||
"NoPayPhoneCloseEnough": "There is no payphone close enough!",
|
||||
"PayPhoneNotRinging": "This payphone is not ringing!",
|
||||
"PayPhoneOccupied": "This payphone is already being used by someone else!",
|
||||
"PayPhoneOccupantSwitched": "A different voice is now on the line",
|
||||
"PayPhoneGiven": "You gave the phone to {1}",
|
||||
"PayPhoneReceived": "{1} gave you the phone",
|
||||
"PayPhoneUnableToCallPlayer": "You can't call {1} at this time. Please try again later.",
|
||||
"ActionTips": {
|
||||
"VehicleEngineOffWhenEnteringKey": "Use {1} to turn on or off a vehicle's engine",
|
||||
"VehicleLockedAfterEntryAttempt": "Use {1} to lock or unlock a vehicle",
|
||||
"ShowItemsAfterPurchase": "Use {1} to see your inventory",
|
||||
"BuyCommandAfterEnterBusiness": "Use {1} to buy items from a business",
|
||||
"UseItemKeyAfterEquipping": "Use {1} to use your equipped item",
|
||||
"UseItemKeyAfterEquippingWalkieTalkie": "Use {1} to turn on or off your radio",
|
||||
"RadioCommandAfterEnablingWalkieTalkie": "Use {1} to talk on your radio",
|
||||
"ReplyToDirectMessage": "Use {1} to easily reply to a private message",
|
||||
"UseItemKeyAmmoAfterEquippingWeapon": "Use {1} to load an ammo item into your equipped weapon",
|
||||
"AnimationStop": "Use {1} to stop your animation",
|
||||
"JobEquipmentInventory": "The job equipment is in your inventory. Use {1} to see them.",
|
||||
"ViewInventory": "Use {1} to see your items",
|
||||
"VehicleRepairItemUsage": "Stand next to a vehicle and use {1} to repair it",
|
||||
"VehicleColourItemUsage": "Stand next to a vehicle and use {1} to change it's colour",
|
||||
"VehiclePartItemUsage": "Stand next to a vehicle and use {1} to upgrade with {2}",
|
||||
"AmmoClipItemUsage": "Equip the weapon and use {1} to load ammo into it",
|
||||
"GenericItemUsage": "Use {1} to use the {2}",
|
||||
"EnterJobVehicleForRoute": "Enter a job vehicle nearby to start a job route",
|
||||
"JobLocations": "Visit a job location to get a job. Use {1} to find a job location",
|
||||
"JobRouteStart": "Use {1} to start a job route with this vehicle",
|
||||
"PayPhoneFirstUse": "Use {1} to end the call, and {2} to give the phone to somebody nearby",
|
||||
"BusinessOwnerHelp": "Use {1} to see commands and information for business owners"
|
||||
},
|
||||
"NoBusinessesWithinRange": "There are no businesses within {1} meters",
|
||||
"NoHousesWithinRange": "There are no houses within {1} meters",
|
||||
"NoPayPhonesWithinRange": "There are no payphones within {1} meters",
|
||||
"HeaderBusinessesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderHousesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderPayPhonesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderCommandsForStaffFlagList": "Admin Commands ({1})",
|
||||
"PlayerLocateDistanceAndDirection": "{1} is {2} meters {3}",
|
||||
"MustBeNumber": "You need to use a number!",
|
||||
"HeaderJobRoutesList": "Job Routes ({1})",
|
||||
"HeaderJobRouteInfo": "Job Route Information (${1})",
|
||||
"InvalidJobRoute": "Job route not found!",
|
||||
"PayPhoneDeleted": "The payphone was deleted",
|
||||
"PayPhoneAnswer": "Use {1} to answer the payphone",
|
||||
"ResetActionTipsConfirm": "Are you sure you want to reset all seen action tips?",
|
||||
"ActionTipsReset": "All seen action tips have been reset.",
|
||||
"NormalChatDisabled": "Normal chat is disabled by server admin. Use chat commands instead.",
|
||||
"GlobalChatDisabled": "Global out-of-character chat is disabled by server admin",
|
||||
"GUIAlertTitle": "Alert!",
|
||||
"JobInviteSent": "You sent a job invite to {1}",
|
||||
"JobInviteAlreadyHasJob": "That player already has a job!",
|
||||
"JobInviteRequest": "{1} invited you to the {2} job.",
|
||||
"CantAddJobMembers": "You can't invite new members to the job!",
|
||||
"CantRemoveJobMembers": "You can't remove members from the job!"
|
||||
}
|
||||
|
||||
@@ -16,12 +16,9 @@
|
||||
"InvalidAnimationDistance": "etäisyyden pitää olla väliin 0 ja 3",
|
||||
"CantBanClient": "Sinä et voi bannätä tätä pelaajaa",
|
||||
"PlayerAccountBanned": "{1} Käyttäjä on nyt bannätty",
|
||||
"ClanNotFound": "Claania ei löydetty",
|
||||
"ClanNameTaken": "Claani tuolla nimellä on jo otettu",
|
||||
"PlayerNotFound": "Pelaajaa ei löytynyt ",
|
||||
"ClanCantRemoveRanks": "Sinä et voi poistaa tämän claanin rankkejä",
|
||||
"ClanCantAddRanks": "sinä et voi lisätä claani ranksejä",
|
||||
"ClanRankNotFound": "Claanin nimeä ei loytynyt",
|
||||
"ClanCantChangeMemberTag": " Sinä et voi vaihtaa claanin jäsenen tagejä",
|
||||
"ClanPlayerNotInSameClan": "Tuo pelaaja ei ole sinun claanissa.",
|
||||
"ClanCantChangeRankLevel": "Sinä et voi vaihtaa claanin rankin leveleitä",
|
||||
@@ -650,28 +647,6 @@
|
||||
"LeftWrist": "Vasempi Ranne",
|
||||
"RightWrist": "Oikeampi Ranne"
|
||||
},
|
||||
"ActionTips": {
|
||||
"VehicleEngineOffWhenEnteringKey": "Käytä {1} laittaksesi päälle tai kiinni ajoneuvon moottori",
|
||||
"VehicleLockedAfterEntryAttempt": "Käytä {1} Lukitaaksesi tai aukaaksesi ajoneuvosi",
|
||||
"ShowItemsAfterPurchase": "Käytä {1} Nähdääksesi Tavarasi",
|
||||
"BuyCommandAfterEnterBusiness": "Käytä {1} tuotteiden ostamiseen yrityksestä",
|
||||
"UseItemKeyAfterEquipping": "Käytä {1} käyttääksesi varustetasi",
|
||||
"UseItemKeyAfterEquippingWalkieTalkie": "Käytä {1} kytkeäksesi radion päälle tai pois",
|
||||
"RadioCommandAfterEnablingWalkieTalkie": "Käytä {1} puhuaksesi radiossasi",
|
||||
"ReplyToDirectMessage": "Käytä {1} vastataksesi helposti yksityisviestiin",
|
||||
"UseItemKeyAmmoAfterEquippingWeapon": "Käytä {1} ladataksesi ammuksia varustetulle aseesesi",
|
||||
"AnimationStop": "Pysäytä animaatio painamalla {1}",
|
||||
"JobEquipmentInventory": "Työvälineet ovat varastossasi. Käytä {1} nähdäksesi ne.",
|
||||
"ViewInventory": "Käytä {1} nähdäksesi kohteesi",
|
||||
"VehicleRepairItemUsage": "Seiso ajoneuvon vieressä ja käytä {1} Korjaaksesi sen",
|
||||
"VehicleColourItemUsage": "Seiso ajoneuvon vieressä ja käytä {1} Vaihtaaksesi sen väriä",
|
||||
"VehiclePartItemUsage": "Seiso ajoneuvon vieressä ja käytä {1} tuunatakseen {2}",
|
||||
"AmmoClipItemUsage": "Varusta ase ja käytä {1} ladataaksesi panoksia",
|
||||
"GenericItemUsage": "Käytä {1} käyttääksesi {2}",
|
||||
"EnterJobVehicleForRoute": "Enter a job vehicle nearby to start a job route",
|
||||
"JobLocations": "Visit a job location to get a job. Use {1} to find a job location",
|
||||
"JobRouteStart": "Use {1} to start a job route with this vehicle"
|
||||
},
|
||||
"DisconnectReasons": {
|
||||
"Unknown": "Tuntematon",
|
||||
"LostConnection": "Yhteys menetetty",
|
||||
@@ -747,5 +722,60 @@
|
||||
"Cancel": "Cancel",
|
||||
"AlreadyOwnVehicle": "You already own this vehicle!",
|
||||
"PropertyEntranceFeeLabel": "Entrance Fee: {1}",
|
||||
"NeedToBeInJobVehicle": "You need to be in a job vehicle!"
|
||||
"NeedToBeInJobVehicle": "You need to be in a job vehicle!",
|
||||
"InvalidJobRank": "Job rank not found!",
|
||||
"PayPhoneRecipientAnswered": "Somebody answered the call. Use normal chat to talk to them.",
|
||||
"PayPhoneAnswered": "You answered the phone. Use normal chat to talk to the caller.",
|
||||
"PayPhoneRecipientHangup": "The line was disconnected. You have been charged {1}",
|
||||
"PayPhoneHangup": "You hung up the phone.",
|
||||
"AlreadyUsingPayPhone": "You are already using a payphone!",
|
||||
"NotUsingPayPhone": "You are not using a payphone!",
|
||||
"NoPayPhoneCloseEnough": "There is no payphone close enough!",
|
||||
"PayPhoneNotRinging": "This payphone is not ringing!",
|
||||
"PayPhoneOccupied": "This payphone is already being used by someone else!",
|
||||
"PayPhoneOccupantSwitched": "A different voice is now on the line",
|
||||
"PayPhoneGiven": "You gave the phone to {1}",
|
||||
"PayPhoneReceived": "{1} gave you the phone",
|
||||
"PayPhoneUnableToCallPlayer": "You can't call {1} at this time. Please try again later.",
|
||||
"ActionTips": {
|
||||
"VehicleEngineOffWhenEnteringKey": "Käytä {1} laittaksesi päälle tai kiinni ajoneuvon moottori",
|
||||
"VehicleLockedAfterEntryAttempt": "Käytä {1} Lukitaaksesi tai aukaaksesi ajoneuvosi",
|
||||
"ShowItemsAfterPurchase": "Käytä {1} Nähdääksesi Tavarasi",
|
||||
"BuyCommandAfterEnterBusiness": "Käytä {1} tuotteiden ostamiseen yrityksestä",
|
||||
"UseItemKeyAfterEquipping": "Käytä {1} käyttääksesi varustetasi",
|
||||
"UseItemKeyAfterEquippingWalkieTalkie": "Käytä {1} kytkeäksesi radion päälle tai pois",
|
||||
"RadioCommandAfterEnablingWalkieTalkie": "Käytä {1} puhuaksesi radiossasi",
|
||||
"ReplyToDirectMessage": "Käytä {1} vastataksesi helposti yksityisviestiin",
|
||||
"UseItemKeyAmmoAfterEquippingWeapon": "Käytä {1} ladataksesi ammuksia varustetulle aseesesi",
|
||||
"AnimationStop": "Pysäytä animaatio painamalla {1}",
|
||||
"JobEquipmentInventory": "Työvälineet ovat varastossasi. Käytä {1} nähdäksesi ne.",
|
||||
"ViewInventory": "Käytä {1} nähdäksesi kohteesi",
|
||||
"VehicleRepairItemUsage": "Seiso ajoneuvon vieressä ja käytä {1} Korjaaksesi sen",
|
||||
"VehicleColourItemUsage": "Seiso ajoneuvon vieressä ja käytä {1} Vaihtaaksesi sen väriä",
|
||||
"VehiclePartItemUsage": "Seiso ajoneuvon vieressä ja käytä {1} tuunatakseen {2}",
|
||||
"AmmoClipItemUsage": "Varusta ase ja käytä {1} ladataaksesi panoksia",
|
||||
"GenericItemUsage": "Käytä {1} käyttääksesi {2}",
|
||||
"EnterJobVehicleForRoute": "Enter a job vehicle nearby to start a job route",
|
||||
"JobLocations": "Visit a job location to get a job. Use {1} to find a job location",
|
||||
"JobRouteStart": "Use {1} to start a job route with this vehicle",
|
||||
"PayPhoneFirstUse": "Use {1} to end the call, and {2} to give the phone to somebody nearby"
|
||||
},
|
||||
"NoBusinessesWithinRange": "There are no businesses within {1} meters",
|
||||
"NoHousesWithinRange": "There are no houses within {1} meters",
|
||||
"NoPayPhonesWithinRange": "There are no payphones within {1} meters",
|
||||
"HeaderBusinessesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderHousesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderPayPhonesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderCommandsForStaffFlagList": "Admin Commands ({1})",
|
||||
"PlayerLocateDistanceAndDirection": "{1} is {2} meters {3}",
|
||||
"MustBeNumber": "You need to use a number!",
|
||||
"HeaderJobRoutesList": "Job Routes ({1})",
|
||||
"HeaderJobRouteInfo": "Job Route Information (${1})",
|
||||
"InvalidJobRoute": "Job route not found!",
|
||||
"PayPhoneDeleted": "The payphone was deleted",
|
||||
"PayPhoneAnswer": "Use {1} to answer the payphone",
|
||||
"ResetActionTipsConfirm": "Are you sure you want to reset all seen action tips?",
|
||||
"ActionTipsReset": "All seen action tips have been reset.",
|
||||
"NormalChatDisabled": "Normal chat is disabled by server admin. Use chat commands instead.",
|
||||
"GlobalChatDisabled": "Global out-of-character chat is disabled by server admin"
|
||||
}
|
||||
|
||||
@@ -16,12 +16,9 @@
|
||||
"InvalidAnimationDistance": "La distance doit être entre 0 et 3",
|
||||
"CantBanClient": "Vous ne pouvez pas bannir cette personne",
|
||||
"PlayerAccountBanned": "le compte {1} a été banni",
|
||||
"ClanNotFound": "Clan non trouvé",
|
||||
"ClanNameTaken": "Un clan avec ce nom existe déjà",
|
||||
"PlayerNotFound": "Joueur non trouvé",
|
||||
"ClanCantRemoveRanks": "Vous ne pouvez pas retirer le rang du clan",
|
||||
"ClanCantAddRanks": "Vous ne pouvez pas ajouter de rang au clan",
|
||||
"ClanRankNotFound": "Le rang du clan est introuvable",
|
||||
"ClanCantChangeMemberTag": "Vous ne pouvez pas modifier les tags des membres du clan",
|
||||
"ClanPlayerNotInSameClan": "Ce joueur n'est pas dans votre clan",
|
||||
"ClanCantChangeRankLevel": "Vous ne pouvez pas modifier le niveau du rang du clan",
|
||||
@@ -651,28 +648,6 @@
|
||||
"LeftWrist": "Left Wrist",
|
||||
"RightWrist": "Right Wrist"
|
||||
},
|
||||
"ActionTips": {
|
||||
"VehicleEngineOffWhenEnteringKey": "Use {1} to turn on or off a vehicle's engine",
|
||||
"VehicleLockedAfterEntryAttempt": "Use {1} to lock or unlock a vehicle",
|
||||
"ShowItemsAfterPurchase": "Use {1} to see your inventory",
|
||||
"BuyCommandAfterEnterBusiness": "Use {1} to buy items from a business",
|
||||
"UseItemKeyAfterEquipping": "Use {1} to use your equipped item",
|
||||
"UseItemKeyAfterEquippingWalkieTalkie": "Use {1} to turn on or off your radio",
|
||||
"RadioCommandAfterEnablingWalkieTalkie": "Use {1} to talk on your radio",
|
||||
"ReplyToDirectMessage": "Use {1} to easily reply to a private message",
|
||||
"UseItemKeyAmmoAfterEquippingWeapon": "Use {1} to load an ammo item into your equipped weapon",
|
||||
"AnimationStop": "Use {1} to stop your animation",
|
||||
"JobEquipmentInventory": "The job equipment is in your inventory. Use {1} to see them.",
|
||||
"ViewInventory": "Use {1} to see your items",
|
||||
"VehicleRepairItemUsage": "Stand next to a vehicle and use {1} to repair it",
|
||||
"VehicleColourItemUsage": "Stand next to a vehicle and use {1} to change it's colour",
|
||||
"VehiclePartItemUsage": "Stand next to a vehicle and use {1} to upgrade with {2}",
|
||||
"AmmoClipItemUsage": "Equip the weapon and use {1} to load ammo into it",
|
||||
"GenericItemUsage": "Use {1} to use the {2}",
|
||||
"EnterJobVehicleForRoute": "Enter a job vehicle nearby to start a job route",
|
||||
"JobLocations": "Visit a job location to get a job. Use {1} to find a job location",
|
||||
"JobRouteStart": "Use {1} to start a job route with this vehicle"
|
||||
},
|
||||
"DisconnectReasons": {
|
||||
"Unknown": "Unknown",
|
||||
"LostConnection": "Lost Connection",
|
||||
@@ -748,5 +723,60 @@
|
||||
"Cancel": "Cancel",
|
||||
"AlreadyOwnVehicle": "You already own this vehicle!",
|
||||
"PropertyEntranceFeeLabel": "Entrance Fee: {1}",
|
||||
"NeedToBeInJobVehicle": "You need to be in a job vehicle!"
|
||||
"NeedToBeInJobVehicle": "You need to be in a job vehicle!",
|
||||
"InvalidJobRank": "Job rank not found!",
|
||||
"PayPhoneRecipientAnswered": "Somebody answered the call. Use normal chat to talk to them.",
|
||||
"PayPhoneAnswered": "You answered the phone. Use normal chat to talk to the caller.",
|
||||
"PayPhoneRecipientHangup": "The line was disconnected. You have been charged {1}",
|
||||
"PayPhoneHangup": "You hung up the phone.",
|
||||
"AlreadyUsingPayPhone": "You are already using a payphone!",
|
||||
"NotUsingPayPhone": "You are not using a payphone!",
|
||||
"NoPayPhoneCloseEnough": "There is no payphone close enough!",
|
||||
"PayPhoneNotRinging": "This payphone is not ringing!",
|
||||
"PayPhoneOccupied": "This payphone is already being used by someone else!",
|
||||
"PayPhoneOccupantSwitched": "A different voice is now on the line",
|
||||
"PayPhoneGiven": "You gave the phone to {1}",
|
||||
"PayPhoneReceived": "{1} gave you the phone",
|
||||
"PayPhoneUnableToCallPlayer": "You can't call {1} at this time. Please try again later.",
|
||||
"ActionTips": {
|
||||
"VehicleEngineOffWhenEnteringKey": "Use {1} to turn on or off a vehicle's engine",
|
||||
"VehicleLockedAfterEntryAttempt": "Use {1} to lock or unlock a vehicle",
|
||||
"ShowItemsAfterPurchase": "Use {1} to see your inventory",
|
||||
"BuyCommandAfterEnterBusiness": "Use {1} to buy items from a business",
|
||||
"UseItemKeyAfterEquipping": "Use {1} to use your equipped item",
|
||||
"UseItemKeyAfterEquippingWalkieTalkie": "Use {1} to turn on or off your radio",
|
||||
"RadioCommandAfterEnablingWalkieTalkie": "Use {1} to talk on your radio",
|
||||
"ReplyToDirectMessage": "Use {1} to easily reply to a private message",
|
||||
"UseItemKeyAmmoAfterEquippingWeapon": "Use {1} to load an ammo item into your equipped weapon",
|
||||
"AnimationStop": "Use {1} to stop your animation",
|
||||
"JobEquipmentInventory": "The job equipment is in your inventory. Use {1} to see them.",
|
||||
"ViewInventory": "Use {1} to see your items",
|
||||
"VehicleRepairItemUsage": "Stand next to a vehicle and use {1} to repair it",
|
||||
"VehicleColourItemUsage": "Stand next to a vehicle and use {1} to change it's colour",
|
||||
"VehiclePartItemUsage": "Stand next to a vehicle and use {1} to upgrade with {2}",
|
||||
"AmmoClipItemUsage": "Equip the weapon and use {1} to load ammo into it",
|
||||
"GenericItemUsage": "Use {1} to use the {2}",
|
||||
"EnterJobVehicleForRoute": "Enter a job vehicle nearby to start a job route",
|
||||
"JobLocations": "Visit a job location to get a job. Use {1} to find a job location",
|
||||
"JobRouteStart": "Use {1} to start a job route with this vehicle",
|
||||
"PayPhoneFirstUse": "Use {1} to end the call, and {2} to give the phone to somebody nearby"
|
||||
},
|
||||
"NoBusinessesWithinRange": "There are no businesses within {1} meters",
|
||||
"NoHousesWithinRange": "There are no houses within {1} meters",
|
||||
"NoPayPhonesWithinRange": "There are no payphones within {1} meters",
|
||||
"HeaderBusinessesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderHousesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderPayPhonesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderCommandsForStaffFlagList": "Admin Commands ({1})",
|
||||
"PlayerLocateDistanceAndDirection": "{1} is {2} meters {3}",
|
||||
"MustBeNumber": "You need to use a number!",
|
||||
"HeaderJobRoutesList": "Job Routes ({1})",
|
||||
"HeaderJobRouteInfo": "Job Route Information (${1})",
|
||||
"InvalidJobRoute": "Job route not found!",
|
||||
"PayPhoneDeleted": "The payphone was deleted",
|
||||
"PayPhoneAnswer": "Use {1} to answer the payphone",
|
||||
"ResetActionTipsConfirm": "Are you sure you want to reset all seen action tips?",
|
||||
"ActionTipsReset": "All seen action tips have been reset.",
|
||||
"NormalChatDisabled": "Normal chat is disabled by server admin. Use chat commands instead.",
|
||||
"GlobalChatDisabled": "Global out-of-character chat is disabled by server admin"
|
||||
}
|
||||
@@ -16,12 +16,9 @@
|
||||
"InvalidAnimationDistance": "The distance must be between 0 and 3",
|
||||
"CantBanClient": "You cannot ban this person",
|
||||
"PlayerAccountBanned": "{1} has been account banned",
|
||||
"ClanNotFound": "Clan not found",
|
||||
"ClanNameTaken": "A clan with that name already exists",
|
||||
"PlayerNotFound": "Player not found",
|
||||
"ClanCantRemoveRanks": "You can't remove clan ranks",
|
||||
"ClanCantAddRanks": "You can't add clan ranks",
|
||||
"ClanRankNotFound": "Clan rank not found",
|
||||
"ClanCantChangeMemberTag": "You can not change clan member's tags",
|
||||
"ClanPlayerNotInSameClan": "That player is not in your clan",
|
||||
"ClanCantChangeRankLevel": "You can not change clan rank's level",
|
||||
@@ -650,28 +647,6 @@
|
||||
"LeftWrist": "Left Wrist",
|
||||
"RightWrist": "Right Wrist"
|
||||
},
|
||||
"ActionTips": {
|
||||
"VehicleEngineOffWhenEnteringKey": "Use {1} to turn on or off a vehicle's engine",
|
||||
"VehicleLockedAfterEntryAttempt": "Use {1} to lock or unlock a vehicle",
|
||||
"ShowItemsAfterPurchase": "Use {1} to see your inventory",
|
||||
"BuyCommandAfterEnterBusiness": "Use {1} to buy items from a business",
|
||||
"UseItemKeyAfterEquipping": "Use {1} to use your equipped item",
|
||||
"UseItemKeyAfterEquippingWalkieTalkie": "Use {1} to turn on or off your radio",
|
||||
"RadioCommandAfterEnablingWalkieTalkie": "Use {1} to talk on your radio",
|
||||
"ReplyToDirectMessage": "Use {1} to easily reply to a private message",
|
||||
"UseItemKeyAmmoAfterEquippingWeapon": "Use {1} to load an ammo item into your equipped weapon",
|
||||
"AnimationStop": "Use {1} to stop your animation",
|
||||
"JobEquipmentInventory": "The job equipment is in your inventory. Use {1} to see them.",
|
||||
"ViewInventory": "Use {1} to see your items",
|
||||
"VehicleRepairItemUsage": "Stand next to a vehicle and use {1} to repair it",
|
||||
"VehicleColourItemUsage": "Stand next to a vehicle and use {1} to change it's colour",
|
||||
"VehiclePartItemUsage": "Stand next to a vehicle and use {1} to upgrade with {2}",
|
||||
"AmmoClipItemUsage": "Equip the weapon and use {1} to load ammo into it",
|
||||
"GenericItemUsage": "Use {1} to use the {2}",
|
||||
"EnterJobVehicleForRoute": "Enter a job vehicle nearby to start a job route",
|
||||
"JobLocations": "Visit a job location to get a job. Use {1} to find a job location",
|
||||
"JobRouteStart": "Use {1} to start a job route with this vehicle"
|
||||
},
|
||||
"DisconnectReasons": {
|
||||
"Unknown": "Unknown",
|
||||
"LostConnection": "Lost Connection",
|
||||
@@ -747,5 +722,60 @@
|
||||
"Cancel": "Cancel",
|
||||
"AlreadyOwnVehicle": "You already own this vehicle!",
|
||||
"PropertyEntranceFeeLabel": "Entrance Fee: {1}",
|
||||
"NeedToBeInJobVehicle": "You need to be in a job vehicle!"
|
||||
"NeedToBeInJobVehicle": "You need to be in a job vehicle!",
|
||||
"InvalidJobRank": "Job rank not found!",
|
||||
"PayPhoneRecipientAnswered": "Somebody answered the call. Use normal chat to talk to them.",
|
||||
"PayPhoneAnswered": "You answered the phone. Use normal chat to talk to the caller.",
|
||||
"PayPhoneRecipientHangup": "The line was disconnected. You have been charged {1}",
|
||||
"PayPhoneHangup": "You hung up the phone.",
|
||||
"AlreadyUsingPayPhone": "You are already using a payphone!",
|
||||
"NotUsingPayPhone": "You are not using a payphone!",
|
||||
"NoPayPhoneCloseEnough": "There is no payphone close enough!",
|
||||
"PayPhoneNotRinging": "This payphone is not ringing!",
|
||||
"PayPhoneOccupied": "This payphone is already being used by someone else!",
|
||||
"PayPhoneOccupantSwitched": "A different voice is now on the line",
|
||||
"PayPhoneGiven": "You gave the phone to {1}",
|
||||
"PayPhoneReceived": "{1} gave you the phone",
|
||||
"PayPhoneUnableToCallPlayer": "You can't call {1} at this time. Please try again later.",
|
||||
"ActionTips": {
|
||||
"VehicleEngineOffWhenEnteringKey": "Use {1} to turn on or off a vehicle's engine",
|
||||
"VehicleLockedAfterEntryAttempt": "Use {1} to lock or unlock a vehicle",
|
||||
"ShowItemsAfterPurchase": "Use {1} to see your inventory",
|
||||
"BuyCommandAfterEnterBusiness": "Use {1} to buy items from a business",
|
||||
"UseItemKeyAfterEquipping": "Use {1} to use your equipped item",
|
||||
"UseItemKeyAfterEquippingWalkieTalkie": "Use {1} to turn on or off your radio",
|
||||
"RadioCommandAfterEnablingWalkieTalkie": "Use {1} to talk on your radio",
|
||||
"ReplyToDirectMessage": "Use {1} to easily reply to a private message",
|
||||
"UseItemKeyAmmoAfterEquippingWeapon": "Use {1} to load an ammo item into your equipped weapon",
|
||||
"AnimationStop": "Use {1} to stop your animation",
|
||||
"JobEquipmentInventory": "The job equipment is in your inventory. Use {1} to see them.",
|
||||
"ViewInventory": "Use {1} to see your items",
|
||||
"VehicleRepairItemUsage": "Stand next to a vehicle and use {1} to repair it",
|
||||
"VehicleColourItemUsage": "Stand next to a vehicle and use {1} to change it's colour",
|
||||
"VehiclePartItemUsage": "Stand next to a vehicle and use {1} to upgrade with {2}",
|
||||
"AmmoClipItemUsage": "Equip the weapon and use {1} to load ammo into it",
|
||||
"GenericItemUsage": "Use {1} to use the {2}",
|
||||
"EnterJobVehicleForRoute": "Enter a job vehicle nearby to start a job route",
|
||||
"JobLocations": "Visit a job location to get a job. Use {1} to find a job location",
|
||||
"JobRouteStart": "Use {1} to start a job route with this vehicle",
|
||||
"PayPhoneFirstUse": "Use {1} to end the call, and {2} to give the phone to somebody nearby"
|
||||
},
|
||||
"NoBusinessesWithinRange": "There are no businesses within {1} meters",
|
||||
"NoHousesWithinRange": "There are no houses within {1} meters",
|
||||
"NoPayPhonesWithinRange": "There are no payphones within {1} meters",
|
||||
"HeaderBusinessesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderHousesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderPayPhonesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderCommandsForStaffFlagList": "Admin Commands ({1})",
|
||||
"PlayerLocateDistanceAndDirection": "{1} is {2} meters {3}",
|
||||
"MustBeNumber": "You need to use a number!",
|
||||
"HeaderJobRoutesList": "Job Routes ({1})",
|
||||
"HeaderJobRouteInfo": "Job Route Information (${1})",
|
||||
"InvalidJobRoute": "Job route not found!",
|
||||
"PayPhoneDeleted": "The payphone was deleted",
|
||||
"PayPhoneAnswer": "Use {1} to answer the payphone",
|
||||
"ResetActionTipsConfirm": "Are you sure you want to reset all seen action tips?",
|
||||
"ActionTipsReset": "All seen action tips have been reset.",
|
||||
"NormalChatDisabled": "Normal chat is disabled by server admin. Use chat commands instead.",
|
||||
"GlobalChatDisabled": "Global out-of-character chat is disabled by server admin"
|
||||
}
|
||||
@@ -16,12 +16,9 @@
|
||||
"InvalidAnimationDistance": "The distance must be between 0 and 3",
|
||||
"CantBanClient": "You cannot ban this person",
|
||||
"PlayerAccountBanned": "{1} has been account banned",
|
||||
"ClanNotFound": "Clan not found",
|
||||
"ClanNameTaken": "A clan with that name already exists",
|
||||
"PlayerNotFound": "Player not found",
|
||||
"ClanCantRemoveRanks": "You can't remove clan ranks",
|
||||
"ClanCantAddRanks": "You can't add clan ranks",
|
||||
"ClanRankNotFound": "Clan rank not found",
|
||||
"ClanCantChangeMemberTag": "You can not change clan member's tags",
|
||||
"ClanPlayerNotInSameClan": "That player is not in your clan",
|
||||
"ClanCantChangeRankLevel": "You can not change clan rank's level",
|
||||
@@ -651,28 +648,6 @@
|
||||
"LeftWrist": "Left Wrist",
|
||||
"RightWrist": "Right Wrist"
|
||||
},
|
||||
"ActionTips": {
|
||||
"VehicleEngineOffWhenEnteringKey": "Use {1} to turn on or off a vehicle's engine",
|
||||
"VehicleLockedAfterEntryAttempt": "Use {1} to lock or unlock a vehicle",
|
||||
"ShowItemsAfterPurchase": "Use {1} to see your inventory",
|
||||
"BuyCommandAfterEnterBusiness": "Use {1} to buy items from a business",
|
||||
"UseItemKeyAfterEquipping": "Use {1} to use your equipped item",
|
||||
"UseItemKeyAfterEquippingWalkieTalkie": "Use {1} to turn on or off your radio",
|
||||
"RadioCommandAfterEnablingWalkieTalkie": "Use {1} to talk on your radio",
|
||||
"ReplyToDirectMessage": "Use {1} to easily reply to a private message",
|
||||
"UseItemKeyAmmoAfterEquippingWeapon": "Use {1} to load an ammo item into your equipped weapon",
|
||||
"AnimationStop": "Use {1} to stop your animation",
|
||||
"JobEquipmentInventory": "The job equipment is in your inventory. Use {1} to see them.",
|
||||
"ViewInventory": "Use {1} to see your items",
|
||||
"VehicleRepairItemUsage": "Stand next to a vehicle and use {1} to repair it",
|
||||
"VehicleColourItemUsage": "Stand next to a vehicle and use {1} to change it's colour",
|
||||
"VehiclePartItemUsage": "Stand next to a vehicle and use {1} to upgrade with {2}",
|
||||
"AmmoClipItemUsage": "Equip the weapon and use {1} to load ammo into it",
|
||||
"GenericItemUsage": "Use {1} to use the {2}",
|
||||
"EnterJobVehicleForRoute": "Enter a job vehicle nearby to start a job route",
|
||||
"JobLocations": "Visit a job location to get a job. Use {1} to find a job location",
|
||||
"JobRouteStart": "Use {1} to start a job route with this vehicle"
|
||||
},
|
||||
"DisconnectReasons": {
|
||||
"Unknown": "Unknown",
|
||||
"LostConnection": "Lost Connection",
|
||||
@@ -748,5 +723,60 @@
|
||||
"Cancel": "Cancel",
|
||||
"AlreadyOwnVehicle": "You already own this vehicle!",
|
||||
"PropertyEntranceFeeLabel": "Entrance Fee: {1}",
|
||||
"NeedToBeInJobVehicle": "You need to be in a job vehicle!"
|
||||
"NeedToBeInJobVehicle": "You need to be in a job vehicle!",
|
||||
"InvalidJobRank": "Job rank not found!",
|
||||
"PayPhoneRecipientAnswered": "Somebody answered the call. Use normal chat to talk to them.",
|
||||
"PayPhoneAnswered": "You answered the phone. Use normal chat to talk to the caller.",
|
||||
"PayPhoneRecipientHangup": "The line was disconnected. You have been charged {1}",
|
||||
"PayPhoneHangup": "You hung up the phone.",
|
||||
"AlreadyUsingPayPhone": "You are already using a payphone!",
|
||||
"NotUsingPayPhone": "You are not using a payphone!",
|
||||
"NoPayPhoneCloseEnough": "There is no payphone close enough!",
|
||||
"PayPhoneNotRinging": "This payphone is not ringing!",
|
||||
"PayPhoneOccupied": "This payphone is already being used by someone else!",
|
||||
"PayPhoneOccupantSwitched": "A different voice is now on the line",
|
||||
"PayPhoneGiven": "You gave the phone to {1}",
|
||||
"PayPhoneReceived": "{1} gave you the phone",
|
||||
"PayPhoneUnableToCallPlayer": "You can't call {1} at this time. Please try again later.",
|
||||
"ActionTips": {
|
||||
"VehicleEngineOffWhenEnteringKey": "Use {1} to turn on or off a vehicle's engine",
|
||||
"VehicleLockedAfterEntryAttempt": "Use {1} to lock or unlock a vehicle",
|
||||
"ShowItemsAfterPurchase": "Use {1} to see your inventory",
|
||||
"BuyCommandAfterEnterBusiness": "Use {1} to buy items from a business",
|
||||
"UseItemKeyAfterEquipping": "Use {1} to use your equipped item",
|
||||
"UseItemKeyAfterEquippingWalkieTalkie": "Use {1} to turn on or off your radio",
|
||||
"RadioCommandAfterEnablingWalkieTalkie": "Use {1} to talk on your radio",
|
||||
"ReplyToDirectMessage": "Use {1} to easily reply to a private message",
|
||||
"UseItemKeyAmmoAfterEquippingWeapon": "Use {1} to load an ammo item into your equipped weapon",
|
||||
"AnimationStop": "Use {1} to stop your animation",
|
||||
"JobEquipmentInventory": "The job equipment is in your inventory. Use {1} to see them.",
|
||||
"ViewInventory": "Use {1} to see your items",
|
||||
"VehicleRepairItemUsage": "Stand next to a vehicle and use {1} to repair it",
|
||||
"VehicleColourItemUsage": "Stand next to a vehicle and use {1} to change it's colour",
|
||||
"VehiclePartItemUsage": "Stand next to a vehicle and use {1} to upgrade with {2}",
|
||||
"AmmoClipItemUsage": "Equip the weapon and use {1} to load ammo into it",
|
||||
"GenericItemUsage": "Use {1} to use the {2}",
|
||||
"EnterJobVehicleForRoute": "Enter a job vehicle nearby to start a job route",
|
||||
"JobLocations": "Visit a job location to get a job. Use {1} to find a job location",
|
||||
"JobRouteStart": "Use {1} to start a job route with this vehicle",
|
||||
"PayPhoneFirstUse": "Use {1} to end the call, and {2} to give the phone to somebody nearby"
|
||||
},
|
||||
"NoBusinessesWithinRange": "There are no businesses within {1} meters",
|
||||
"NoHousesWithinRange": "There are no houses within {1} meters",
|
||||
"NoPayPhonesWithinRange": "There are no payphones within {1} meters",
|
||||
"HeaderBusinessesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderHousesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderPayPhonesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderCommandsForStaffFlagList": "Admin Commands ({1})",
|
||||
"PlayerLocateDistanceAndDirection": "{1} is {2} meters {3}",
|
||||
"MustBeNumber": "You need to use a number!",
|
||||
"HeaderJobRoutesList": "Job Routes ({1})",
|
||||
"HeaderJobRouteInfo": "Job Route Information (${1})",
|
||||
"InvalidJobRoute": "Job route not found!",
|
||||
"PayPhoneDeleted": "The payphone was deleted",
|
||||
"PayPhoneAnswer": "Use {1} to answer the payphone",
|
||||
"ResetActionTipsConfirm": "Are you sure you want to reset all seen action tips?",
|
||||
"ActionTipsReset": "All seen action tips have been reset.",
|
||||
"NormalChatDisabled": "Normal chat is disabled by server admin. Use chat commands instead.",
|
||||
"GlobalChatDisabled": "Global out-of-character chat is disabled by server admin"
|
||||
}
|
||||
@@ -16,12 +16,9 @@
|
||||
"InvalidAnimationDistance": "The distance must be between 0 and 3",
|
||||
"CantBanClient": "You cannot ban this person",
|
||||
"PlayerAccountBanned": "{1} has been account banned",
|
||||
"ClanNotFound": "Clan not found",
|
||||
"ClanNameTaken": "A clan with that name already exists",
|
||||
"PlayerNotFound": "Player not found",
|
||||
"ClanCantRemoveRanks": "You can't remove clan ranks",
|
||||
"ClanCantAddRanks": "You can't add clan ranks",
|
||||
"ClanRankNotFound": "Clan rank not found",
|
||||
"ClanCantChangeMemberTag": "You can not change clan member's tags",
|
||||
"ClanPlayerNotInSameClan": "That player is not in your clan",
|
||||
"ClanCantChangeRankLevel": "You can not change clan rank's level",
|
||||
@@ -653,28 +650,6 @@
|
||||
"LeftWrist": "Left Wrist",
|
||||
"RightWrist": "Right Wrist"
|
||||
},
|
||||
"ActionTips": {
|
||||
"VehicleEngineOffWhenEnteringKey": "Use {1} to turn on or off a vehicle's engine",
|
||||
"VehicleLockedAfterEntryAttempt": "Use {1} to lock or unlock a vehicle",
|
||||
"ShowItemsAfterPurchase": "Use {1} to see your inventory",
|
||||
"BuyCommandAfterEnterBusiness": "Use {1} to buy items from a business",
|
||||
"UseItemKeyAfterEquipping": "Use {1} to use your equipped item",
|
||||
"UseItemKeyAfterEquippingWalkieTalkie": "Use {1} to turn on or off your radio",
|
||||
"RadioCommandAfterEnablingWalkieTalkie": "Use {1} to talk on your radio",
|
||||
"ReplyToDirectMessage": "Use {1} to easily reply to a private message",
|
||||
"UseItemKeyAmmoAfterEquippingWeapon": "Use {1} to load an ammo item into your equipped weapon",
|
||||
"AnimationStop": "Use {1} to stop your animation",
|
||||
"JobEquipmentInventory": "The job equipment is in your inventory. Use {1} to see them.",
|
||||
"ViewInventory": "Use {1} to see your items",
|
||||
"VehicleRepairItemUsage": "Stand next to a vehicle and use {1} to repair it",
|
||||
"VehicleColourItemUsage": "Stand next to a vehicle and use {1} to change it's colour",
|
||||
"VehiclePartItemUsage": "Stand next to a vehicle and use {1} to upgrade with {2}",
|
||||
"AmmoClipItemUsage": "Equip the weapon and use {1} to load ammo into it",
|
||||
"GenericItemUsage": "Use {1} to use the {2}",
|
||||
"EnterJobVehicleForRoute": "Enter a job vehicle nearby to start a job route",
|
||||
"JobLocations": "Visit a job location to get a job. Use {1} to find a job location",
|
||||
"JobRouteStart": "Use {1} to start a job route with this vehicle"
|
||||
},
|
||||
"DisconnectReasons": {
|
||||
"Unknown": "Unknown",
|
||||
"LostConnection": "Lost Connection",
|
||||
@@ -750,5 +725,60 @@
|
||||
"Cancel": "Cancel",
|
||||
"AlreadyOwnVehicle": "You already own this vehicle!",
|
||||
"PropertyEntranceFeeLabel": "Entrance Fee: {1}",
|
||||
"NeedToBeInJobVehicle": "You need to be in a job vehicle!"
|
||||
"NeedToBeInJobVehicle": "You need to be in a job vehicle!",
|
||||
"InvalidJobRank": "Job rank not found!",
|
||||
"PayPhoneRecipientAnswered": "Somebody answered the call. Use normal chat to talk to them.",
|
||||
"PayPhoneAnswered": "You answered the phone. Use normal chat to talk to the caller.",
|
||||
"PayPhoneRecipientHangup": "The line was disconnected. You have been charged {1}",
|
||||
"PayPhoneHangup": "You hung up the phone.",
|
||||
"AlreadyUsingPayPhone": "You are already using a payphone!",
|
||||
"NotUsingPayPhone": "You are not using a payphone!",
|
||||
"NoPayPhoneCloseEnough": "There is no payphone close enough!",
|
||||
"PayPhoneNotRinging": "This payphone is not ringing!",
|
||||
"PayPhoneOccupied": "This payphone is already being used by someone else!",
|
||||
"PayPhoneOccupantSwitched": "A different voice is now on the line",
|
||||
"PayPhoneGiven": "You gave the phone to {1}",
|
||||
"PayPhoneReceived": "{1} gave you the phone",
|
||||
"PayPhoneUnableToCallPlayer": "You can't call {1} at this time. Please try again later.",
|
||||
"ActionTips": {
|
||||
"VehicleEngineOffWhenEnteringKey": "Use {1} to turn on or off a vehicle's engine",
|
||||
"VehicleLockedAfterEntryAttempt": "Use {1} to lock or unlock a vehicle",
|
||||
"ShowItemsAfterPurchase": "Use {1} to see your inventory",
|
||||
"BuyCommandAfterEnterBusiness": "Use {1} to buy items from a business",
|
||||
"UseItemKeyAfterEquipping": "Use {1} to use your equipped item",
|
||||
"UseItemKeyAfterEquippingWalkieTalkie": "Use {1} to turn on or off your radio",
|
||||
"RadioCommandAfterEnablingWalkieTalkie": "Use {1} to talk on your radio",
|
||||
"ReplyToDirectMessage": "Use {1} to easily reply to a private message",
|
||||
"UseItemKeyAmmoAfterEquippingWeapon": "Use {1} to load an ammo item into your equipped weapon",
|
||||
"AnimationStop": "Use {1} to stop your animation",
|
||||
"JobEquipmentInventory": "The job equipment is in your inventory. Use {1} to see them.",
|
||||
"ViewInventory": "Use {1} to see your items",
|
||||
"VehicleRepairItemUsage": "Stand next to a vehicle and use {1} to repair it",
|
||||
"VehicleColourItemUsage": "Stand next to a vehicle and use {1} to change it's colour",
|
||||
"VehiclePartItemUsage": "Stand next to a vehicle and use {1} to upgrade with {2}",
|
||||
"AmmoClipItemUsage": "Equip the weapon and use {1} to load ammo into it",
|
||||
"GenericItemUsage": "Use {1} to use the {2}",
|
||||
"EnterJobVehicleForRoute": "Enter a job vehicle nearby to start a job route",
|
||||
"JobLocations": "Visit a job location to get a job. Use {1} to find a job location",
|
||||
"JobRouteStart": "Use {1} to start a job route with this vehicle",
|
||||
"PayPhoneFirstUse": "Use {1} to end the call, and {2} to give the phone to somebody nearby"
|
||||
},
|
||||
"NoBusinessesWithinRange": "There are no businesses within {1} meters",
|
||||
"NoHousesWithinRange": "There are no houses within {1} meters",
|
||||
"NoPayPhonesWithinRange": "There are no payphones within {1} meters",
|
||||
"HeaderBusinessesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderHousesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderPayPhonesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderCommandsForStaffFlagList": "Admin Commands ({1})",
|
||||
"PlayerLocateDistanceAndDirection": "{1} is {2} meters {3}",
|
||||
"MustBeNumber": "You need to use a number!",
|
||||
"HeaderJobRoutesList": "Job Routes ({1})",
|
||||
"HeaderJobRouteInfo": "Job Route Information (${1})",
|
||||
"InvalidJobRoute": "Job route not found!",
|
||||
"PayPhoneDeleted": "The payphone was deleted",
|
||||
"PayPhoneAnswer": "Use {1} to answer the payphone",
|
||||
"ResetActionTipsConfirm": "Are you sure you want to reset all seen action tips?",
|
||||
"ActionTipsReset": "All seen action tips have been reset.",
|
||||
"NormalChatDisabled": "Normal chat is disabled by server admin. Use chat commands instead.",
|
||||
"GlobalChatDisabled": "Global out-of-character chat is disabled by server admin"
|
||||
}
|
||||
@@ -16,12 +16,9 @@
|
||||
"InvalidAnimationDistance": "The distance must be between 0 and 3",
|
||||
"CantBanClient": "You cannot ban this person",
|
||||
"PlayerAccountBanned": "{1} has been account banned",
|
||||
"ClanNotFound": "Clan not found",
|
||||
"ClanNameTaken": "A clan with that name already exists",
|
||||
"PlayerNotFound": "Player not found",
|
||||
"ClanCantRemoveRanks": "You can't remove clan ranks",
|
||||
"ClanCantAddRanks": "You can't add clan ranks",
|
||||
"ClanRankNotFound": "Clan rank not found",
|
||||
"ClanCantChangeMemberTag": "You can not change clan member's tags",
|
||||
"ClanPlayerNotInSameClan": "That player is not in your clan",
|
||||
"ClanCantChangeRankLevel": "You can not change clan rank's level",
|
||||
@@ -652,28 +649,6 @@
|
||||
"LeftWrist": "Left Wrist",
|
||||
"RightWrist": "Right Wrist"
|
||||
},
|
||||
"ActionTips": {
|
||||
"VehicleEngineOffWhenEnteringKey": "Use {1} to turn on or off a vehicle's engine",
|
||||
"VehicleLockedAfterEntryAttempt": "Use {1} to lock or unlock a vehicle",
|
||||
"ShowItemsAfterPurchase": "Use {1} to see your inventory",
|
||||
"BuyCommandAfterEnterBusiness": "Use {1} to buy items from a business",
|
||||
"UseItemKeyAfterEquipping": "Use {1} to use your equipped item",
|
||||
"UseItemKeyAfterEquippingWalkieTalkie": "Use {1} to turn on or off your radio",
|
||||
"RadioCommandAfterEnablingWalkieTalkie": "Use {1} to talk on your radio",
|
||||
"ReplyToDirectMessage": "Use {1} to easily reply to a private message",
|
||||
"UseItemKeyAmmoAfterEquippingWeapon": "Use {1} to load an ammo item into your equipped weapon",
|
||||
"AnimationStop": "Use {1} to stop your animation",
|
||||
"JobEquipmentInventory": "The job equipment is in your inventory. Use {1} to see them.",
|
||||
"ViewInventory": "Use {1} to see your items",
|
||||
"VehicleRepairItemUsage": "Stand next to a vehicle and use {1} to repair it",
|
||||
"VehicleColourItemUsage": "Stand next to a vehicle and use {1} to change it's colour",
|
||||
"VehiclePartItemUsage": "Stand next to a vehicle and use {1} to upgrade with {2}",
|
||||
"AmmoClipItemUsage": "Equip the weapon and use {1} to load ammo into it",
|
||||
"GenericItemUsage": "Use {1} to use the {2}",
|
||||
"EnterJobVehicleForRoute": "Enter a job vehicle nearby to start a job route",
|
||||
"JobLocations": "Visit a job location to get a job. Use {1} to find a job location",
|
||||
"JobRouteStart": "Use {1} to start a job route with this vehicle"
|
||||
},
|
||||
"DisconnectReasons": {
|
||||
"Unknown": "Unknown",
|
||||
"LostConnection": "Lost Connection",
|
||||
@@ -749,5 +724,60 @@
|
||||
"Cancel": "Cancel",
|
||||
"AlreadyOwnVehicle": "You already own this vehicle!",
|
||||
"PropertyEntranceFeeLabel": "Entrance Fee: {1}",
|
||||
"NeedToBeInJobVehicle": "You need to be in a job vehicle!"
|
||||
"NeedToBeInJobVehicle": "You need to be in a job vehicle!",
|
||||
"InvalidJobRank": "Job rank not found!",
|
||||
"PayPhoneRecipientAnswered": "Somebody answered the call. Use normal chat to talk to them.",
|
||||
"PayPhoneAnswered": "You answered the phone. Use normal chat to talk to the caller.",
|
||||
"PayPhoneRecipientHangup": "The line was disconnected. You have been charged {1}",
|
||||
"PayPhoneHangup": "You hung up the phone.",
|
||||
"AlreadyUsingPayPhone": "You are already using a payphone!",
|
||||
"NotUsingPayPhone": "You are not using a payphone!",
|
||||
"NoPayPhoneCloseEnough": "There is no payphone close enough!",
|
||||
"PayPhoneNotRinging": "This payphone is not ringing!",
|
||||
"PayPhoneOccupied": "This payphone is already being used by someone else!",
|
||||
"PayPhoneOccupantSwitched": "A different voice is now on the line",
|
||||
"PayPhoneGiven": "You gave the phone to {1}",
|
||||
"PayPhoneReceived": "{1} gave you the phone",
|
||||
"PayPhoneUnableToCallPlayer": "You can't call {1} at this time. Please try again later.",
|
||||
"ActionTips": {
|
||||
"VehicleEngineOffWhenEnteringKey": "Use {1} to turn on or off a vehicle's engine",
|
||||
"VehicleLockedAfterEntryAttempt": "Use {1} to lock or unlock a vehicle",
|
||||
"ShowItemsAfterPurchase": "Use {1} to see your inventory",
|
||||
"BuyCommandAfterEnterBusiness": "Use {1} to buy items from a business",
|
||||
"UseItemKeyAfterEquipping": "Use {1} to use your equipped item",
|
||||
"UseItemKeyAfterEquippingWalkieTalkie": "Use {1} to turn on or off your radio",
|
||||
"RadioCommandAfterEnablingWalkieTalkie": "Use {1} to talk on your radio",
|
||||
"ReplyToDirectMessage": "Use {1} to easily reply to a private message",
|
||||
"UseItemKeyAmmoAfterEquippingWeapon": "Use {1} to load an ammo item into your equipped weapon",
|
||||
"AnimationStop": "Use {1} to stop your animation",
|
||||
"JobEquipmentInventory": "The job equipment is in your inventory. Use {1} to see them.",
|
||||
"ViewInventory": "Use {1} to see your items",
|
||||
"VehicleRepairItemUsage": "Stand next to a vehicle and use {1} to repair it",
|
||||
"VehicleColourItemUsage": "Stand next to a vehicle and use {1} to change it's colour",
|
||||
"VehiclePartItemUsage": "Stand next to a vehicle and use {1} to upgrade with {2}",
|
||||
"AmmoClipItemUsage": "Equip the weapon and use {1} to load ammo into it",
|
||||
"GenericItemUsage": "Use {1} to use the {2}",
|
||||
"EnterJobVehicleForRoute": "Enter a job vehicle nearby to start a job route",
|
||||
"JobLocations": "Visit a job location to get a job. Use {1} to find a job location",
|
||||
"JobRouteStart": "Use {1} to start a job route with this vehicle",
|
||||
"PayPhoneFirstUse": "Use {1} to end the call, and {2} to give the phone to somebody nearby"
|
||||
},
|
||||
"NoBusinessesWithinRange": "There are no businesses within {1} meters",
|
||||
"NoHousesWithinRange": "There are no houses within {1} meters",
|
||||
"NoPayPhonesWithinRange": "There are no payphones within {1} meters",
|
||||
"HeaderBusinessesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderHousesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderPayPhonesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderCommandsForStaffFlagList": "Admin Commands ({1})",
|
||||
"PlayerLocateDistanceAndDirection": "{1} is {2} meters {3}",
|
||||
"MustBeNumber": "You need to use a number!",
|
||||
"HeaderJobRoutesList": "Job Routes ({1})",
|
||||
"HeaderJobRouteInfo": "Job Route Information (${1})",
|
||||
"InvalidJobRoute": "Job route not found!",
|
||||
"PayPhoneDeleted": "The payphone was deleted",
|
||||
"PayPhoneAnswer": "Use {1} to answer the payphone",
|
||||
"ResetActionTipsConfirm": "Are you sure you want to reset all seen action tips?",
|
||||
"ActionTipsReset": "All seen action tips have been reset.",
|
||||
"NormalChatDisabled": "Normal chat is disabled by server admin. Use chat commands instead.",
|
||||
"GlobalChatDisabled": "Global out-of-character chat is disabled by server admin"
|
||||
}
|
||||
|
||||
@@ -16,12 +16,9 @@
|
||||
"InvalidAnimationDistance": "The distance must be between 0 and 3",
|
||||
"CantBanClient": "You cannot ban this person",
|
||||
"PlayerAccountBanned": "{1} has been account banned",
|
||||
"ClanNotFound": "Clan not found",
|
||||
"ClanNameTaken": "A clan with that name already exists",
|
||||
"PlayerNotFound": "Player not found",
|
||||
"ClanCantRemoveRanks": "You can't remove clan ranks",
|
||||
"ClanCantAddRanks": "You can't add clan ranks",
|
||||
"ClanRankNotFound": "Clan rank not found",
|
||||
"ClanCantChangeMemberTag": "You can not change clan member's tags",
|
||||
"ClanPlayerNotInSameClan": "That player is not in your clan",
|
||||
"ClanCantChangeRankLevel": "You can not change clan rank's level",
|
||||
@@ -652,28 +649,6 @@
|
||||
"LeftWrist": "Left Wrist",
|
||||
"RightWrist": "Right Wrist"
|
||||
},
|
||||
"ActionTips": {
|
||||
"VehicleEngineOffWhenEnteringKey": "Use {1} to turn on or off a vehicle's engine",
|
||||
"VehicleLockedAfterEntryAttempt": "Use {1} to lock or unlock a vehicle",
|
||||
"ShowItemsAfterPurchase": "Use {1} to see your inventory",
|
||||
"BuyCommandAfterEnterBusiness": "Use {1} to buy items from a business",
|
||||
"UseItemKeyAfterEquipping": "Use {1} to use your equipped item",
|
||||
"UseItemKeyAfterEquippingWalkieTalkie": "Use {1} to turn on or off your radio",
|
||||
"RadioCommandAfterEnablingWalkieTalkie": "Use {1} to talk on your radio",
|
||||
"ReplyToDirectMessage": "Use {1} to easily reply to a private message",
|
||||
"UseItemKeyAmmoAfterEquippingWeapon": "Use {1} to load an ammo item into your equipped weapon",
|
||||
"AnimationStop": "Use {1} to stop your animation",
|
||||
"JobEquipmentInventory": "The job equipment is in your inventory. Use {1} to see them.",
|
||||
"ViewInventory": "Use {1} to see your items",
|
||||
"VehicleRepairItemUsage": "Stand next to a vehicle and use {1} to repair it",
|
||||
"VehicleColourItemUsage": "Stand next to a vehicle and use {1} to change it's colour",
|
||||
"VehiclePartItemUsage": "Stand next to a vehicle and use {1} to upgrade with {2}",
|
||||
"AmmoClipItemUsage": "Equip the weapon and use {1} to load ammo into it",
|
||||
"GenericItemUsage": "Use {1} to use the {2}",
|
||||
"EnterJobVehicleForRoute": "Enter a job vehicle nearby to start a job route",
|
||||
"JobLocations": "Visit a job location to get a job. Use {1} to find a job location",
|
||||
"JobRouteStart": "Use {1} to start a job route with this vehicle"
|
||||
},
|
||||
"DisconnectReasons": {
|
||||
"Unknown": "Unknown",
|
||||
"LostConnection": "Lost Connection",
|
||||
@@ -749,5 +724,60 @@
|
||||
"Cancel": "Cancel",
|
||||
"AlreadyOwnVehicle": "You already own this vehicle!",
|
||||
"PropertyEntranceFeeLabel": "Entrance Fee: {1}",
|
||||
"NeedToBeInJobVehicle": "You need to be in a job vehicle!"
|
||||
"NeedToBeInJobVehicle": "You need to be in a job vehicle!",
|
||||
"InvalidJobRank": "Job rank not found!",
|
||||
"PayPhoneRecipientAnswered": "Somebody answered the call. Use normal chat to talk to them.",
|
||||
"PayPhoneAnswered": "You answered the phone. Use normal chat to talk to the caller.",
|
||||
"PayPhoneRecipientHangup": "The line was disconnected. You have been charged {1}",
|
||||
"PayPhoneHangup": "You hung up the phone.",
|
||||
"AlreadyUsingPayPhone": "You are already using a payphone!",
|
||||
"NotUsingPayPhone": "You are not using a payphone!",
|
||||
"NoPayPhoneCloseEnough": "There is no payphone close enough!",
|
||||
"PayPhoneNotRinging": "This payphone is not ringing!",
|
||||
"PayPhoneOccupied": "This payphone is already being used by someone else!",
|
||||
"PayPhoneOccupantSwitched": "A different voice is now on the line",
|
||||
"PayPhoneGiven": "You gave the phone to {1}",
|
||||
"PayPhoneReceived": "{1} gave you the phone",
|
||||
"PayPhoneUnableToCallPlayer": "You can't call {1} at this time. Please try again later.",
|
||||
"ActionTips": {
|
||||
"VehicleEngineOffWhenEnteringKey": "Use {1} to turn on or off a vehicle's engine",
|
||||
"VehicleLockedAfterEntryAttempt": "Use {1} to lock or unlock a vehicle",
|
||||
"ShowItemsAfterPurchase": "Use {1} to see your inventory",
|
||||
"BuyCommandAfterEnterBusiness": "Use {1} to buy items from a business",
|
||||
"UseItemKeyAfterEquipping": "Use {1} to use your equipped item",
|
||||
"UseItemKeyAfterEquippingWalkieTalkie": "Use {1} to turn on or off your radio",
|
||||
"RadioCommandAfterEnablingWalkieTalkie": "Use {1} to talk on your radio",
|
||||
"ReplyToDirectMessage": "Use {1} to easily reply to a private message",
|
||||
"UseItemKeyAmmoAfterEquippingWeapon": "Use {1} to load an ammo item into your equipped weapon",
|
||||
"AnimationStop": "Use {1} to stop your animation",
|
||||
"JobEquipmentInventory": "The job equipment is in your inventory. Use {1} to see them.",
|
||||
"ViewInventory": "Use {1} to see your items",
|
||||
"VehicleRepairItemUsage": "Stand next to a vehicle and use {1} to repair it",
|
||||
"VehicleColourItemUsage": "Stand next to a vehicle and use {1} to change it's colour",
|
||||
"VehiclePartItemUsage": "Stand next to a vehicle and use {1} to upgrade with {2}",
|
||||
"AmmoClipItemUsage": "Equip the weapon and use {1} to load ammo into it",
|
||||
"GenericItemUsage": "Use {1} to use the {2}",
|
||||
"EnterJobVehicleForRoute": "Enter a job vehicle nearby to start a job route",
|
||||
"JobLocations": "Visit a job location to get a job. Use {1} to find a job location",
|
||||
"JobRouteStart": "Use {1} to start a job route with this vehicle",
|
||||
"PayPhoneFirstUse": "Use {1} to end the call, and {2} to give the phone to somebody nearby"
|
||||
},
|
||||
"NoBusinessesWithinRange": "There are no businesses within {1} meters",
|
||||
"NoHousesWithinRange": "There are no houses within {1} meters",
|
||||
"NoPayPhonesWithinRange": "There are no payphones within {1} meters",
|
||||
"HeaderBusinessesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderHousesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderPayPhonesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderCommandsForStaffFlagList": "Admin Commands ({1})",
|
||||
"PlayerLocateDistanceAndDirection": "{1} is {2} meters {3}",
|
||||
"MustBeNumber": "You need to use a number!",
|
||||
"HeaderJobRoutesList": "Job Routes ({1})",
|
||||
"HeaderJobRouteInfo": "Job Route Information (${1})",
|
||||
"InvalidJobRoute": "Job route not found!",
|
||||
"PayPhoneDeleted": "The payphone was deleted",
|
||||
"PayPhoneAnswer": "Use {1} to answer the payphone",
|
||||
"ResetActionTipsConfirm": "Are you sure you want to reset all seen action tips?",
|
||||
"ActionTipsReset": "All seen action tips have been reset.",
|
||||
"NormalChatDisabled": "Normal chat is disabled by server admin. Use chat commands instead.",
|
||||
"GlobalChatDisabled": "Global out-of-character chat is disabled by server admin"
|
||||
}
|
||||
@@ -15,12 +15,9 @@
|
||||
"AnimationInvalidDistance": "Dystans musi być między 0 i 3",
|
||||
"CantBanClient": "Nie możesz zbanować tej osoby",
|
||||
"PlayerAccountBanned": "{1} został zbanowany",
|
||||
"ClanNotFound": "Nie znaleziono klanu",
|
||||
"ClanNameTaken": "Klan z taką nazwą już istnieje",
|
||||
"PlayerNotFound": "Nie znaleziono gracza",
|
||||
"ClanCantRemoveRanks": "Nie możesz usuwać rang klanu",
|
||||
"ClanCantAddRanks": "Nie możesz dodawać rang klanu",
|
||||
"ClanRankNotFound": "Nie znaleziono rangi klanu",
|
||||
"ClanCantChangeMemberTag": "Nie możesz zmienić tagu członka klanu",
|
||||
"ClanPlayerNotInSameClan": "Ten gracz nie jest w twoim klanie",
|
||||
"ClanCantChangeRankLevel": "Nie możesz zmienić poziomu rangi klanu",
|
||||
@@ -650,28 +647,6 @@
|
||||
"LeftWrist": "Lewy Nadgarstek",
|
||||
"RightWrist": "Prawy Nadgarstek"
|
||||
},
|
||||
"ActionTips": {
|
||||
"VehicleEngineOffWhenEnteringKey": "Użyj {1} aby włączyć/wyłączyć silnik pojazdu",
|
||||
"VehicleLockedAfterEntryAttempt": "Użyj {1} aby otworzyć/zamknąć pojazd",
|
||||
"ShowItemsAfterPurchase": "Użyj {1} aby zobaczyć swoje inventory",
|
||||
"BuyCommandAfterEnterBusiness": "Użyj {1} aby kupić przedmioty od biznesu",
|
||||
"UseItemKeyAfterEquipping": "Użyj {1} aby użyć wyjęty przedmiot",
|
||||
"UseItemKeyAfterEquippingWalkieTalkie": "Użyj {1} aby włączyć/wyłączyć radio",
|
||||
"RadioCommandAfterEnablingWalkieTalkie": "Użyj {1} aby użyć radia",
|
||||
"ReplyToDirectMessage": "Użyj {1} aby odpowiedzieć na prywatną wiadomość",
|
||||
"UseItemKeyAmmoAfterEquippingWeapon": "Użyj {1} aby załadować amunicje do wyjętej broni",
|
||||
"AnimationStop": "Użyj {1} aby zatrzymać swoją animacje",
|
||||
"JobEquipmentInventory": "Sprzęt do pracy jest w twoim inventory. Użyj {1} aby go zobaczyć.",
|
||||
"ViewInventory": "Użyj {1} aby zobaczyć swoje przedmioty",
|
||||
"VehicleRepairItemUsage": "Stań obok pojazdu i użyj {1} aby go naprawić",
|
||||
"VehicleColourItemUsage": "Stań obok pojazdu i użyj {1} aby zmienić jego kolor",
|
||||
"VehiclePartItemUsage": "Stań obok pojazdu i użyj {1} aby ulepszyć go z {2}",
|
||||
"AmmoClipItemUsage": "Wyjmnij broń i użyj {1} aby załadować amunicje",
|
||||
"GenericItemUsage": "Użyj {1} aby użyć {2}",
|
||||
"EnterJobVehicleForRoute": "Wejdź do pobliskiego pojazdu służbowego aby rozpocząć trasę",
|
||||
"JobLocations": "Odwiedź zakład pracy aby zdobyć pracę. Użyj {1} aby znaleźć zakład pracy",
|
||||
"JobRouteStart": "Użyj {1} aby rozpocząć trasę z tym pojazdem"
|
||||
},
|
||||
"DisconnectReasons": {
|
||||
"Unknown": "Nieznane",
|
||||
"LostConnection": "Stracono Połączenie",
|
||||
@@ -747,5 +722,60 @@
|
||||
"Cancel": "Anuluj",
|
||||
"AlreadyOwnVehicle": "Już posiadasz ten pojazd!",
|
||||
"PropertyEntranceFeeLabel": "Opłata wejściowa: {1}",
|
||||
"NeedToBeInJobVehicle": "Musisz być w firmowym pojeździe!"
|
||||
"NeedToBeInJobVehicle": "Musisz być w firmowym pojeździe!",
|
||||
"InvalidJobRank": "Job rank not found!",
|
||||
"PayPhoneRecipientAnswered": "Somebody answered the call. Use normal chat to talk to them.",
|
||||
"PayPhoneAnswered": "You answered the phone. Use normal chat to talk to the caller.",
|
||||
"PayPhoneRecipientHangup": "The line was disconnected. You have been charged {1}",
|
||||
"PayPhoneHangup": "You hung up the phone.",
|
||||
"AlreadyUsingPayPhone": "You are already using a payphone!",
|
||||
"NotUsingPayPhone": "You are not using a payphone!",
|
||||
"NoPayPhoneCloseEnough": "There is no payphone close enough!",
|
||||
"PayPhoneNotRinging": "This payphone is not ringing!",
|
||||
"PayPhoneOccupied": "This payphone is already being used by someone else!",
|
||||
"PayPhoneOccupantSwitched": "A different voice is now on the line",
|
||||
"PayPhoneGiven": "You gave the phone to {1}",
|
||||
"PayPhoneReceived": "{1} gave you the phone",
|
||||
"PayPhoneUnableToCallPlayer": "You can't call {1} at this time. Please try again later.",
|
||||
"ActionTips": {
|
||||
"VehicleEngineOffWhenEnteringKey": "Użyj {1} aby włączyć/wyłączyć silnik pojazdu",
|
||||
"VehicleLockedAfterEntryAttempt": "Użyj {1} aby otworzyć/zamknąć pojazd",
|
||||
"ShowItemsAfterPurchase": "Użyj {1} aby zobaczyć swoje inventory",
|
||||
"BuyCommandAfterEnterBusiness": "Użyj {1} aby kupić przedmioty od biznesu",
|
||||
"UseItemKeyAfterEquipping": "Użyj {1} aby użyć wyjęty przedmiot",
|
||||
"UseItemKeyAfterEquippingWalkieTalkie": "Użyj {1} aby włączyć/wyłączyć radio",
|
||||
"RadioCommandAfterEnablingWalkieTalkie": "Użyj {1} aby użyć radia",
|
||||
"ReplyToDirectMessage": "Użyj {1} aby odpowiedzieć na prywatną wiadomość",
|
||||
"UseItemKeyAmmoAfterEquippingWeapon": "Użyj {1} aby załadować amunicje do wyjętej broni",
|
||||
"AnimationStop": "Użyj {1} aby zatrzymać swoją animacje",
|
||||
"JobEquipmentInventory": "Sprzęt do pracy jest w twoim inventory. Użyj {1} aby go zobaczyć.",
|
||||
"ViewInventory": "Użyj {1} aby zobaczyć swoje przedmioty",
|
||||
"VehicleRepairItemUsage": "Stań obok pojazdu i użyj {1} aby go naprawić",
|
||||
"VehicleColourItemUsage": "Stań obok pojazdu i użyj {1} aby zmienić jego kolor",
|
||||
"VehiclePartItemUsage": "Stań obok pojazdu i użyj {1} aby ulepszyć go z {2}",
|
||||
"AmmoClipItemUsage": "Wyjmnij broń i użyj {1} aby załadować amunicje",
|
||||
"GenericItemUsage": "Użyj {1} aby użyć {2}",
|
||||
"EnterJobVehicleForRoute": "Wejdź do pobliskiego pojazdu służbowego aby rozpocząć trasę",
|
||||
"JobLocations": "Odwiedź zakład pracy aby zdobyć pracę. Użyj {1} aby znaleźć zakład pracy",
|
||||
"JobRouteStart": "Użyj {1} aby rozpocząć trasę z tym pojazdem",
|
||||
"PayPhoneFirstUse": "Use {1} to end the call, and {2} to give the phone to somebody nearby"
|
||||
},
|
||||
"NoBusinessesWithinRange": "There are no businesses within {1} meters",
|
||||
"NoHousesWithinRange": "There are no houses within {1} meters",
|
||||
"NoPayPhonesWithinRange": "There are no payphones within {1} meters",
|
||||
"HeaderBusinessesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderHousesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderPayPhonesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderCommandsForStaffFlagList": "Admin Commands ({1})",
|
||||
"PlayerLocateDistanceAndDirection": "{1} is {2} meters {3}",
|
||||
"MustBeNumber": "You need to use a number!",
|
||||
"HeaderJobRoutesList": "Job Routes ({1})",
|
||||
"HeaderJobRouteInfo": "Job Route Information (${1})",
|
||||
"InvalidJobRoute": "Job route not found!",
|
||||
"PayPhoneDeleted": "The payphone was deleted",
|
||||
"PayPhoneAnswer": "Use {1} to answer the payphone",
|
||||
"ResetActionTipsConfirm": "Are you sure you want to reset all seen action tips?",
|
||||
"ActionTipsReset": "All seen action tips have been reset.",
|
||||
"NormalChatDisabled": "Normal chat is disabled by server admin. Use chat commands instead.",
|
||||
"GlobalChatDisabled": "Global out-of-character chat is disabled by server admin"
|
||||
}
|
||||
|
||||
@@ -16,12 +16,9 @@
|
||||
"InvalidAnimationDistance": "Дистанция должна быть между 0 и 3",
|
||||
"CantBanClient": "Вы не можете забанить этого игрока",
|
||||
"PlayerAccountBanned": "Аккаунт {1} был заблокирован ",
|
||||
"ClanNotFound": "Не удалось найти клан",
|
||||
"ClanNameTaken": "Клан с таким именем уже существует",
|
||||
"PlayerNotFound": "Не удалось найти игрока",
|
||||
"ClanCantRemoveRanks": "Вы не можете убрать ранги клана",
|
||||
"ClanCantAddRanks": "Вы не можете добавить новые ранги клана",
|
||||
"ClanRankNotFound": "Не удалось найти ранг клана",
|
||||
"ClanCantChangeMemberTag": "Вы не можете изменить теги членов клана",
|
||||
"ClanPlayerNotInSameClan": "Игрок не в вашем клане",
|
||||
"ClanCantChangeRankLevel": "Вы не можете изменить уровень ранга клана",
|
||||
@@ -651,28 +648,6 @@
|
||||
"LeftWrist": "Left Wrist",
|
||||
"RightWrist": "Right Wrist"
|
||||
},
|
||||
"ActionTips": {
|
||||
"VehicleEngineOffWhenEnteringKey": "Use {1} to turn on or off a vehicle's engine",
|
||||
"VehicleLockedAfterEntryAttempt": "Use {1} to lock or unlock a vehicle",
|
||||
"ShowItemsAfterPurchase": "Use {1} to see your inventory",
|
||||
"BuyCommandAfterEnterBusiness": "Use {1} to buy items from a business",
|
||||
"UseItemKeyAfterEquipping": "Use {1} to use your equipped item",
|
||||
"UseItemKeyAfterEquippingWalkieTalkie": "Use {1} to turn on or off your radio",
|
||||
"RadioCommandAfterEnablingWalkieTalkie": "Use {1} to talk on your radio",
|
||||
"ReplyToDirectMessage": "Use {1} to easily reply to a private message",
|
||||
"UseItemKeyAmmoAfterEquippingWeapon": "Use {1} to load an ammo item into your equipped weapon",
|
||||
"AnimationStop": "Use {1} to stop your animation",
|
||||
"JobEquipmentInventory": "The job equipment is in your inventory. Use {1} to see them.",
|
||||
"ViewInventory": "Use {1} to see your items",
|
||||
"VehicleRepairItemUsage": "Stand next to a vehicle and use {1} to repair it",
|
||||
"VehicleColourItemUsage": "Stand next to a vehicle and use {1} to change it's colour",
|
||||
"VehiclePartItemUsage": "Stand next to a vehicle and use {1} to upgrade with {2}",
|
||||
"AmmoClipItemUsage": "Equip the weapon and use {1} to load ammo into it",
|
||||
"GenericItemUsage": "Use {1} to use the {2}",
|
||||
"EnterJobVehicleForRoute": "Enter a job vehicle nearby to start a job route",
|
||||
"JobLocations": "Visit a job location to get a job. Use {1} to find a job location",
|
||||
"JobRouteStart": "Use {1} to start a job route with this vehicle"
|
||||
},
|
||||
"DisconnectReasons": {
|
||||
"Unknown": "Unknown",
|
||||
"LostConnection": "Lost Connection",
|
||||
@@ -748,5 +723,60 @@
|
||||
"Cancel": "Cancel",
|
||||
"AlreadyOwnVehicle": "You already own this vehicle!",
|
||||
"PropertyEntranceFeeLabel": "Entrance Fee: {1}",
|
||||
"NeedToBeInJobVehicle": "You need to be in a job vehicle!"
|
||||
"NeedToBeInJobVehicle": "You need to be in a job vehicle!",
|
||||
"InvalidJobRank": "Job rank not found!",
|
||||
"PayPhoneRecipientAnswered": "Somebody answered the call. Use normal chat to talk to them.",
|
||||
"PayPhoneAnswered": "You answered the phone. Use normal chat to talk to the caller.",
|
||||
"PayPhoneRecipientHangup": "The line was disconnected. You have been charged {1}",
|
||||
"PayPhoneHangup": "You hung up the phone.",
|
||||
"AlreadyUsingPayPhone": "You are already using a payphone!",
|
||||
"NotUsingPayPhone": "You are not using a payphone!",
|
||||
"NoPayPhoneCloseEnough": "There is no payphone close enough!",
|
||||
"PayPhoneNotRinging": "This payphone is not ringing!",
|
||||
"PayPhoneOccupied": "This payphone is already being used by someone else!",
|
||||
"PayPhoneOccupantSwitched": "A different voice is now on the line",
|
||||
"PayPhoneGiven": "You gave the phone to {1}",
|
||||
"PayPhoneReceived": "{1} gave you the phone",
|
||||
"PayPhoneUnableToCallPlayer": "You can't call {1} at this time. Please try again later.",
|
||||
"ActionTips": {
|
||||
"VehicleEngineOffWhenEnteringKey": "Use {1} to turn on or off a vehicle's engine",
|
||||
"VehicleLockedAfterEntryAttempt": "Use {1} to lock or unlock a vehicle",
|
||||
"ShowItemsAfterPurchase": "Use {1} to see your inventory",
|
||||
"BuyCommandAfterEnterBusiness": "Use {1} to buy items from a business",
|
||||
"UseItemKeyAfterEquipping": "Use {1} to use your equipped item",
|
||||
"UseItemKeyAfterEquippingWalkieTalkie": "Use {1} to turn on or off your radio",
|
||||
"RadioCommandAfterEnablingWalkieTalkie": "Use {1} to talk on your radio",
|
||||
"ReplyToDirectMessage": "Use {1} to easily reply to a private message",
|
||||
"UseItemKeyAmmoAfterEquippingWeapon": "Use {1} to load an ammo item into your equipped weapon",
|
||||
"AnimationStop": "Use {1} to stop your animation",
|
||||
"JobEquipmentInventory": "The job equipment is in your inventory. Use {1} to see them.",
|
||||
"ViewInventory": "Use {1} to see your items",
|
||||
"VehicleRepairItemUsage": "Stand next to a vehicle and use {1} to repair it",
|
||||
"VehicleColourItemUsage": "Stand next to a vehicle and use {1} to change it's colour",
|
||||
"VehiclePartItemUsage": "Stand next to a vehicle and use {1} to upgrade with {2}",
|
||||
"AmmoClipItemUsage": "Equip the weapon and use {1} to load ammo into it",
|
||||
"GenericItemUsage": "Use {1} to use the {2}",
|
||||
"EnterJobVehicleForRoute": "Enter a job vehicle nearby to start a job route",
|
||||
"JobLocations": "Visit a job location to get a job. Use {1} to find a job location",
|
||||
"JobRouteStart": "Use {1} to start a job route with this vehicle",
|
||||
"PayPhoneFirstUse": "Use {1} to end the call, and {2} to give the phone to somebody nearby"
|
||||
},
|
||||
"NoBusinessesWithinRange": "There are no businesses within {1} meters",
|
||||
"NoHousesWithinRange": "There are no houses within {1} meters",
|
||||
"NoPayPhonesWithinRange": "There are no payphones within {1} meters",
|
||||
"HeaderBusinessesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderHousesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderPayPhonesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderCommandsForStaffFlagList": "Admin Commands ({1})",
|
||||
"PlayerLocateDistanceAndDirection": "{1} is {2} meters {3}",
|
||||
"MustBeNumber": "You need to use a number!",
|
||||
"HeaderJobRoutesList": "Job Routes ({1})",
|
||||
"HeaderJobRouteInfo": "Job Route Information (${1})",
|
||||
"InvalidJobRoute": "Job route not found!",
|
||||
"PayPhoneDeleted": "The payphone was deleted",
|
||||
"PayPhoneAnswer": "Use {1} to answer the payphone",
|
||||
"ResetActionTipsConfirm": "Are you sure you want to reset all seen action tips?",
|
||||
"ActionTipsReset": "All seen action tips have been reset.",
|
||||
"NormalChatDisabled": "Normal chat is disabled by server admin. Use chat commands instead.",
|
||||
"GlobalChatDisabled": "Global out-of-character chat is disabled by server admin"
|
||||
}
|
||||
|
||||
@@ -16,12 +16,9 @@
|
||||
"InvalidAnimationDistance": "The distance must be between 0 and 3",
|
||||
"CantBanClient": "You cannot ban this person",
|
||||
"PlayerAccountBanned": "{1} has been account banned",
|
||||
"ClanNotFound": "Clan not found",
|
||||
"ClanNameTaken": "A clan with that name already exists",
|
||||
"PlayerNotFound": "Player not found",
|
||||
"ClanCantRemoveRanks": "You can't remove clan ranks",
|
||||
"ClanCantAddRanks": "You can't add clan ranks",
|
||||
"ClanRankNotFound": "Clan rank not found",
|
||||
"ClanCantChangeMemberTag": "You can not change clan member's tags",
|
||||
"ClanPlayerNotInSameClan": "That player is not in your clan",
|
||||
"ClanCantChangeRankLevel": "You can not change clan rank's level",
|
||||
@@ -651,28 +648,6 @@
|
||||
"LeftWrist": "Left Wrist",
|
||||
"RightWrist": "Right Wrist"
|
||||
},
|
||||
"ActionTips": {
|
||||
"VehicleEngineOffWhenEnteringKey": "Use {1} to turn on or off a vehicle's engine",
|
||||
"VehicleLockedAfterEntryAttempt": "Use {1} to lock or unlock a vehicle",
|
||||
"ShowItemsAfterPurchase": "Use {1} to see your inventory",
|
||||
"BuyCommandAfterEnterBusiness": "Use {1} to buy items from a business",
|
||||
"UseItemKeyAfterEquipping": "Use {1} to use your equipped item",
|
||||
"UseItemKeyAfterEquippingWalkieTalkie": "Use {1} to turn on or off your radio",
|
||||
"RadioCommandAfterEnablingWalkieTalkie": "Use {1} to talk on your radio",
|
||||
"ReplyToDirectMessage": "Use {1} to easily reply to a private message",
|
||||
"UseItemKeyAmmoAfterEquippingWeapon": "Use {1} to load an ammo item into your equipped weapon",
|
||||
"AnimationStop": "Use {1} to stop your animation",
|
||||
"JobEquipmentInventory": "The job equipment is in your inventory. Use {1} to see them.",
|
||||
"ViewInventory": "Use {1} to see your items",
|
||||
"VehicleRepairItemUsage": "Stand next to a vehicle and use {1} to repair it",
|
||||
"VehicleColourItemUsage": "Stand next to a vehicle and use {1} to change it's colour",
|
||||
"VehiclePartItemUsage": "Stand next to a vehicle and use {1} to upgrade with {2}",
|
||||
"AmmoClipItemUsage": "Equip the weapon and use {1} to load ammo into it",
|
||||
"GenericItemUsage": "Use {1} to use the {2}",
|
||||
"EnterJobVehicleForRoute": "Enter a job vehicle nearby to start a job route",
|
||||
"JobLocations": "Visit a job location to get a job. Use {1} to find a job location",
|
||||
"JobRouteStart": "Use {1} to start a job route with this vehicle"
|
||||
},
|
||||
"DisconnectReasons": {
|
||||
"Unknown": "Unknown",
|
||||
"LostConnection": "Lost Connection",
|
||||
@@ -748,5 +723,60 @@
|
||||
"Cancel": "Cancel",
|
||||
"AlreadyOwnVehicle": "You already own this vehicle!",
|
||||
"PropertyEntranceFeeLabel": "Entrance Fee: {1}",
|
||||
"NeedToBeInJobVehicle": "You need to be in a job vehicle!"
|
||||
"NeedToBeInJobVehicle": "You need to be in a job vehicle!",
|
||||
"InvalidJobRank": "Job rank not found!",
|
||||
"PayPhoneRecipientAnswered": "Somebody answered the call. Use normal chat to talk to them.",
|
||||
"PayPhoneAnswered": "You answered the phone. Use normal chat to talk to the caller.",
|
||||
"PayPhoneRecipientHangup": "The line was disconnected. You have been charged {1}",
|
||||
"PayPhoneHangup": "You hung up the phone.",
|
||||
"AlreadyUsingPayPhone": "You are already using a payphone!",
|
||||
"NotUsingPayPhone": "You are not using a payphone!",
|
||||
"NoPayPhoneCloseEnough": "There is no payphone close enough!",
|
||||
"PayPhoneNotRinging": "This payphone is not ringing!",
|
||||
"PayPhoneOccupied": "This payphone is already being used by someone else!",
|
||||
"PayPhoneOccupantSwitched": "A different voice is now on the line",
|
||||
"PayPhoneGiven": "You gave the phone to {1}",
|
||||
"PayPhoneReceived": "{1} gave you the phone",
|
||||
"PayPhoneUnableToCallPlayer": "You can't call {1} at this time. Please try again later.",
|
||||
"ActionTips": {
|
||||
"VehicleEngineOffWhenEnteringKey": "Use {1} to turn on or off a vehicle's engine",
|
||||
"VehicleLockedAfterEntryAttempt": "Use {1} to lock or unlock a vehicle",
|
||||
"ShowItemsAfterPurchase": "Use {1} to see your inventory",
|
||||
"BuyCommandAfterEnterBusiness": "Use {1} to buy items from a business",
|
||||
"UseItemKeyAfterEquipping": "Use {1} to use your equipped item",
|
||||
"UseItemKeyAfterEquippingWalkieTalkie": "Use {1} to turn on or off your radio",
|
||||
"RadioCommandAfterEnablingWalkieTalkie": "Use {1} to talk on your radio",
|
||||
"ReplyToDirectMessage": "Use {1} to easily reply to a private message",
|
||||
"UseItemKeyAmmoAfterEquippingWeapon": "Use {1} to load an ammo item into your equipped weapon",
|
||||
"AnimationStop": "Use {1} to stop your animation",
|
||||
"JobEquipmentInventory": "The job equipment is in your inventory. Use {1} to see them.",
|
||||
"ViewInventory": "Use {1} to see your items",
|
||||
"VehicleRepairItemUsage": "Stand next to a vehicle and use {1} to repair it",
|
||||
"VehicleColourItemUsage": "Stand next to a vehicle and use {1} to change it's colour",
|
||||
"VehiclePartItemUsage": "Stand next to a vehicle and use {1} to upgrade with {2}",
|
||||
"AmmoClipItemUsage": "Equip the weapon and use {1} to load ammo into it",
|
||||
"GenericItemUsage": "Use {1} to use the {2}",
|
||||
"EnterJobVehicleForRoute": "Enter a job vehicle nearby to start a job route",
|
||||
"JobLocations": "Visit a job location to get a job. Use {1} to find a job location",
|
||||
"JobRouteStart": "Use {1} to start a job route with this vehicle",
|
||||
"PayPhoneFirstUse": "Use {1} to end the call, and {2} to give the phone to somebody nearby"
|
||||
},
|
||||
"NoBusinessesWithinRange": "There are no businesses within {1} meters",
|
||||
"NoHousesWithinRange": "There are no houses within {1} meters",
|
||||
"NoPayPhonesWithinRange": "There are no payphones within {1} meters",
|
||||
"HeaderBusinessesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderHousesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderPayPhonesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderCommandsForStaffFlagList": "Admin Commands ({1})",
|
||||
"PlayerLocateDistanceAndDirection": "{1} is {2} meters {3}",
|
||||
"MustBeNumber": "You need to use a number!",
|
||||
"HeaderJobRoutesList": "Job Routes ({1})",
|
||||
"HeaderJobRouteInfo": "Job Route Information (${1})",
|
||||
"InvalidJobRoute": "Job route not found!",
|
||||
"PayPhoneDeleted": "The payphone was deleted",
|
||||
"PayPhoneAnswer": "Use {1} to answer the payphone",
|
||||
"ResetActionTipsConfirm": "Are you sure you want to reset all seen action tips?",
|
||||
"ActionTipsReset": "All seen action tips have been reset.",
|
||||
"NormalChatDisabled": "Normal chat is disabled by server admin. Use chat commands instead.",
|
||||
"GlobalChatDisabled": "Global out-of-character chat is disabled by server admin"
|
||||
}
|
||||
@@ -22,12 +22,9 @@
|
||||
"InvalidAnimationDistance": "La distancia debe ser un numero entre el 0 y el 3",
|
||||
"CantBanClient": "No se puede vetar a esta persona",
|
||||
"PlayerAccountBanned": "La cuenta de {1} ha sido vetada",
|
||||
"ClanNotFound": "Clan no encontrado",
|
||||
"ClanNameTaken": "Ya existe un clan con ese nombre",
|
||||
"PlayerNotFound": "Jugador no encontrado",
|
||||
"ClanCantRemoveRanks": "No puedes eliminar rangos del clan",
|
||||
"ClanCantAddRanks": "No puedes añadir rangos del clan",
|
||||
"ClanRankNotFound": "No se encontró el rango del clan indicado",
|
||||
"ClanCantChangeMemberTag": "No puedes cambiar las etiquetas del miembro del clan",
|
||||
"ClanPlayerNotInSameClan": "El jugador indicado no está en tu clan",
|
||||
"ClanCantChangeRankLevel": "No puedes cambiar el nivel del rango del clan",
|
||||
@@ -657,28 +654,6 @@
|
||||
"LeftWrist": "Left Wrist",
|
||||
"RightWrist": "Right Wrist"
|
||||
},
|
||||
"ActionTips": {
|
||||
"VehicleEngineOffWhenEnteringKey": "Use {1} to turn on or off a vehicle's engine",
|
||||
"VehicleLockedAfterEntryAttempt": "Use {1} to lock or unlock a vehicle",
|
||||
"ShowItemsAfterPurchase": "Use {1} to see your inventory",
|
||||
"BuyCommandAfterEnterBusiness": "Use {1} to buy items from a business",
|
||||
"UseItemKeyAfterEquipping": "Use {1} to use your equipped item",
|
||||
"UseItemKeyAfterEquippingWalkieTalkie": "Use {1} to turn on or off your radio",
|
||||
"RadioCommandAfterEnablingWalkieTalkie": "Use {1} to talk on your radio",
|
||||
"ReplyToDirectMessage": "Use {1} to easily reply to a private message",
|
||||
"UseItemKeyAmmoAfterEquippingWeapon": "Use {1} to load an ammo item into your equipped weapon",
|
||||
"AnimationStop": "Use {1} to stop your animation",
|
||||
"JobEquipmentInventory": "The job equipment is in your inventory. Use {1} to see them.",
|
||||
"ViewInventory": "Use {1} to see your items",
|
||||
"VehicleRepairItemUsage": "Stand next to a vehicle and use {1} to repair it",
|
||||
"VehicleColourItemUsage": "Stand next to a vehicle and use {1} to change it's colour",
|
||||
"VehiclePartItemUsage": "Stand next to a vehicle and use {1} to upgrade with {2}",
|
||||
"AmmoClipItemUsage": "Equip the weapon and use {1} to load ammo into it",
|
||||
"GenericItemUsage": "Use {1} to use the {2}",
|
||||
"EnterJobVehicleForRoute": "Enter a job vehicle nearby to start a job route",
|
||||
"JobLocations": "Visit a job location to get a job. Use {1} to find a job location",
|
||||
"JobRouteStart": "Use {1} to start a job route with this vehicle"
|
||||
},
|
||||
"DisconnectReasons": {
|
||||
"Unknown": "Unknown",
|
||||
"LostConnection": "Lost Connection",
|
||||
@@ -754,5 +729,60 @@
|
||||
"Cancel": "Cancel",
|
||||
"AlreadyOwnVehicle": "You already own this vehicle!",
|
||||
"PropertyEntranceFeeLabel": "Entrance Fee: {1}",
|
||||
"NeedToBeInJobVehicle": "You need to be in a job vehicle!"
|
||||
"NeedToBeInJobVehicle": "You need to be in a job vehicle!",
|
||||
"InvalidJobRank": "Job rank not found!",
|
||||
"PayPhoneRecipientAnswered": "Somebody answered the call. Use normal chat to talk to them.",
|
||||
"PayPhoneAnswered": "You answered the phone. Use normal chat to talk to the caller.",
|
||||
"PayPhoneRecipientHangup": "The line was disconnected. You have been charged {1}",
|
||||
"PayPhoneHangup": "You hung up the phone.",
|
||||
"AlreadyUsingPayPhone": "You are already using a payphone!",
|
||||
"NotUsingPayPhone": "You are not using a payphone!",
|
||||
"NoPayPhoneCloseEnough": "There is no payphone close enough!",
|
||||
"PayPhoneNotRinging": "This payphone is not ringing!",
|
||||
"PayPhoneOccupied": "This payphone is already being used by someone else!",
|
||||
"PayPhoneOccupantSwitched": "A different voice is now on the line",
|
||||
"PayPhoneGiven": "You gave the phone to {1}",
|
||||
"PayPhoneReceived": "{1} gave you the phone",
|
||||
"PayPhoneUnableToCallPlayer": "You can't call {1} at this time. Please try again later.",
|
||||
"ActionTips": {
|
||||
"VehicleEngineOffWhenEnteringKey": "Use {1} to turn on or off a vehicle's engine",
|
||||
"VehicleLockedAfterEntryAttempt": "Use {1} to lock or unlock a vehicle",
|
||||
"ShowItemsAfterPurchase": "Use {1} to see your inventory",
|
||||
"BuyCommandAfterEnterBusiness": "Use {1} to buy items from a business",
|
||||
"UseItemKeyAfterEquipping": "Use {1} to use your equipped item",
|
||||
"UseItemKeyAfterEquippingWalkieTalkie": "Use {1} to turn on or off your radio",
|
||||
"RadioCommandAfterEnablingWalkieTalkie": "Use {1} to talk on your radio",
|
||||
"ReplyToDirectMessage": "Use {1} to easily reply to a private message",
|
||||
"UseItemKeyAmmoAfterEquippingWeapon": "Use {1} to load an ammo item into your equipped weapon",
|
||||
"AnimationStop": "Use {1} to stop your animation",
|
||||
"JobEquipmentInventory": "The job equipment is in your inventory. Use {1} to see them.",
|
||||
"ViewInventory": "Use {1} to see your items",
|
||||
"VehicleRepairItemUsage": "Stand next to a vehicle and use {1} to repair it",
|
||||
"VehicleColourItemUsage": "Stand next to a vehicle and use {1} to change it's colour",
|
||||
"VehiclePartItemUsage": "Stand next to a vehicle and use {1} to upgrade with {2}",
|
||||
"AmmoClipItemUsage": "Equip the weapon and use {1} to load ammo into it",
|
||||
"GenericItemUsage": "Use {1} to use the {2}",
|
||||
"EnterJobVehicleForRoute": "Enter a job vehicle nearby to start a job route",
|
||||
"JobLocations": "Visit a job location to get a job. Use {1} to find a job location",
|
||||
"JobRouteStart": "Use {1} to start a job route with this vehicle",
|
||||
"PayPhoneFirstUse": "Use {1} to end the call, and {2} to give the phone to somebody nearby"
|
||||
},
|
||||
"NoBusinessesWithinRange": "There are no businesses within {1} meters",
|
||||
"NoHousesWithinRange": "There are no houses within {1} meters",
|
||||
"NoPayPhonesWithinRange": "There are no payphones within {1} meters",
|
||||
"HeaderBusinessesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderHousesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderPayPhonesInRangeList": "Businesses (within {1} meters)",
|
||||
"HeaderCommandsForStaffFlagList": "Admin Commands ({1})",
|
||||
"PlayerLocateDistanceAndDirection": "{1} is {2} meters {3}",
|
||||
"MustBeNumber": "You need to use a number!",
|
||||
"HeaderJobRoutesList": "Job Routes ({1})",
|
||||
"HeaderJobRouteInfo": "Job Route Information (${1})",
|
||||
"InvalidJobRoute": "Job route not found!",
|
||||
"PayPhoneDeleted": "The payphone was deleted",
|
||||
"PayPhoneAnswer": "Use {1} to answer the payphone",
|
||||
"ResetActionTipsConfirm": "Are you sure you want to reset all seen action tips?",
|
||||
"ActionTipsReset": "All seen action tips have been reset.",
|
||||
"NormalChatDisabled": "Normal chat is disabled by server admin. Use chat commands instead.",
|
||||
"GlobalChatDisabled": "Global out-of-character chat is disabled by server admin"
|
||||
}
|
||||
|
||||
22
meta.xml
22
meta.xml
@@ -8,6 +8,8 @@
|
||||
<script src="scripts/shared/utilities.js" type="client" language="javascript" />
|
||||
<script src="scripts/shared/gamedata.js" type="server" language="javascript" />
|
||||
<script src="scripts/shared/gamedata.js" type="client" language="javascript" />
|
||||
<script src="scripts/shared/queue.js" type="server" language="javascript" />
|
||||
<script src="scripts/shared/queue.js" type="client" language="javascript" />
|
||||
|
||||
<!-- Multiplayer Mod (Wrapped Natives) -->
|
||||
<!-- The goal is to just swap only these out when I port the script to a new MP mod -->
|
||||
@@ -50,6 +52,7 @@
|
||||
<script src="scripts/server/npc.js" type="server" language="javascript" />
|
||||
<script src="scripts/server/netevents.js" type="server" language="javascript" />
|
||||
<script src="scripts/server/paintball.js" type="server" language="javascript" />
|
||||
<script src="scripts/server/payphone.js" type="server" language="javascript" />
|
||||
<script src="scripts/server/prompt.js" type="server" language="javascript" />
|
||||
<script src="scripts/server/race.js" type="server" language="javascript" />
|
||||
<script src="scripts/server/radio.js" type="server" language="javascript" />
|
||||
@@ -83,16 +86,29 @@
|
||||
<script src="scripts/server/item/rope.js" type="server" language="javascript" />
|
||||
<script src="scripts/server/item/tazer.js" type="server" language="javascript" />
|
||||
|
||||
<!-- Extra Client Files -->
|
||||
<!-- Fonts -->
|
||||
<file type="client" src="files/fonts/roboto-regular.ttf" />
|
||||
<file type="client" src="files/fonts/pricedown.ttf" />
|
||||
<file type="client" src="files/fonts/aurora-bold-condensed.ttf" />
|
||||
|
||||
<!-- Images -->
|
||||
<file type="client" src="files/images/skins/none.png" />
|
||||
<!--<file type="client" src="files/images/server-logo.png" />-->
|
||||
<file type="client" src="files/images/gtac-logo.png" />
|
||||
<file type="client" src="files/images/mafiac-logo.png" />
|
||||
<file type="client" src="files/images/cursor.png" />
|
||||
|
||||
<!-- 3D World Icons -->
|
||||
<file type="client" src="files/images/icons/objective-icon.png" />
|
||||
<file type="client" src="files/images/icons/business-icon.png" />
|
||||
<file type="client" src="files/images/icons/house-icon.png" />
|
||||
<file type="client" src="files/images/icons/job-icon.png" />
|
||||
|
||||
<!-- Sounds -->
|
||||
<file type="client" src="files/sounds/payphone/old-payphone-ring.mp3" />
|
||||
<file type="client" src="files/sounds/payphone/old-payphone-dial.mp3" />
|
||||
<file type="client" src="files/sounds/payphone/old-payphone-pickup.mp3" />
|
||||
<file type="client" src="files/sounds/payphone/old-payphone-hangup.mp3" />
|
||||
|
||||
<!-- GUI -->
|
||||
<script src="scripts/client/gui/2fa.js" type="client" language="javascript" />
|
||||
<script src="scripts/client/gui/bizmgr.js" type="client" language="javascript" />
|
||||
@@ -139,10 +155,12 @@
|
||||
<script src="scripts/client/mousecam.js" type="client" language="javascript" />
|
||||
<script src="scripts/client/nametag.js" type="client" language="javascript" />
|
||||
<script src="scripts/client/npc.js" type="client" language="javascript" />
|
||||
<script src="scripts/client/payphone.js" type="client" language="javascript" />
|
||||
<script src="scripts/client/radio.js" type="client" language="javascript" />
|
||||
<script src="scripts/client/scoreboard.js" type="client" language="javascript" />
|
||||
<script src="scripts/client/skin-select.js" type="client" language="javascript" />
|
||||
<script src="scripts/client/sync.js" type="client" language="javascript" />
|
||||
<script src="scripts/client/timers.js" type="client" language="javascript" />
|
||||
<script src="scripts/client/utilities.js" type="client" language="javascript" />
|
||||
<script src="scripts/client/vehicle.js" type="client" language="javascript" />
|
||||
<script src="scripts/client/netevents.js" type="client" language="javascript" />
|
||||
|
||||
@@ -64,12 +64,14 @@ function receiveBusinessFromServer(businessId, isDeleted, name, entrancePosition
|
||||
if (businessData.buyPrice > 0) {
|
||||
businessData.labelInfoType = V_PROPLABEL_INFO_BUYBIZ;
|
||||
} else {
|
||||
if (hasInterior && !hasItems) {
|
||||
if (hasInterior) {
|
||||
businessData.labelInfoType = V_PROPLABEL_INFO_ENTER;
|
||||
} else if (!hasInterior && hasItems) {
|
||||
businessData.labelInfoType = V_PROPLABEL_INFO_BUY;
|
||||
} else {
|
||||
businessData.labelInfoType = V_PROPLABEL_INFO_NONE;
|
||||
if (hasItems) {
|
||||
businessData.labelInfoType = V_PROPLABEL_INFO_BUY;
|
||||
} else {
|
||||
businessData.labelInfoType = V_PROPLABEL_INFO_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,17 +110,27 @@ function receiveBusinessFromServer(businessId, isDeleted, name, entrancePosition
|
||||
}
|
||||
} else {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Business] Business ${businessId} doesn't exist. Adding ...`);
|
||||
let tempBusinessData = new BusinessData(businessId, name, entrancePosition, blipModel, pickupModel, hasInterior, hasItems);
|
||||
let businessData = new BusinessData(businessId, name, entrancePosition, blipModel, pickupModel, hasInterior, locked, hasItems, entranceFee);
|
||||
businessData.name = name;
|
||||
businessData.entrancePosition = entrancePosition;
|
||||
businessData.blipModel = blipModel;
|
||||
businessData.pickupModel = pickupModel;
|
||||
businessData.hasInterior = hasInterior;
|
||||
businessData.buyPrice = buyPrice;
|
||||
businessData.rentPrice = rentPrice;
|
||||
businessData.hasItems = hasItems;
|
||||
businessData.locked = locked;
|
||||
businessData.entranceFee = entranceFee;
|
||||
if (blipModel != -1) {
|
||||
let blipId = createGameBlip(tempBusinessData.blipModel, tempBusinessData.entrancePosition, tempBusinessData.name);
|
||||
let blipId = createGameBlip(businessData.blipModel, businessData.entrancePosition, businessData.name);
|
||||
if (blipId != -1) {
|
||||
tempBusinessData.blipId = blipId;
|
||||
businessData.blipId = blipId;
|
||||
}
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Business] Business ${businessId}'s blip has been added by the server (Model ${blipModel}, ID ${blipId})`);
|
||||
} else {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Business] Business ${businessId} has no blip.`);
|
||||
}
|
||||
getServerData().businesses.push(tempBusinessData);
|
||||
getServerData().businesses.push(businessData);
|
||||
setAllBusinessDataIndexes();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,4 +40,17 @@ function processCameraFadeRendering() {
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function fadeLocalCamera(state, duration, colour) {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Utilities] Fading camera ${(state) ? "in" : "out"} for ${duration}ms`);
|
||||
|
||||
cameraFadeDuration = duration;
|
||||
cameraFadeStart = sdl.ticks;
|
||||
cameraFadeIn = state;
|
||||
cameraFadeColour = colour;
|
||||
cameraFadeAlpha = (state) ? 255 : 0;
|
||||
cameraFadeEnabled = true;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -28,10 +28,11 @@ let renderHotBar = true;
|
||||
let renderItemActionDelay = true;
|
||||
let renderInteriorLights = true;
|
||||
|
||||
let logLevel = LOG_INFO;
|
||||
let logLevel = LOG_INFO | LOG_DEBUG;
|
||||
|
||||
let weaponDamageEnabled = {};
|
||||
let weaponDamageEvent = {};
|
||||
let weaponDamageMultiplier = 1.0;
|
||||
|
||||
let forceWeapon = 0;
|
||||
let forceWeaponAmmo = 0;
|
||||
@@ -89,6 +90,7 @@ let localLocaleId = 0;
|
||||
* @property {Array} localeStrings
|
||||
* @property {Array} localeOptions
|
||||
* @property {Object} cvars
|
||||
* @property {Array.<PayPhoneData>} payPhones
|
||||
*/
|
||||
let serverData = {
|
||||
houses: [],
|
||||
@@ -98,6 +100,7 @@ let serverData = {
|
||||
vehicles: [],
|
||||
jobs: [],
|
||||
cvars: {},
|
||||
payPhones: [],
|
||||
};
|
||||
|
||||
let localPlayerMoney = 0;
|
||||
@@ -106,6 +109,7 @@ let localPlayerMoneyInterval = null;
|
||||
let currencyString = "${AMOUNT}";
|
||||
|
||||
let mapChangeWarning = false;
|
||||
let mapChangeToNight = false;
|
||||
|
||||
let cruiseControlEnabled = false;
|
||||
let cruiseControlSpeed = 0.0;
|
||||
|
||||
@@ -47,6 +47,7 @@ function addAllEventHandlers() {
|
||||
addEventHandler("OnMapLoaded", onMapLoaded);
|
||||
addEventHandler("OnPedEnteringVehicle", onPedEnteredVehicle);
|
||||
addEventHandler("OnPedExitingVehicle", onPedExitedVehicle);
|
||||
addEventHandler("OnPedInflictDamage", onPedHit);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,6 +122,8 @@ function onProcess(event, deltaTime) {
|
||||
processVehiclePurchasing();
|
||||
processVehicleBurning();
|
||||
processVehicleCruiseControl();
|
||||
processPayPhonesDistance();
|
||||
processJobRouteLocationDistance();
|
||||
//checkChatBoxAutoHide(); // Will be uncommented on 1.4.0 GTAC update
|
||||
//processVehicleFires();
|
||||
}
|
||||
@@ -158,6 +161,8 @@ function onDrawnHUD(event) {
|
||||
processInteriorLightsRendering();
|
||||
processCustomHUDRendering();
|
||||
processCameraFadeRendering();
|
||||
processJobLocationIndicatorRendering();
|
||||
processMapChangeWarning();
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -182,6 +187,7 @@ function onPedExitedVehicle(event, ped, vehicle, seat) {
|
||||
cruiseControlEnabled = false;
|
||||
cruiseControlSpeed = 0.0;
|
||||
|
||||
/*
|
||||
if (localPlayer != null) {
|
||||
if (ped == localPlayer) {
|
||||
if (areServerElementsSupported()) {
|
||||
@@ -195,6 +201,7 @@ function onPedExitedVehicle(event, ped, vehicle, seat) {
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -257,6 +264,16 @@ function onPedInflictDamage(event, damagedEntity, damagerEntity, weaponId, healt
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function onPedHit(event, hitPed, vec1, vec2, vec3, hitType, damage, bodyPart) {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Event] Ped ${hitPed.id} (${hitPed.name}) hit using type ${hitType}, causing ${damage} to body part ${bodyPart}`);
|
||||
event.preventDefault();
|
||||
if (hitPed == localPlayer) {
|
||||
localPlayer.health = localPlayer.health - (damage * weaponDamageMultiplier);
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function onPedEnteredSphere(event, ped, sphere) {
|
||||
if (sphere == jobRouteLocationSphere) {
|
||||
enteredJobRouteSphere();
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
// ===========================================================================
|
||||
|
||||
let customHUDMoneyFont = null;
|
||||
let customHUDMoneyColour = toColour(200, 200, 200, 200);
|
||||
let customHUDMoneyColour = toColour(255, 255, 255, 255);
|
||||
let customHUDMoneySize = 22.0;
|
||||
|
||||
// ===========================================================================
|
||||
@@ -33,6 +33,7 @@ function processCustomHUDRendering() {
|
||||
let text = getCurrencyString(localPlayerMoney);
|
||||
logToConsole(LOG_VERBOSE, `[V.RP.HUD]: Rendering custom HUD money (${text})...`);
|
||||
customHUDMoneyFont.render(text, [game.width - 150, 20], 130, 1.0, 0.0, customHUDMoneyFont.size, customHUDMoneyColour, true, true, false, true);
|
||||
//graphics.drawRectangle()
|
||||
} else {
|
||||
logToConsole(LOG_VERBOSE | LOG_ERROR, `[V.RP.HUD]: Rendering custom HUD money FAILED. Font object is null!`);
|
||||
}
|
||||
|
||||
@@ -7,10 +7,17 @@
|
||||
// TYPE: Client (JavaScript)
|
||||
// ===========================================================================
|
||||
|
||||
let localPlayerJobType = 0;
|
||||
let localPlayerJobType = -1;
|
||||
let localPlayerWorking = false;
|
||||
let jobRouteLocationBlip = null;
|
||||
let jobRouteLocationSphere = null;
|
||||
let jobRouteLocationRadius = 5.0;
|
||||
|
||||
let jobRouteLocationIndicatorPosition = toVector3(0.0, 0.0, 0.0);
|
||||
let jobRouteLocationIndicatorSize = toVector2(32, 32);
|
||||
let jobRouteLocationIndicatorEnabled = false;
|
||||
let jobRouteLocationIndicatorImagePath = "files/images/icons/objective-icon.png";
|
||||
let jobRouteLocationIndicatorImage = null;
|
||||
|
||||
let jobBlipBlinkAmount = 0;
|
||||
let jobBlipBlinkTimes = 10;
|
||||
@@ -36,11 +43,25 @@ class JobData {
|
||||
|
||||
function initJobScript() {
|
||||
logToConsole(LOG_DEBUG, "[V.RP.Job]: Initializing job script ...");
|
||||
jobRouteLocationIndicatorImage = loadJobRouteLocationIndicatorImage();
|
||||
logToConsole(LOG_DEBUG, "[V.RP.Job]: Job script initialized!");
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function loadJobRouteLocationIndicatorImage() {
|
||||
let imageStream = openFile(jobRouteLocationIndicatorImagePath);
|
||||
let tempImage = null;
|
||||
if (imageStream != null) {
|
||||
tempImage = graphics.loadPNG(imageStream);
|
||||
imageStream.close();
|
||||
}
|
||||
|
||||
return tempImage;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function setLocalPlayerJobType(tempJobType) {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Job] Set local player job type to ${tempJobType}`);
|
||||
localPlayerJobType = tempJobType;
|
||||
@@ -75,6 +96,11 @@ function showJobRouteLocation(position, colour) {
|
||||
blinkJobRouteLocationBlip(10, position, colour);
|
||||
jobRouteLocationBlip = game.createBlip(position, 0, 2, colour);
|
||||
}
|
||||
|
||||
if (getGame() == V_GAME_MAFIA_ONE) {
|
||||
jobRouteLocationIndicatorPosition = position;
|
||||
jobRouteLocationIndicatorEnabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -116,22 +142,29 @@ function blinkJobRouteLocationBlip(times, position, colour) {
|
||||
function hideJobRouteLocation() {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Job] Hiding job route location`);
|
||||
|
||||
if (jobRouteLocationBlip != null) {
|
||||
destroyElement(jobRouteLocationBlip);
|
||||
jobRouteLocationBlip = null;
|
||||
if (isGameFeatureSupported("blip")) {
|
||||
if (jobRouteLocationBlip != null) {
|
||||
destroyElement(jobRouteLocationBlip);
|
||||
jobRouteLocationBlip = null;
|
||||
}
|
||||
|
||||
if (jobRouteLocationSphere != null) {
|
||||
destroyElement(jobRouteLocationSphere);
|
||||
jobRouteLocationSphere = null;
|
||||
}
|
||||
|
||||
if (jobBlipBlinkTimer != null) {
|
||||
clearInterval(jobBlipBlinkTimer);
|
||||
}
|
||||
|
||||
jobBlipBlinkAmount = 0;
|
||||
jobBlipBlinkTimes = 0;
|
||||
}
|
||||
|
||||
if (jobRouteLocationSphere != null) {
|
||||
destroyElement(jobRouteLocationSphere);
|
||||
jobRouteLocationSphere = null;
|
||||
if (getGame() == V_GAME_MAFIA_ONE) {
|
||||
jobRouteLocationIndicatorPosition = toVector3(0.0, 0.0, 0.0);
|
||||
jobRouteLocationIndicatorEnabled = false;
|
||||
}
|
||||
|
||||
if (jobBlipBlinkTimer != null) {
|
||||
clearInterval(jobBlipBlinkTimer);
|
||||
}
|
||||
|
||||
jobBlipBlinkAmount = 0;
|
||||
jobBlipBlinkTimes = 0;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -236,4 +269,45 @@ function removeJobsFromClient() {
|
||||
getServerData().jobs.splice(0);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function processJobLocationIndicatorRendering() {
|
||||
if (jobRouteLocationIndicatorImage == null) {
|
||||
logToConsole(LOG_VERBOSE, `[V.RP.Job]: Can't render job location indicator. Image is null.`);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getGame() != V_GAME_MAFIA_ONE) {
|
||||
logToConsole(LOG_VERBOSE, `[V.RP.Job]: Can't render job location indicator. Unsupported game.`);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!jobRouteLocationIndicatorEnabled) {
|
||||
logToConsole(LOG_VERBOSE, `[V.RP.Job]: Can't render job location indicator. Disabled`);
|
||||
return false;
|
||||
}
|
||||
|
||||
let screenPosition = getScreenFromWorldPosition(jobRouteLocationIndicatorPosition);
|
||||
screenPosition = fixOffScreenPosition(screenPosition, jobRouteLocationIndicatorSize);
|
||||
graphics.drawRectangle(jobRouteLocationIndicatorImage, [screenPosition.x - (jobRouteLocationIndicatorSize.x / 2), screenPosition.y - (jobRouteLocationIndicatorSize.y / 2)], [jobRouteLocationIndicatorSize.x, jobRouteLocationIndicatorSize.y]);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function processJobRouteLocationDistance() {
|
||||
if (getGame() != V_GAME_MAFIA_ONE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (jobRouteLocationIndicatorEnabled == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getDistance(getLocalPlayerPosition(), jobRouteLocationIndicatorPosition) <= jobRouteLocationRadius) {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Job] Reached job route location`);
|
||||
hideJobRouteLocation();
|
||||
tellServerPlayerArrivedAtJobRouteLocation();
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -13,7 +13,7 @@ let jobLabels = [];
|
||||
|
||||
let propertyLabelNameFont = null;
|
||||
let propertyLabelLockedFont = null;
|
||||
let propertyLabelHeight = (getGame() == V_GAME_MAFIA_ONE) ? 2.0 : 1.0;
|
||||
let propertyLabelHeight = (getGame() == V_GAME_MAFIA_ONE) ? 1.75 : 1.0;
|
||||
let propertyPickupRenderDistance = 75.0;
|
||||
let propertyLabelRenderDistance = 5.0;
|
||||
let propertyLabelLockedOffset = 16;
|
||||
@@ -27,6 +27,20 @@ let unlockedColour = toColour(50, 205, 50, 255);
|
||||
let lockedColour = toColour(205, 92, 92, 255);
|
||||
let jobHelpColour = toColour(234, 198, 126, 255);
|
||||
|
||||
let businessWorldIconPath = "files/images/icons/business-icon.png";
|
||||
let jobWorldIconPath = "files/images/icons/job-icon.png";
|
||||
let houseWorldIconPath = "files/images/icons/house-icon.png";
|
||||
let businessWorldIconImage = null;
|
||||
let jobWorldIconImage = null;
|
||||
let houseWorldIconImage = null;
|
||||
let businessWorldIconSize = [64, 64];
|
||||
let jobWorldIconSize = [64, 64];
|
||||
let houseWorldIconSize = [64, 64];
|
||||
let worldIconRenderDistance = 15.0;
|
||||
let businessWorldIconRenderDistance = worldIconRenderDistance;
|
||||
let houseWorldIconRenderDistance = worldIconRenderDistance;
|
||||
let jobWorldIconRenderDistance = worldIconRenderDistance;
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function initLabelScript() {
|
||||
@@ -35,6 +49,10 @@ function initLabelScript() {
|
||||
propertyLabelLockedFont = initLabelPropertyLockedFont();
|
||||
jobNameLabelFont = initLabelJobNameFont();
|
||||
jobHelpLabelFont = initLabelJobHelpFont();
|
||||
|
||||
businessWorldIconImage = initBusinessWorldIcon();
|
||||
jobWorldIconImage = initJobWorldIcon();
|
||||
houseWorldIconImage = initHouseWorldIcon();
|
||||
logToConsole(LOG_DEBUG, "[V.RP.Label]: Label script initialized!");
|
||||
}
|
||||
|
||||
@@ -64,6 +82,45 @@ function initLabelJobHelpFont() {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function initBusinessWorldIcon() {
|
||||
let imageStream = openFile(businessWorldIconPath);
|
||||
let tempImage = null;
|
||||
if (imageStream != null) {
|
||||
tempImage = graphics.loadPNG(imageStream);
|
||||
imageStream.close();
|
||||
}
|
||||
|
||||
return tempImage;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function initJobWorldIcon() {
|
||||
let imageStream = openFile(jobWorldIconPath);
|
||||
let tempImage = null;
|
||||
if (imageStream != null) {
|
||||
tempImage = graphics.loadPNG(imageStream);
|
||||
imageStream.close();
|
||||
}
|
||||
|
||||
return tempImage;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function initHouseWorldIcon() {
|
||||
let imageStream = openFile(houseWorldIconPath);
|
||||
let tempImage = null;
|
||||
if (imageStream != null) {
|
||||
tempImage = graphics.loadPNG(imageStream);
|
||||
imageStream.close();
|
||||
}
|
||||
|
||||
return tempImage;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function renderPropertyEntranceLabel(name, position, locked, isBusiness, price, rentPrice, labelInfoType, fee) {
|
||||
if (localPlayer == null) {
|
||||
return false;
|
||||
@@ -77,6 +134,12 @@ function renderPropertyEntranceLabel(name, position, locked, isBusiness, price,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getGame() == V_GAME_MAFIA_ONE) {
|
||||
if (localPlayer.vehicle != null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (getGame() == V_GAME_GTA_IV) {
|
||||
if (!natives.doesViewportExist(natives.getGameViewportId())) {
|
||||
logToConsole(LOG_INFO, "[V.RP.Label]: Game viewport does not exist!");
|
||||
@@ -218,6 +281,12 @@ function renderPropertyExitLabel(position) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getGame() == V_GAME_MAFIA_ONE) {
|
||||
if (localPlayer.vehicle != null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (getGame() == V_GAME_GTA_IV) {
|
||||
if (!natives.doesViewportExist(natives.getGameViewportId())) {
|
||||
logToConsole(LOG_INFO, "[V.RP.Label]: Game viewport does not exist!");
|
||||
@@ -230,17 +299,12 @@ function renderPropertyExitLabel(position) {
|
||||
}
|
||||
}
|
||||
|
||||
let tempPosition = position;
|
||||
tempPosition.z = tempPosition.z + propertyLabelHeight;
|
||||
position = getPosAbovePos(position, propertyLabelHeight);
|
||||
let screenPosition = new Vec3(0.0, 0.0, 0.0);
|
||||
if (getGame() == V_GAME_GTA_IV) {
|
||||
screenPosition = natives.getViewportPositionOfCoord(tempPosition, natives.getGameViewportId());
|
||||
screenPosition = natives.getViewportPositionOfCoord(position, natives.getGameViewportId());
|
||||
} else {
|
||||
screenPosition = getScreenFromWorldPosition(tempPosition);
|
||||
}
|
||||
|
||||
if (screenPosition.x < 0 || screenPosition.x > game.width) {
|
||||
return false;
|
||||
screenPosition = getScreenFromWorldPosition(position);
|
||||
}
|
||||
|
||||
let text = "EXIT";
|
||||
@@ -263,6 +327,12 @@ function renderJobLabel(name, position, jobType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getGame() == V_GAME_MAFIA_ONE) {
|
||||
if (localPlayer.vehicle != null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (getGame() == V_GAME_GTA_IV) {
|
||||
if (!natives.doesViewportExist(natives.getGameViewportId())) {
|
||||
logToConsole(LOG_INFO, "[V.RP.Label]: Game viewport does not exist!");
|
||||
@@ -275,15 +345,16 @@ function renderJobLabel(name, position, jobType) {
|
||||
}
|
||||
}
|
||||
|
||||
let tempPosition = position;
|
||||
tempPosition.z = tempPosition.z + propertyLabelHeight;
|
||||
position = getPosAbovePos(position, propertyLabelHeight);
|
||||
let screenPosition = new Vec3(0.0, 0.0, 0.0);
|
||||
if (getGame() == V_GAME_GTA_IV) {
|
||||
screenPosition = natives.getViewportPositionOfCoord(tempPosition, natives.getGameViewportId());
|
||||
screenPosition = natives.getViewportPositionOfCoord(position, natives.getGameViewportId());
|
||||
} else {
|
||||
screenPosition = getScreenFromWorldPosition(tempPosition);
|
||||
screenPosition = getScreenFromWorldPosition(position);
|
||||
}
|
||||
|
||||
logToConsole(LOG_VERBOSE, `[V.RP.Label] World [${position.x}, ${position.y}, ${position.z}] to screen [${screenPosition.x}, ${screenPosition.y}, ${screenPosition.z}]`);
|
||||
|
||||
if (screenPosition.x < 0 || screenPosition.x > game.width) {
|
||||
return false;
|
||||
}
|
||||
@@ -296,7 +367,7 @@ function renderJobLabel(name, position, jobType) {
|
||||
text = getLocaleString("StartWorkLabel", "/startwork");
|
||||
}
|
||||
} else {
|
||||
if (localPlayerJobType == 0) {
|
||||
if (localPlayerJobType == -1) {
|
||||
text = getLocaleString("TakeJobLabel", "/takejob");
|
||||
} else {
|
||||
text = getLocaleString("NotYourJobLabel", "/quitjob");
|
||||
@@ -316,48 +387,69 @@ function renderJobLabel(name, position, jobType) {
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
function processLabelRendering() {
|
||||
if (getGame() == V_GAME_MAFIA_ONE) {
|
||||
if (localPlayer.vehicle != null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (renderLabels) {
|
||||
if (!areServerElementsSupported() || getGame() == V_GAME_MAFIA_ONE || getGame() == V_GAME_GTA_IV || getGame() == V_GAME_GTA_IV_EFLC) {
|
||||
if (localPlayer != null) {
|
||||
getServerData().businesses.forEach((business) => {
|
||||
if (getDistance(localPlayer.position, business.entrancePosition) <= propertyPickupRenderDistance) {
|
||||
let distance = getDistance(localPlayer.position, business.entrancePosition);
|
||||
if (distance <= propertyLabelRenderDistance) {
|
||||
if (getGame() == V_GAME_GTA_IV || getGame() == V_GAME_GTA_IV_EFLC) {
|
||||
natives.drawColouredCylinder(getPosBelowPos(business.entrancePosition, 1.0), 0.0, 0.0, 0, 153, 255, 255);
|
||||
}
|
||||
|
||||
if (getDistance(localPlayer.position, business.entrancePosition) <= propertyLabelRenderDistance) {
|
||||
renderPropertyEntranceLabel(business.name, business.entrancePosition, business.locked, true, business.buyPrice, business.rentPrice, business.labelInfoType, business.entranceFee);
|
||||
renderPropertyEntranceLabel(business.name, business.entrancePosition, business.locked, true, business.buyPrice, business.rentPrice, business.labelInfoType, business.entranceFee);
|
||||
}
|
||||
|
||||
if (distance <= businessWorldIconRenderDistance) {
|
||||
if (getGame() == V_GAME_MAFIA_ONE && localPlayer.vehicle == null) {
|
||||
renderBusinessWorldIcon(getPosAbovePos(business.entrancePosition, 1.0));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
getServerData().houses.forEach((house) => {
|
||||
if (getDistance(localPlayer.position, house.entrancePosition) <= propertyPickupRenderDistance) {
|
||||
let distance = getDistance(localPlayer.position, house.entrancePosition);
|
||||
if (distance <= propertyLabelRenderDistance) {
|
||||
if (getGame() == V_GAME_GTA_IV || getGame() == V_GAME_GTA_IV_EFLC) {
|
||||
natives.drawColouredCylinder(getPosBelowPos(house.entrancePosition, 1.0), 0.0, 0.0, 0, 200, 0, 255);
|
||||
}
|
||||
|
||||
if (getDistance(localPlayer.position, house.entrancePosition) <= propertyLabelRenderDistance) {
|
||||
renderPropertyEntranceLabel(house.description, house.entrancePosition, house.locked, true, house.buyPrice, house.rentPrice, house.labelInfoType);
|
||||
renderPropertyEntranceLabel(house.description, house.entrancePosition, house.locked, true, house.buyPrice, house.rentPrice, house.labelInfoType);
|
||||
}
|
||||
|
||||
if (distance <= houseWorldIconRenderDistance) {
|
||||
if (getGame() == V_GAME_MAFIA_ONE && localPlayer.vehicle == null) {
|
||||
renderHouseWorldIcon(getPosAbovePos(house.entrancePosition, 1.0));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
getServerData().jobs.forEach((job) => {
|
||||
if (getDistance(localPlayer.position, job.position) <= propertyPickupRenderDistance) {
|
||||
let distance = getDistance(localPlayer.position, job.position);
|
||||
if (distance <= propertyLabelRenderDistance) {
|
||||
if (getGame() == V_GAME_GTA_IV || getGame() == V_GAME_GTA_IV_EFLC) {
|
||||
natives.drawColouredCylinder(getPosBelowPos(job.position, 1.0), 0.0, 0.0, 255, 255, 0, 255);
|
||||
}
|
||||
|
||||
if (getDistance(localPlayer.position, job.position) <= propertyPickupRenderDistance) {
|
||||
renderJobLabel(job.name, job.position, job.jobType);
|
||||
renderJobLabel(job.name, job.position, job.jobId);
|
||||
}
|
||||
|
||||
if (distance <= jobWorldIconRenderDistance) {
|
||||
if (getGame() == V_GAME_MAFIA_ONE && localPlayer.vehicle == null) {
|
||||
renderJobWorldIcon(getPosAbovePos(job.position, 1.0));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (areWorldLabelsSupported()) {
|
||||
if (arePickupsSupported() && areWorldLabelsSupported()) {
|
||||
if (localPlayer != null) {
|
||||
let pickups = getElementsByType(ELEMENT_PICKUP);
|
||||
for (let i in pickups) {
|
||||
@@ -415,4 +507,55 @@ function processLabelRendering() {
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
function renderJobWorldIcon(position) {
|
||||
if (jobWorldIconImage == null) {
|
||||
logToConsole(LOG_VERBOSE, `[V.RP.Label]: Can't render job world icon. Image is null.`);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getGame() != V_GAME_MAFIA_ONE) {
|
||||
logToConsole(LOG_VERBOSE, `[V.RP.Label]: Can't render job world icon. Unsupported game.`);
|
||||
return false;
|
||||
}
|
||||
|
||||
let screenPosition = getScreenFromWorldPosition(position);
|
||||
graphics.drawRectangle(jobWorldIconImage, [screenPosition.x - (jobWorldIconSize[0] / 2), screenPosition.y - (jobWorldIconSize[1] / 2)], [jobWorldIconSize[0], jobWorldIconSize[1]]);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
function renderBusinessWorldIcon(position) {
|
||||
if (businessWorldIconImage == null) {
|
||||
logToConsole(LOG_VERBOSE, `[V.RP.Label]: Can't render business world icon. Image is null.`);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getGame() != V_GAME_MAFIA_ONE) {
|
||||
logToConsole(LOG_VERBOSE, `[V.RP.Label]: Can't render business world icon. Unsupported game.`);
|
||||
return false;
|
||||
}
|
||||
|
||||
let screenPosition = getScreenFromWorldPosition(position);
|
||||
graphics.drawRectangle(businessWorldIconImage, [screenPosition.x - (businessWorldIconSize[0] / 2), screenPosition.y - (businessWorldIconSize[1] / 2)], [businessWorldIconSize[0], businessWorldIconSize[1]]);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
function renderHouseWorldIcon(position) {
|
||||
if (houseWorldIconImage == null) {
|
||||
logToConsole(LOG_VERBOSE, `[V.RP.Label]: Can't render house world icon. Image is null.`);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getGame() != V_GAME_MAFIA_ONE) {
|
||||
logToConsole(LOG_VERBOSE, `[V.RP.Label]: Can't render house world icon. Unsupported game.`);
|
||||
return false;
|
||||
}
|
||||
|
||||
let screenPosition = getScreenFromWorldPosition(position);
|
||||
graphics.drawRectangle(houseWorldIconImage, [screenPosition.x - (houseWorldIconSize[0] / 2), screenPosition.y - (houseWorldIconSize[1] / 2)], [houseWorldIconSize[0], houseWorldIconSize[1]]);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
@@ -8,7 +8,7 @@
|
||||
// ===========================================================================
|
||||
|
||||
let logoImage = null;
|
||||
let logoPos = toVector2(game.width - 132, game.height - 132);
|
||||
let logoPos = (getGame() == V_GAME_MAFIA_ONE) ? toVector2(80, game.height - 80) : toVector2(64, 64);
|
||||
let logoSize = toVector2(128, 128);
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
@@ -13,6 +13,7 @@ let afkStatusFont = null;
|
||||
let pingFont = null;
|
||||
let nametagDistance = 50.0;
|
||||
let nametagWidth = 70;
|
||||
let nametagHeight = (getGame() == V_GAME_MAFIA_ONE) ? 2.0 : 0.9;
|
||||
|
||||
let playerNames = {};
|
||||
let playerColours = {};
|
||||
@@ -84,21 +85,15 @@ function drawNametag(x, y, health, armour, text, ping, alpha, distance, colour,
|
||||
// -------------------------------------------
|
||||
// Health Bar
|
||||
|
||||
if (getMultiplayerMod() == V_MPMOD_GTAC) {
|
||||
if (getGame() == V_GAME_GTA_III) {
|
||||
// Mickey Hamfists is ridiculously tall. Raise the nametag for him a bit
|
||||
if (skin == 109) {
|
||||
y -= 20;
|
||||
} else {
|
||||
y -= 5;
|
||||
}
|
||||
} else {
|
||||
y -= 5;
|
||||
if (getGame() == V_GAME_GTA_III) {
|
||||
// Mickey Hamfists is ridiculously tall. Raise the nametag for him a bit
|
||||
if (skin == 109) {
|
||||
y -= 15;
|
||||
}
|
||||
} else {
|
||||
y -= 5;
|
||||
}
|
||||
|
||||
y -= 5;
|
||||
|
||||
if (health > 0.0) {
|
||||
let hx = x - width / 2;
|
||||
let hy = y - 10 / 2;
|
||||
@@ -143,20 +138,18 @@ function drawNametag(x, y, health, armour, text, ping, alpha, distance, colour,
|
||||
// ===========================================================================
|
||||
|
||||
function updateNametag(element) {
|
||||
if (!areWorldLabelsSupported()) {
|
||||
if (!isGameFeatureSupported("customNametag")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (localPlayer != null) {
|
||||
let playerPos = localPlayer.position;
|
||||
let elementPos = element.position;
|
||||
let playerPosition = localPlayer.position;
|
||||
let elementPosition = element.position;
|
||||
|
||||
elementPos[2] += 0.9;
|
||||
elementPosition = getPosAbovePos(elementPosition, nametagHeight);
|
||||
|
||||
//if(typeof element.getComponentPosition()) {
|
||||
|
||||
let screenPos = getScreenFromWorldPosition(elementPos);
|
||||
if (screenPos[2] >= 0.0) {
|
||||
let screenPosition = getScreenFromWorldPosition(elementPosition);
|
||||
if (screenPosition[2] >= 0.0 || getGame() == V_GAME_MAFIA_ONE) {
|
||||
let health = element.health / 100.0;
|
||||
if (health > 1.0) {
|
||||
health = 1.0;
|
||||
@@ -167,10 +160,10 @@ function updateNametag(element) {
|
||||
armour = 1.0;
|
||||
}
|
||||
|
||||
let distance = playerPos.distance(elementPos);
|
||||
let distance = playerPosition.distance(elementPosition);
|
||||
if (distance <= nametagDistance) {
|
||||
if (typeof game.processLineOfSight != "undefined") {
|
||||
let losCheck = game.processLineOfSight(playerPos, elementPos, true, false, false, true, true, false, true, true);
|
||||
let losCheck = game.processLineOfSight(playerPosition, elementPosition, true, false, false, true, true, false, true, true);
|
||||
if (losCheck != null) {
|
||||
return false;
|
||||
}
|
||||
@@ -182,25 +175,23 @@ function updateNametag(element) {
|
||||
let paused = false;
|
||||
let ping = -1;
|
||||
|
||||
if (element.isType(ELEMENT_PLAYER)) {
|
||||
if (typeof playerNames[element.name] != "undefined") {
|
||||
name = playerNames[element.name];
|
||||
}
|
||||
|
||||
if (typeof playerPaused[element.name] != "undefined") {
|
||||
paused = playerPaused[element.name];
|
||||
}
|
||||
|
||||
if (typeof playerColours[element.name] != "undefined") {
|
||||
colour = playerColours[element.name];
|
||||
}
|
||||
|
||||
if (typeof playerPing[element.name] != "undefined") {
|
||||
ping = playerPing[element.name];
|
||||
}
|
||||
if (typeof playerNames[element.name] != "undefined") {
|
||||
name = playerNames[element.name];
|
||||
}
|
||||
|
||||
drawNametag(screenPos[0], screenPos[1], health, armour, name, ping, 1.0 - distance / nametagDistance, distance, colour, paused, element.skin);
|
||||
if (typeof playerPaused[element.name] != "undefined") {
|
||||
paused = playerPaused[element.name];
|
||||
}
|
||||
|
||||
if (typeof playerColours[element.name] != "undefined") {
|
||||
colour = playerColours[element.name];
|
||||
}
|
||||
|
||||
if (typeof playerPing[element.name] != "undefined") {
|
||||
ping = playerPing[element.name];
|
||||
}
|
||||
|
||||
drawNametag(screenPosition[0], screenPosition[1], health, armour, name, ping, 1.0 - distance / nametagDistance, distance, colour, paused, element.skin);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -224,6 +215,12 @@ function processNameTagRendering(event) {
|
||||
// return false;
|
||||
//}
|
||||
|
||||
if (getGame() == V_GAME_MAFIA_ONE) {
|
||||
if (localPlayer.vehicle != null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
getElementsByType(ELEMENT_PED).forEach(function (ped) {
|
||||
if (ped != localPlayer) {
|
||||
updateNametag(ped);
|
||||
|
||||
@@ -110,7 +110,7 @@ function addAllNetworkHandlers() {
|
||||
addNetworkEventHandler("v.rp.changePassword", showChangePasswordGUI);
|
||||
addNetworkEventHandler("v.rp.showLocaleChooser", showLocaleChooserGUI);
|
||||
addNetworkEventHandler("v.rp.guiColour", setGUIColours);
|
||||
addNetworkEventHandler("v.rp.mapChangeWarning", setMapChangeWarningState);
|
||||
addNetworkEventHandler("v.rp.mapChangingSoon", setMapChangeWarningState);
|
||||
|
||||
// 2D Rendering
|
||||
addNetworkEventHandler("v.rp.set2DRendering", set2DRendering);
|
||||
@@ -141,6 +141,14 @@ function addAllNetworkHandlers() {
|
||||
addNetworkEventHandler("v.rp.nametag", updatePlayerNameTag);
|
||||
addNetworkEventHandler("v.rp.nametagDistance", setNameTagDistance);
|
||||
|
||||
// PayPhones
|
||||
addNetworkEventHandler("v.rp.payPhone", receivePayPhoneFromServer);
|
||||
addNetworkEventHandler("v.rp.payPhoneState", receivePayPhoneStateFromServer);
|
||||
addNetworkEventHandler("v.rp.removePayPhones", removePayPhonesFromClient);
|
||||
addNetworkEventHandler("v.rp.payPhoneDial", payPhoneDial);
|
||||
addNetworkEventHandler("v.rp.payPhoneHangup", payPhoneHangup);
|
||||
addNetworkEventHandler("v.rp.payPhonePickup", payPhonePickup);
|
||||
|
||||
// Misc
|
||||
addNetworkEventHandler("v.rp.mouseCursor", toggleMouseCursor);
|
||||
addNetworkEventHandler("v.rp.mouseCamera", toggleMouseCamera);
|
||||
@@ -152,6 +160,7 @@ function addAllNetworkHandlers() {
|
||||
addNetworkEventHandler("v.rp.minuteDuration", setMinuteDuration);
|
||||
addNetworkEventHandler("v.rp.snow", setSnowState);
|
||||
addNetworkEventHandler("v.rp.enterPropertyKey", setEnterPropertyKey);
|
||||
addNetworkEventHandler("v.rp.scoreBoardKey", setScoreBoardKey);
|
||||
addNetworkEventHandler("v.rp.skinSelect", toggleSkinSelect);
|
||||
addNetworkEventHandler("v.rp.hotbar", updatePlayerHotBar);
|
||||
addNetworkEventHandler("v.rp.logLevel", setLogLevel);
|
||||
@@ -167,6 +176,7 @@ function addAllNetworkHandlers() {
|
||||
addNetworkEventHandler("v.rp.profanityFilter", setProfanityFilterState);
|
||||
addNetworkEventHandler("v.rp.currencyString", receiveCurrencyStringFromServer);
|
||||
addNetworkEventHandler("v.rp.token", serverRequestedToken);
|
||||
addNetworkEventHandler("v.rp.incomingDamageMultiplier", setIncomingDamageMultiplier);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -286,9 +296,8 @@ function setEnterPropertyKey(key) {
|
||||
if (key == -1) {
|
||||
enterPropertyKey = null;
|
||||
} else {
|
||||
enterPropertyKey = key;
|
||||
enterPropertyKey = toInteger(key);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -464,8 +473,9 @@ function receiveCurrencyStringFromServer(newCurrencyString) {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function setMapChangeWarningState(state) {
|
||||
function setMapChangeWarningState(state, changeToNight) {
|
||||
mapChangeWarning = state;
|
||||
mapChangeToNight = changeToNight;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -487,4 +497,10 @@ function serverRequestedToken() {
|
||||
sendNetworkEventToServer("v.rp.token", token);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function setIncomingDamageMultiplier(tempMultiplier) {
|
||||
weaponDamageMultiplier = tempMultiplier;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
252
scripts/client/payphone.js
Normal file
252
scripts/client/payphone.js
Normal file
@@ -0,0 +1,252 @@
|
||||
// ===========================================================================
|
||||
// Vortrex's Roleplay Resource
|
||||
// https://github.com/VortrexFTW/v-roleplay
|
||||
// ===========================================================================
|
||||
// FILE: payphone.js
|
||||
// DESC: Provides payphone functions and processing
|
||||
// TYPE: Client (JavaScript)
|
||||
// ===========================================================================
|
||||
|
||||
let payPhoneMaxAudibleDistance = 75;
|
||||
let payPhoneRingMaxVolume = 50;
|
||||
|
||||
let payPhoneRingingIndicatorImage = null;
|
||||
let payPhoneRingingIndicatorImagePath = "files/images/payphone-ringing.png";
|
||||
|
||||
// Will be unnecessary once MafiaC has game sound playback in scripting
|
||||
let payPhoneRingingSound = null;
|
||||
let payPhoneDialingSound = null;
|
||||
let payPhonePickupSound = null;
|
||||
let payPhoneHangupSound = null;
|
||||
let payPhoneRingingSoundFilePath = "files/sounds/payphone/old-payphone-ring.mp3";
|
||||
let payPhoneDialingSoundFilePath = "files/sounds/payphone/old-payphone-dial.mp3";
|
||||
let payPhonePickupSoundFilePath = "files/sounds/payphone/old-payphone-pickup.mp3";
|
||||
let payPhoneHangupSoundFilePath = "files/sounds/payphone/old-payphone-hangup.mp3";
|
||||
|
||||
let ringingPayPhone = -1;
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
class PayPhoneData {
|
||||
constructor(payPhoneId, state, position) {
|
||||
this.index = -1;
|
||||
this.payPhoneId = payPhoneId;
|
||||
this.position = position;
|
||||
this.state = state;
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function initPayPhoneScript() {
|
||||
logToConsole(LOG_DEBUG, "[V.RP.PayPhone]: Initializing payphone script ...");
|
||||
//payPhoneRingingIndicatorImage = loadPayPhoneRingingIndicatorImage();
|
||||
payPhoneRingingSound = loadPayPhoneRingingSound();
|
||||
payPhoneDialingSound = loadPayPhoneDialingSound();
|
||||
payPhonePickupSound = loadPayPhonePickupSound();
|
||||
payPhoneHangupSound = loadPayPhoneHangupSound();
|
||||
logToConsole(LOG_DEBUG, "[V.RP.PayPhone]: Payphone script initialized!");
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function loadPayPhoneRingingIndicatorImage() {
|
||||
let imageStream = openFile(payPhoneRingingIndicatorImagePath);
|
||||
let tempImage = null;
|
||||
if (imageStream != null) {
|
||||
tempImage = graphics.loadPNG(imageStream);
|
||||
imageStream.close();
|
||||
}
|
||||
|
||||
return tempImage;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function loadPayPhoneRingingSound() {
|
||||
let soundStream = openFile(payPhoneRingingSoundFilePath);
|
||||
let tempSound = null;
|
||||
if (soundStream != null) {
|
||||
tempSound = audio.createSound(soundStream, true);
|
||||
soundStream.close();
|
||||
}
|
||||
|
||||
return tempSound;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function loadPayPhoneDialingSound() {
|
||||
let soundStream = openFile(payPhoneDialingSoundFilePath);
|
||||
let tempSound = null;
|
||||
if (soundStream != null) {
|
||||
tempSound = audio.createSound(soundStream, false);
|
||||
soundStream.close();
|
||||
}
|
||||
|
||||
if (tempSound != null) {
|
||||
tempSound.volume = 1.0;
|
||||
}
|
||||
|
||||
return tempSound;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function loadPayPhonePickupSound() {
|
||||
let soundStream = openFile(payPhonePickupSoundFilePath);
|
||||
let tempSound = null;
|
||||
if (soundStream != null) {
|
||||
tempSound = audio.createSound(soundStream, false);
|
||||
soundStream.close();
|
||||
}
|
||||
|
||||
if (tempSound != null) {
|
||||
tempSound.volume = 1.0;
|
||||
}
|
||||
|
||||
return tempSound;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function loadPayPhoneHangupSound() {
|
||||
let soundStream = openFile(payPhoneHangupSoundFilePath);
|
||||
let tempSound = null;
|
||||
if (soundStream != null) {
|
||||
tempSound = audio.createSound(soundStream, false);
|
||||
soundStream.close();
|
||||
}
|
||||
|
||||
if (tempSound != null) {
|
||||
tempSound.volume = 1.0;
|
||||
}
|
||||
|
||||
return tempSound;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function processPayPhonesDistance() {
|
||||
let tempRingingPhone = -1;
|
||||
for (let i in getServerData().payPhones) {
|
||||
if (getServerData().payPhones[i].state == V_PAYPHONE_STATE_RINGING) {
|
||||
if (getDistance(getLocalPlayerPosition(), getServerData().payPhones[i].position) <= payPhoneMaxAudibleDistance) {
|
||||
if (tempRingingPhone != -1) {
|
||||
if (getDistance(getLocalPlayerPosition(), getServerData().payPhones[i].position) <= getDistance(getLocalPlayerPosition(), getServerData().payPhones[tempRingingPhone].position)) {
|
||||
tempRingingPhone = i;
|
||||
}
|
||||
} else {
|
||||
tempRingingPhone = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tempRingingPhone == -1) {
|
||||
logToConsole(LOG_VERBOSE, "[V.RP.PayPhone]: No phones are ringing, stopping all ring sounds");
|
||||
payPhoneRingingSound.stop();
|
||||
} else {
|
||||
let distance = getDistance(getLocalPlayerPosition(), getServerData().payPhones[tempRingingPhone].position);
|
||||
let distancePercent = (payPhoneRingMaxVolume - (distance * 100 / payPhoneMaxAudibleDistance));
|
||||
payPhoneRingingSound.volume = distancePercent / 100;
|
||||
|
||||
if (ringingPayPhone == -1) {
|
||||
logToConsole(LOG_VERBOSE, "[V.RP.PayPhone]: No previous phone ringing, starting ring sound");
|
||||
payPhoneRingingSound.play();
|
||||
}
|
||||
}
|
||||
|
||||
ringingPayPhone = tempRingingPhone;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function receivePayPhoneFromServer(payPhoneId, isDeleted, state, position) {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.PayPhone] Received payphone ${payPhoneId} from server`);
|
||||
|
||||
if (!areServerElementsSupported() || getGame() == V_GAME_MAFIA_ONE || getGame() == V_GAME_GTA_IV) {
|
||||
if (isDeleted == true) {
|
||||
getServerData().payPhones.splice(payPhoneId, 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getPayPhoneData(payPhoneId) != false) {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.PayPhone] Payphone ${payPhoneId} already exists. Updating ...`);
|
||||
let payPhoneData = getPayPhoneData(payPhoneId);
|
||||
payPhoneData.state = state;
|
||||
payPhoneData.position = position;
|
||||
} else {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.PayPhone] Payphone ${payPhoneId} doesn't exist. Adding ...`);
|
||||
let tempPayPhoneData = new PayPhoneData(payPhoneId, state, position);
|
||||
getServerData().payPhones.push(tempPayPhoneData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function receivePayPhoneStateFromServer(payPhoneId, state) {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.PayPhone] Received payphone ${payPhoneId} state (${state}) from server`);
|
||||
|
||||
if (payPhoneId != -1) {
|
||||
if (getPayPhoneData(payPhoneId) == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
getPayPhoneData(payPhoneId).state = state;
|
||||
} else {
|
||||
for (let i in getServerData().payPhones) {
|
||||
getServerData().payPhones[i].state = state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
/**
|
||||
* @param {number} payPhoneId - The ID of the payphone (initially provided by server)
|
||||
* @return {PayPhoneData} The payphone's data (class instance)
|
||||
*/
|
||||
function getPayPhoneData(payPhoneId) {
|
||||
if (payPhoneId == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i in getServerData().payPhones) {
|
||||
if (getServerData().payPhones[i].payPhoneId == payPhoneId) {
|
||||
return getServerData().payPhones[i];
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function removePayPhonesFromClient() {
|
||||
clearArray(getServerData().payPhones);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function payPhoneDial() {
|
||||
logToConsole(LOG_DEBUG, "[V.RP.PayPhone]: Playing payphone dial sound");
|
||||
payPhoneDialingSound.play();
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function payPhoneHangup() {
|
||||
logToConsole(LOG_DEBUG, "[V.RP.PayPhone]: Playing payphone hangup sound");
|
||||
payPhoneHangupSound.play();
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function payPhonePickup() {
|
||||
logToConsole(LOG_DEBUG, "[V.RP.PayPhone]: Playing payphone pickup sound");
|
||||
payPhonePickupSound.play();
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -12,7 +12,7 @@ let scoreBoardListFont = null;
|
||||
|
||||
let pausedColour = COLOUR_RED;
|
||||
|
||||
let scoreboardKey = SDLK_TAB;
|
||||
let scoreBoardKey = null;
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
@@ -38,67 +38,97 @@ function initScoreBoardListFont() {
|
||||
// ===========================================================================
|
||||
|
||||
function processScoreBoardRendering() {
|
||||
if (isAnyGUIActive()) {
|
||||
if (!renderScoreBoard) {
|
||||
logToConsole(LOG_VERBOSE | LOG_ERROR, `[V.RP.ScoreBoard] Could not render scoreboard. Scoreboard rendering is disabled!`);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (renderScoreBoard) {
|
||||
if (isKeyDown(SDLK_TAB)) {
|
||||
if (scoreBoardListFont != null && scoreBoardTitleFont != null) {
|
||||
let scoreboardStart = (game.height / 2) - (Math.floor(getClients().length / 2) * 20);
|
||||
let titleSize = scoreBoardTitleFont.measure("PLAYERS", game.width, 0.0, 1.0, 10, false, false);
|
||||
scoreBoardTitleFont.render("PLAYERS", [game.width / 2, scoreboardStart - 50], 0, 0.5, 0.0, scoreBoardTitleFont.size, COLOUR_WHITE, false, false, false, true);
|
||||
if (scoreBoardListFont == null) {
|
||||
logToConsole(LOG_VERBOSE | LOG_ERROR, `[V.RP.ScoreBoard] Could not render scoreboard. List font is null!`);
|
||||
return false;
|
||||
}
|
||||
|
||||
titleSize = scoreBoardTitleFont.measure("____________________________", game.width, 0.0, 1.0, 10, false, false);
|
||||
scoreBoardTitleFont.render("____________________________", [game.width / 2, scoreboardStart - 35], 0, 0.5, 0.0, scoreBoardTitleFont.size, COLOUR_WHITE, false, false, false, true);
|
||||
if (scoreBoardTitleFont == null) {
|
||||
logToConsole(LOG_VERBOSE | LOG_ERROR, `[V.RP.ScoreBoard] Could not render scoreboard. Title font is null!`);
|
||||
return false;
|
||||
}
|
||||
|
||||
let clients = getClients();
|
||||
for (let i in clients) {
|
||||
if (!clients[i].console) {
|
||||
let name = clients[i].name;
|
||||
let colour = COLOUR_WHITE;
|
||||
let paused = false;
|
||||
let ping = "-1";
|
||||
if (isAnyGUIActive()) {
|
||||
logToConsole(LOG_VERBOSE | LOG_ERROR, `[V.RP.ScoreBoard] Could not render scoreboard. A GUI window is active!`);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (typeof playerNames[clients[i].name] != "undefined") {
|
||||
name = playerNames[clients[i].name];
|
||||
}
|
||||
if (scoreBoardKey == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (typeof playerPaused[clients[i].name] != "undefined") {
|
||||
paused = playerPaused[clients[i].name];
|
||||
}
|
||||
if (!isKeyDown(scoreBoardKey)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (typeof playerColours[clients[i].name] != "undefined") {
|
||||
colour = playerColours[clients[i].name];
|
||||
}
|
||||
let scoreboardStart = (game.height / 2) - (Math.floor(getClients().length / 2) * 20);
|
||||
let titleSize = scoreBoardTitleFont.measure("PLAYERS", game.width, 0.0, 1.0, 10, false, false);
|
||||
scoreBoardTitleFont.render("PLAYERS", [game.width / 2, scoreboardStart - 50], 0, 0.5, 0.0, scoreBoardTitleFont.size, COLOUR_WHITE, false, false, false, true);
|
||||
|
||||
if (typeof playerPing[clients[i].name] != "undefined") {
|
||||
ping = toString(playerPing[clients[i].name]);
|
||||
}
|
||||
titleSize = scoreBoardTitleFont.measure("____________________________", game.width, 0.0, 1.0, 10, false, false);
|
||||
scoreBoardTitleFont.render("____________________________", [game.width / 2, scoreboardStart - 35], 0, 0.5, 0.0, scoreBoardTitleFont.size, COLOUR_WHITE, false, false, false, true);
|
||||
|
||||
// Player ID
|
||||
let text = String(clients[i].index);
|
||||
let size = scoreBoardListFont.measure(text, 75, 0.0, 1.0, 10, false, false);
|
||||
scoreBoardListFont.render(text, [game.width / 2 - 100, scoreboardStart + (i * 20)], 0, 0.5, 0.0, scoreBoardListFont.size, COLOUR_WHITE, false, false, false, true);
|
||||
let clients = getClients();
|
||||
for (let i in clients) {
|
||||
if (!clients[i].console) {
|
||||
let name = clients[i].name;
|
||||
let colour = COLOUR_WHITE;
|
||||
let paused = false;
|
||||
let ping = "-1";
|
||||
|
||||
// Player Name
|
||||
text = name;
|
||||
size = scoreBoardListFont.measure(text, 100, 0.0, 1.0, 10, false, false);
|
||||
scoreBoardListFont.render(text, [game.width / 2, scoreboardStart + (i * 20)], 0, 0.5, 0.0, scoreBoardListFont.size, colour, false, false, false, true);
|
||||
if (typeof playerNames[clients[i].name] != "undefined") {
|
||||
name = playerNames[clients[i].name];
|
||||
}
|
||||
|
||||
// Ping
|
||||
text = ping;
|
||||
size = scoreBoardListFont.measure(ping, 75, 0.0, 1.0, 10, false, false);
|
||||
scoreBoardListFont.render(ping, [game.width / 2 + 100, scoreboardStart + (i * 20)], 0, 0.5, 0.0, scoreBoardListFont.size, COLOUR_WHITE, false, false, false, true);
|
||||
if (typeof playerPaused[clients[i].name] != "undefined") {
|
||||
paused = playerPaused[clients[i].name];
|
||||
}
|
||||
|
||||
// PAUSED Status (depends on resource "afk")
|
||||
if (paused == true) {
|
||||
size = scoreBoardListFont.measure("PAUSED", 100, 0.0, 1.0, 10, false, false);
|
||||
scoreBoardListFont.render("PAUSED", [game.width / 2 + 200, scoreboardStart + (i * 20)], 0, 0.5, 0.0, scoreBoardListFont.size, pausedColour, false, false, false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (typeof playerColours[clients[i].name] != "undefined") {
|
||||
colour = playerColours[clients[i].name];
|
||||
}
|
||||
|
||||
if (typeof playerPing[clients[i].name] != "undefined") {
|
||||
ping = toString(playerPing[clients[i].name]);
|
||||
}
|
||||
|
||||
// Player ID
|
||||
let text = String(clients[i].index);
|
||||
let size = scoreBoardListFont.measure(text, 75, 0.0, 1.0, 10, false, false);
|
||||
scoreBoardListFont.render(text, [game.width / 2 - 100, scoreboardStart + (i * 20)], 0, 0.5, 0.0, scoreBoardListFont.size, COLOUR_WHITE, false, false, false, true);
|
||||
|
||||
// Player Name
|
||||
text = name;
|
||||
size = scoreBoardListFont.measure(text, 100, 0.0, 1.0, 10, false, false);
|
||||
scoreBoardListFont.render(text, [game.width / 2, scoreboardStart + (i * 20)], 0, 0.5, 0.0, scoreBoardListFont.size, colour, false, false, false, true);
|
||||
|
||||
// Ping
|
||||
text = ping;
|
||||
size = scoreBoardListFont.measure(ping, 75, 0.0, 1.0, 10, false, false);
|
||||
scoreBoardListFont.render(ping, [game.width / 2 + 100, scoreboardStart + (i * 20)], 0, 0.5, 0.0, scoreBoardListFont.size, COLOUR_WHITE, false, false, false, true);
|
||||
|
||||
// PAUSED Status (depends on resource "afk")
|
||||
if (paused == true) {
|
||||
size = scoreBoardListFont.measure("PAUSED", 100, 0.0, 1.0, 10, false, false);
|
||||
scoreBoardListFont.render("PAUSED", [game.width / 2 + 200, scoreboardStart + (i * 20)], 0, 0.5, 0.0, scoreBoardListFont.size, pausedColour, false, false, false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function setScoreBoardKey(key) {
|
||||
if (key == -1) {
|
||||
scoreBoardKey = null;
|
||||
} else {
|
||||
scoreBoardKey = toInteger(key);
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -22,8 +22,13 @@ function initClientScripts() {
|
||||
initSkinSelectScript();
|
||||
initCursorScript();
|
||||
initCustomHUDScript();
|
||||
initPayPhoneScript();
|
||||
initTimersScript();
|
||||
initJobScript();
|
||||
|
||||
addAllNetworkHandlers();
|
||||
|
||||
initTimers();
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
@@ -49,15 +49,9 @@ function processSync(event, deltaTime) {
|
||||
// ===========================================================================
|
||||
|
||||
function setVehicleLights(vehicleId, state) {
|
||||
//if (getGame() == V_GAME_GTA_IV) {
|
||||
// if (!state) {
|
||||
// natives.forceCarLights(natives.getVehicleFromNetworkId(vehicleId, 0));
|
||||
// } else {
|
||||
// natives.forceCarLights(natives.getVehicleFromNetworkId(vehicleId, 1));
|
||||
// }
|
||||
//} else {
|
||||
getElementFromId(vehicleId).lights = state;
|
||||
//}
|
||||
if (getElementFromId(vehicleId) != null) {
|
||||
getElementFromId(vehicleId).lights = state;
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
20
scripts/client/timers.js
Normal file
20
scripts/client/timers.js
Normal file
@@ -0,0 +1,20 @@
|
||||
// ===========================================================================
|
||||
// Vortrex's Roleplay Resource
|
||||
// https://github.com/VortrexFTW/v-roleplay
|
||||
// ===========================================================================
|
||||
// FILE: timers.js
|
||||
// DESC: Provides timer functions and usage
|
||||
// TYPE: Client (JavaScript)
|
||||
// ===========================================================================
|
||||
|
||||
function initTimersScript() {
|
||||
logToConsole(LOG_DEBUG, "[V.RP.Timers]: Initializing timer script ...");
|
||||
logToConsole(LOG_DEBUG, "[V.RP.Timers]: Timers script initialized!");
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function initTimers() {
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -28,20 +28,12 @@ function setLocalPlayerControlState(controlState, cursorState = false) {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function fadeLocalCamera(state, duration, colour) {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Utilities] Fading camera ${(state) ? "in" : "out"} for ${duration}ms`);
|
||||
|
||||
cameraFadeDuration = duration;
|
||||
cameraFadeStart = sdl.ticks;
|
||||
cameraFadeIn = state;
|
||||
cameraFadeColour = colour;
|
||||
cameraFadeAlpha = (state) ? 255 : 0;
|
||||
cameraFadeEnabled = true;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function removeLocalPlayerFromVehicle() {
|
||||
if (getGame() == V_GAME_MAFIA_ONE) {
|
||||
localPlayer.removeFromVehicle(localPlayer.vehicle, 0);
|
||||
localPlayer.position = getPosAbovePos(localPlayer.position, 5);
|
||||
}
|
||||
|
||||
localPlayer.removeFromVehicle();
|
||||
}
|
||||
|
||||
@@ -405,36 +397,6 @@ function processWantedLevelReset() {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function processLocalPlayerVehicleControlState() {
|
||||
if (areServerElementsSupported()) {
|
||||
if (localPlayer.vehicle != null) {
|
||||
if (doesEntityDataExist(localPlayer.vehicle, "v.rp.engine")) {
|
||||
if (getEntityData(localPlayer.vehicle, "v.rp.engine") == false) {
|
||||
if (localPlayer.vehicle.engine == true) {
|
||||
localPlayer.vehicle.engine = false;
|
||||
}
|
||||
//localPlayer.vehicle.netFlags.sendSync = false;
|
||||
if (!localPlayer.vehicle.engine) {
|
||||
if (typeof localPlayer.vehicle.velocity != "undefined") {
|
||||
localPlayer.vehicle.velocity = toVector3(0.0, 0.0, 0.0);
|
||||
localPlayer.vehicle.turnVelocity = toVector3(0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
//if (parkedVehiclePosition) {
|
||||
// localPlayer.vehicle.position = parkedVehiclePosition;
|
||||
// localPlayer.vehicle.heading = parkedVehicleHeading;
|
||||
//}
|
||||
}
|
||||
} else {
|
||||
//localPlayer.vehicle.netFlags.sendSync = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function forceLocalPlayerEquippedWeaponItem() {
|
||||
if (typeof localPlayer.weapon != "undefined") {
|
||||
if (forceWeapon != 0) {
|
||||
@@ -631,4 +593,32 @@ function setLocalPlayerMoney(amount) {
|
||||
updateLocalPlayerMoney();
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function fixOffScreenPosition(position, margin = toVector2(0.0, 0.0)) {
|
||||
if (position.x <= 0) {
|
||||
position.x = 0.0 + (margin.x / 2);
|
||||
} else if (position.x > game.width) {
|
||||
position.x = game.width - (margin.x / 2);
|
||||
}
|
||||
|
||||
if (position.y <= 0) {
|
||||
position.y = 0.0 + (margin.y / 2);
|
||||
} else if (position.y > game.height) {
|
||||
position.y = game.height - (margin.y / 2);
|
||||
}
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function processMapChangeWarning() {
|
||||
if (mapChangeWarning == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
smallGameMessageFonts["AuroraBdCnBT"].render(`Map is changing to ${(mapChangeToNight) ? "night" : "day"} soon!`, [0, game.height - 90], game.width, 0.5, 0.0, smallGameMessageFonts["AuroraBdCnBT"].size, getColourByName("yellow"), true, true, false, true);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -171,4 +171,27 @@ function removeVehiclesFromClient() {
|
||||
getServerData().vehicles.splice(0);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function processLocalPlayerVehicleControlState() {
|
||||
if (areServerElementsSupported()) {
|
||||
if (localPlayer.vehicle != null) {
|
||||
if (doesEntityDataExist(localPlayer.vehicle, "v.rp.engine")) {
|
||||
if (getEntityData(localPlayer.vehicle, "v.rp.engine") == false) {
|
||||
setImmediate(function () {
|
||||
localPlayer.vehicle.engine = getEntityData(localPlayer.vehicle, "v.rp.engine");
|
||||
});
|
||||
|
||||
if (!getEntityData(localPlayer.vehicle, "v.rp.engine")) {
|
||||
if (typeof localPlayer.vehicle.velocity != "undefined") {
|
||||
localPlayer.vehicle.velocity = toVector3(0.0, 0.0, 0.0);
|
||||
localPlayer.vehicle.turnVelocity = toVector3(0.0, 0.0, 0.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -48,6 +48,7 @@ class AccountData {
|
||||
this.databaseId = 0;
|
||||
this.name = "";
|
||||
this.password = "";
|
||||
this.passwordRevision = 0;
|
||||
this.registerDate = 0;
|
||||
this.flags = {
|
||||
moderation: 0,
|
||||
@@ -78,6 +79,7 @@ class AccountData {
|
||||
this.databaseId = toInteger(dbAssoc["acct_id"]);
|
||||
this.name = toString(dbAssoc["acct_name"]);
|
||||
this.password = toString(dbAssoc["acct_pass"]);
|
||||
this.passwordRevision = toString(dbAssoc["acct_pass_revision"]);
|
||||
this.registerDate = toInteger(dbAssoc["acct_when_registered"]);
|
||||
this.flags = {
|
||||
moderation: toInteger(dbAssoc["acct_svr_mod_flags"]),
|
||||
@@ -614,6 +616,13 @@ function verifyAccountEmailCommand(command, params, client) {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function resetActionTipsCommand(command, params, client) {
|
||||
getPlayerData(client).promptType = V_PROMPT_RESETACTIONTIPS;
|
||||
showPlayerPrompt(client, getLocaleString(client, "ResetActionTipsConfirm"), getLocaleString(client, "GUIWarningTitle"), getLocaleString(client, "Yes"), getLocaleString(client, "No"));
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
/*
|
||||
function resetAccountPasswordCommand(command, params, client) {
|
||||
if(areParamsEmpty(params)) {
|
||||
@@ -802,7 +811,7 @@ function getAccountHashingFunction() {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
async function isNameRegistered(name) {
|
||||
function isNameRegistered(name) {
|
||||
let accountData = loadAccountFromName(name, true);
|
||||
if (accountData.databaseId > 0) {
|
||||
return true;
|
||||
@@ -813,16 +822,21 @@ async function isNameRegistered(name) {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function hashAccountPassword(name, password) {
|
||||
function hashAccountPassword(name, password, revision = 0) {
|
||||
let hashFunction = getAccountHashingFunction();
|
||||
let saltedInfo = saltAccountInfo(name, password);
|
||||
let saltedInfo = saltAccountInfo(name, password, revision);
|
||||
return hashFunction(saltedInfo);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function saltAccountInfo(name, password) {
|
||||
return `ag.gaming.${accountSaltHash}.${name}.${password}`;
|
||||
function saltAccountInfo(name, password, revision = 0) {
|
||||
let tempString = getSecurityConfig().accountPasswordSaltAlgorithm[revision];
|
||||
|
||||
tempString = tempString.replace("{NAME}", name);
|
||||
tempString = tempString.replace("{PASSWORD}", password);
|
||||
tempString = tempString.replace("{SALTHASH}", getSecurityConfig().accountSaltHash[revision]);
|
||||
return tempString;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -915,6 +929,7 @@ function saveAccountToDatabase(accountData) {
|
||||
["acct_streaming_radio_volume", accountData.streamingRadioVolume],
|
||||
["acct_ip", accountData.ipAddress],
|
||||
["acct_locale", accountData.locale],
|
||||
["acct_pass_revision", accountData.passwordRevision],
|
||||
];
|
||||
|
||||
let data2 = [
|
||||
@@ -1070,15 +1085,15 @@ function saveAccountContactsToDatabase(accountContactData) {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function createAccount(name, password, email = "") {
|
||||
function createAccount(name, password, email = "", passwordRevision = 0) {
|
||||
let dbConnection = connectToDatabase();
|
||||
|
||||
if (dbConnection) {
|
||||
let hashedPassword = hashAccountPassword(name, password);
|
||||
let hashedPassword = hashAccountPassword(name, password, passwordRevision);
|
||||
let safeName = escapeDatabaseString(dbConnection, name);
|
||||
let safeEmail = escapeDatabaseString(dbConnection, email);
|
||||
|
||||
let dbQuery = queryDatabase(dbConnection, `INSERT INTO acct_main (acct_name, acct_pass, acct_email, acct_when_registered) VALUES ('${safeName}', '${hashedPassword}', '${safeEmail}', CURRENT_TIMESTAMP())`);
|
||||
let dbQuery = queryDatabase(dbConnection, `INSERT INTO acct_main (acct_name, acct_pass, acct_email, acct_when_registered, acct_pass_revision) VALUES ('${safeName}', '${hashedPassword}', '${safeEmail}', UNIX_TIMESTAMP(), ${passwordRevision})`);
|
||||
if (getDatabaseInsertId(dbConnection) > 0) {
|
||||
let insertId = getDatabaseInsertId(dbConnection);
|
||||
createDefaultAccountServerData(insertId);
|
||||
@@ -1478,6 +1493,8 @@ function savePlayerToDatabase(client) {
|
||||
}
|
||||
}
|
||||
|
||||
getPlayerCurrentSubAccount(client).payDayAmount = getPlayerData(client).payDayAmount;
|
||||
|
||||
saveSubAccountToDatabase(getPlayerCurrentSubAccount(client));
|
||||
}
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Account]: Saved client ${getPlayerDisplayForConsole(client)} to database successfully!`);
|
||||
@@ -1732,34 +1749,34 @@ function generateEmailVerificationCode() {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
async function sendEmailVerificationEmail(client, emailVerificationCode) {
|
||||
function sendEmailVerificationEmail(client, emailVerificationCode) {
|
||||
let emailBodyText = getEmailConfig().bodyContent.confirmEmail;
|
||||
emailBodyText = emailBodyText.replace("{VERIFICATIONCODE}", emailVerificationCode);
|
||||
emailBodyText = emailBodyText.replace("{SERVERNAME}", getServerName());
|
||||
|
||||
await sendEmail(getPlayerData(client).accountData.emailAddress, getPlayerData(client).accountData.name, `Confirm email on ${getServerName()}`, emailBodyText);
|
||||
sendEmail(getPlayerData(client).accountData.emailAddress, getPlayerData(client).accountData.name, `Confirm email on ${getServerName()}`, emailBodyText);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
async function sendPasswordResetEmail(client, verificationCode) {
|
||||
function sendPasswordResetEmail(client, verificationCode) {
|
||||
let emailBodyText = getEmailConfig().bodyContent.confirmPasswordReset;
|
||||
emailBodyText = emailBodyText.replace("{VERIFICATIONCODE}", verificationCode);
|
||||
emailBodyText = emailBodyText.replace("{SERVERNAME}", getServerName());
|
||||
|
||||
await sendEmail(getPlayerData(client).accountData.emailAddress, getPlayerData(client).accountData.name, `Reset your password on ${getServerName()}`, emailBodyText);
|
||||
sendEmail(getPlayerData(client).accountData.emailAddress, getPlayerData(client).accountData.name, `Reset your password on ${getServerName()}`, emailBodyText);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
async function verifyAccountEmail(accountData, verificationCode) {
|
||||
function verifyAccountEmail(accountData, verificationCode) {
|
||||
let emailVerificationCode = generateRandomString(10);
|
||||
|
||||
let emailBodyText = getEmailConfig().bodyContent.confirmEmail;
|
||||
emailBodyText = emailBodyText.replace("{VERIFICATIONCODE}", emailVerificationCode);
|
||||
emailBodyText = emailBodyText.replace("{SERVERNAME}", getServerName());
|
||||
|
||||
await sendEmail(getPlayerData(client).accountData.emailAddress, getPlayerData(client).accountData.name, `Confirm email on ${getServerName()}`, emailBodyText);
|
||||
sendEmail(getPlayerData(client).accountData.emailAddress, getPlayerData(client).accountData.name, `Confirm email on ${getServerName()}`, emailBodyText);
|
||||
|
||||
getPlayerData(client).accountData.emailAddress = emailAddress;
|
||||
getPlayerData(client).accountData.emailVerificationCode = module.hashing.sha512(emailVerificationCode);
|
||||
@@ -1767,7 +1784,7 @@ async function verifyAccountEmail(accountData, verificationCode) {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
async function sendAccountLoginFailedNotification(emailAddress, name, ip, game = getGame()) {
|
||||
function sendAccountLoginFailedNotification(emailAddress, name, ip, game = getGame()) {
|
||||
let countryName = module.geoip.getCountryName(getGlobalConfig().geoIPCountryDatabaseFilePath, ip);
|
||||
let subDivisionName = module.geoip.getSubdivisionName(getGlobalConfig().geoIPCityDatabaseFilePath, ip);
|
||||
let cityName = module.geoip.getCityName(getGlobalConfig().geoIPCityDatabaseFilePath, ip);
|
||||
@@ -1779,13 +1796,13 @@ async function sendAccountLoginFailedNotification(emailAddress, name, ip, game =
|
||||
emailBodyText = emailBodyText.replace("{SERVERNAME}", getServerName());
|
||||
emailBodyText = emailBodyText.replace("{TIMESTAMP}", new Date().toLocaleString('en-US'));
|
||||
|
||||
await sendEmail(emailAddress, name, `Login failed on ${getServerName()}`, emailBodyText);
|
||||
sendEmail(emailAddress, name, `Login failed on ${getServerName()}`, emailBodyText);
|
||||
return true;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
async function sendAccountLoginSuccessNotification(emailAddress, name, ip, game = getGame()) {
|
||||
function sendAccountLoginSuccessNotification(emailAddress, name, ip, game = getGame()) {
|
||||
let countryName = module.geoip.getCountryName(getGlobalConfig().geoIPCountryDatabaseFilePath, ip);
|
||||
let subDivisionName = module.geoip.getSubdivisionName(getGlobalConfig().geoIPCityDatabaseFilePath, ip);
|
||||
let cityName = module.geoip.getCityName(getGlobalConfig().geoIPCityDatabaseFilePath, ip);
|
||||
@@ -1797,7 +1814,7 @@ async function sendAccountLoginSuccessNotification(emailAddress, name, ip, game
|
||||
emailBodyText = emailBodyText.replace("{SERVERNAME}", getServerName());
|
||||
emailBodyText = emailBodyText.replace("{TIMESTAMP}", new Date().toLocaleString('en-US'));
|
||||
|
||||
await sendEmail(emailAddress, name, `Login successful on ${getServerName()}`, emailBodyText);
|
||||
sendEmail(emailAddress, name, `Login successful on ${getServerName()}`, emailBodyText);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1843,13 +1860,13 @@ function isPlayerATester(client) {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
async function sendAccountTwoFactorAuthCode(emailAddress, name, twoFactorAuthCode) {
|
||||
function sendAccountTwoFactorAuthCode(emailAddress, name, twoFactorAuthCode) {
|
||||
let emailBodyText = getEmailConfig().bodyContent.twoFactorAuthentication;
|
||||
emailBodyText = emailBodyText.replace("{2FACODE}", twoFactorAuthCode);
|
||||
emailBodyText = emailBodyText.replace("{GAMENAME}", getGameName(getGame()));
|
||||
emailBodyText = emailBodyText.replace("{SERVERNAME}", getServerName());
|
||||
|
||||
await sendEmail(emailAddress, name, `Login code for ${getServerName()}`, emailBodyText);
|
||||
sendEmail(emailAddress, name, `Login code for ${getServerName()}`, emailBodyText);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ let serverBitFlagKeys = {
|
||||
"Developer",
|
||||
"ManageNPCs",
|
||||
"ManageRaces",
|
||||
"ManagePayPhones",
|
||||
],
|
||||
moderationFlagKeys: [
|
||||
"None",
|
||||
@@ -261,14 +262,14 @@ let serverBitFlagKeys = {
|
||||
"EnterJobVehicleForRoute",
|
||||
"JobLocations",
|
||||
"JobRouteStart",
|
||||
"PayPhoneFirstUse",
|
||||
],
|
||||
jobRankKeys: [
|
||||
jobFlagKeys: [
|
||||
"None",
|
||||
"PublicAccess",
|
||||
"WhiteList",
|
||||
"BlackList",
|
||||
"AddMember",
|
||||
"RemoveMember",
|
||||
"SuspendMember",
|
||||
"SetRank",
|
||||
"SetPay",
|
||||
"ManageUniforms",
|
||||
"ManageEquipment",
|
||||
"ManageVehicles",
|
||||
@@ -293,7 +294,7 @@ function initBitFlagScript() {
|
||||
serverBitFlags.npcTriggerConditionTypes = createBitFlagTable(serverBitFlagKeys.npcTriggerConditionTypeKeys);
|
||||
serverBitFlags.npcTriggerResponseTypes = createBitFlagTable(serverBitFlagKeys.npcTriggerResponseTypeKeys);
|
||||
serverBitFlags.seenActionTips = createBitFlagTable(serverBitFlagKeys.seenActionTipsKeys);
|
||||
serverBitFlags.jobRankFlags = createBitFlagTable(serverBitFlagKeys.jobRankKeys);
|
||||
serverBitFlags.jobFlags = createBitFlagTable(serverBitFlagKeys.jobFlagKeys);
|
||||
logToConsole(LOG_INFO, "[V.RP.BitFlag]: Bit flag script initialized successfully!");
|
||||
return true;
|
||||
}
|
||||
@@ -420,6 +421,20 @@ function getClanFlagValue(flagName) {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function getJobFlagValue(flagName) {
|
||||
if (flagName == "All") {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (typeof getServerBitFlags().jobFlags[flagName] == "undefined") {
|
||||
return false;
|
||||
}
|
||||
|
||||
return getServerBitFlags().jobFlags[flagName];
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function getAccountSettingsFlagValue(flagName) {
|
||||
if (flagName == "All") {
|
||||
return -1;
|
||||
|
||||
@@ -224,7 +224,7 @@ function loadBusinessesFromDatabase() {
|
||||
if (dbAssoc.length > 0) {
|
||||
for (let i in dbAssoc) {
|
||||
let tempBusinessData = new BusinessData(dbAssoc[i]);
|
||||
tempBusinessData.locations = loadBusinessLocationsFromDatabase(tempBusinessData.databaseId);
|
||||
//tempBusinessData.locations = loadBusinessLocationsFromDatabase(tempBusinessData.databaseId);
|
||||
//tempBusinessData.gameScripts = loadBusinessGameScriptsFromDatabase(tempBusinessData.databaseId);
|
||||
tempBusinesses.push(tempBusinessData);
|
||||
logToConsole(LOG_VERBOSE, `[V.RP.Business]: Business '${tempBusinessData.name}' (ID ${tempBusinessData.databaseId}) loaded from database successfully!`);
|
||||
@@ -1114,6 +1114,8 @@ function setBusinessInteriorTypeCommand(command, params, client) {
|
||||
getBusinessData(businessId).exitScene = "";
|
||||
getBusinessData(businessId).exitPickupModel = -1;
|
||||
getBusinessData(businessId).customInterior = false;
|
||||
getBusinessData(businessId).exitScene = "";
|
||||
getBusinessData(businessId).entranceScene = "";
|
||||
messageAdmins(`{adminOrange}${getPlayerName(client)}{MAINCOLOUR} removed business {businessBlue}${getBusinessData(businessId).name}{MAINCOLOUR} interior`, true);
|
||||
return false;
|
||||
}
|
||||
@@ -1138,11 +1140,8 @@ function setBusinessInteriorTypeCommand(command, params, client) {
|
||||
getBusinessData(businessId).customInterior = getGameConfig().interiors[getGame()][typeParam][2];
|
||||
|
||||
if (isGameFeatureSupported("interiorScene")) {
|
||||
if (isMainWorldScene(getPlayerData(client).scene)) {
|
||||
getBusinessData(businessId).exitScene = getGameConfig().mainWorldScene[getGame()];
|
||||
} else {
|
||||
getBusinessData(businessId).exitScene = getGameConfig().interiors[getGame()][typeParam][3];
|
||||
}
|
||||
getBusinessData(businessId).exitScene = getGameConfig().interiors[getGame()][typeParam][3];
|
||||
getBusinessData(businessId).entranceScene = getPlayerData(client).scene;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1287,6 +1286,8 @@ function giveDefaultItemsToBusinessCommand(command, params, client) {
|
||||
return false;
|
||||
}
|
||||
|
||||
saveBusinessToDatabase(businessId);
|
||||
|
||||
if (isNull(getGameConfig().defaultBusinessItems[getGame()][typeParam])) {
|
||||
messagePlayerError(client, "Invalid business items type! Use a business items type name");
|
||||
let businessItemTypes = Object.keys(getGameConfig().defaultBusinessItems[getGame()]);
|
||||
@@ -2021,7 +2022,7 @@ function spawnBusinessEntrancePickup(businessId) {
|
||||
// return false;
|
||||
//}
|
||||
|
||||
logToConsole(LOG_VERBOSE, `[V.RP.Job]: Creating entrance pickup for business ${businessData.name}`);
|
||||
logToConsole(LOG_VERBOSE, `[V.RP.Business]: Creating entrance pickup for business ${businessData.name} (${businessData.databaseId})`);
|
||||
|
||||
if (areServerElementsSupported() && getGame() != V_GAME_MAFIA_ONE && getGame() != V_GAME_GTA_IV) {
|
||||
let entrancePickup = null;
|
||||
@@ -2271,9 +2272,8 @@ function deleteBusiness(businessId, whoDeleted = 0) {
|
||||
}
|
||||
|
||||
removePlayersFromBusiness(businessId);
|
||||
|
||||
getServerData().businesses.splice(businessId, 1);
|
||||
updateBusinessPickupLabelData(businessId);
|
||||
updateBusinessPickupLabelData(businessId, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -2619,6 +2619,14 @@ function buyFromBusinessCommand(command, params, client) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let useType = getItemTypeData(getItemData(getBusinessData(businessId).floorItemCache[itemSlot - 1]).itemTypeIndex).useType;
|
||||
if (useType == V_ITEM_USE_TYPE_WEAPON || V_ITEM_USE_TYPE_TAZER || useType == V_ITEM_USE_TYPE_AMMO_CLIP) {
|
||||
if (isPlayerWeaponBanned(client) && !isPlayerExemptFromAntiCheat(client)) {
|
||||
messagePlayerError(client, getLocaleString(client, "WeaponBanned"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
let amount = 1;
|
||||
if (areThereEnoughParams(params, 2, " ")) {
|
||||
amount = toInteger(getParam(params, " ", 2)) || 1;
|
||||
@@ -2643,12 +2651,12 @@ function buyFromBusinessCommand(command, params, client) {
|
||||
let itemName = getItemTypeData(getItemData(getBusinessData(businessId).floorItemCache[itemSlot - 1]).itemTypeIndex).name;
|
||||
|
||||
if (getPlayerCurrentSubAccount(client).cash < totalCost) {
|
||||
messagePlayerError(client, getLocaleString(client, "NotEnoughCashNeedAmountMore", `{ALTCOLOUR}${getBusinessData(businessId).floorItemCache[itemSlot - 1].buyPrice * amount - getPlayerCurrentSubAccount(client).cash}{MAINCOLOUR}`));
|
||||
messagePlayerError(client, getLocaleString(client, "NotEnoughCashNeedAmountMore", `{ALTCOLOUR}${totalCost - getPlayerCurrentSubAccount(client).cash}{MAINCOLOUR}`));
|
||||
return false;
|
||||
}
|
||||
|
||||
takePlayerCash(client, totalCost);
|
||||
createItem(getItemData(getBusinessData(businessId).floorItemCache[itemSlot - 1]).itemTypeIndex, getItemData(getBusinessData(businessId).floorItemCache[itemSlot - 1]).value, V_ITEM_OWNER_PLAYER, getPlayerCurrentSubAccount(client).databaseId, amount);
|
||||
let itemIndex = createItem(getItemData(getBusinessData(businessId).floorItemCache[itemSlot - 1]).itemTypeIndex, getItemData(getBusinessData(businessId).floorItemCache[itemSlot - 1]).value, V_ITEM_OWNER_PLAYER, getPlayerCurrentSubAccount(client).databaseId, amount);
|
||||
cachePlayerHotBarItems(client);
|
||||
getBusinessData(businessId).till = getBusinessData(businessId).till + totalCost;
|
||||
|
||||
@@ -2657,14 +2665,6 @@ function buyFromBusinessCommand(command, params, client) {
|
||||
deleteItem(getBusinessData(businessId).floorItemCache[itemSlot - 1]);
|
||||
}
|
||||
|
||||
let useType = getItemTypeData(getItemData(getBusinessData(businessId).floorItemCache[itemSlot - 1]).itemTypeIndex).useType;
|
||||
if (useType == V_ITEM_USE_TYPE_WEAPON || V_ITEM_USE_TYPE_TAZER || useType == V_ITEM_USE_TYPE_AMMO_CLIP) {
|
||||
if (isPlayerWeaponBanned(client) && !isPlayerExemptFromAntiCheat(client)) {
|
||||
messagePlayerError(client, getLocaleString(client, "WeaponBanned"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//messagePlayerSuccess(client, `You bought ${amount} {ALTCOLOUR}${itemName} {MAINCOLOUR}for ${totalCost} ${priceEach}`);
|
||||
meActionToNearbyPlayers(client, `buys a ${itemName}`);
|
||||
|
||||
@@ -2677,7 +2677,7 @@ function buyFromBusinessCommand(command, params, client) {
|
||||
}
|
||||
}
|
||||
|
||||
markPlayerActionTipSeen(client, "ViewInventory");
|
||||
logBusinessItemPurchase(getBusinessData(businessId).databaseId, getPlayerCurrentSubAccount(client).databaseId, getItemData(itemIndex).databaseId);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -2720,7 +2720,7 @@ function setBusinessItemSellPriceCommand(command, params, client) {
|
||||
|
||||
getItemData(getBusinessData(businessId).floorItemCache[itemSlot - 1]).buyPrice = newPrice;
|
||||
|
||||
messagePlayerSuccess(client, `You changed the price of the {ALTCOLOUR}${getItemTypeData(getItemData(getBusinessData(businessId).floorItemCache[itemSlot - 1]).itemTypeIndex).name}'s {MAINCOLOUR}in slot {ALTCOLOUR}${itemSlot} {MAINCOLOUR}from ${getCurrencyString(oldPrice)} to ${getCurrencyString(newprice)}`);
|
||||
messagePlayerSuccess(client, `You changed the price of the {ALTCOLOUR}${getItemTypeData(getItemData(getBusinessData(businessId).floorItemCache[itemSlot - 1]).itemTypeIndex).name}'s {MAINCOLOUR}in slot {ALTCOLOUR}${itemSlot} {MAINCOLOUR}from ${getCurrencyString(oldPrice)} to ${getCurrencyString(newPrice)}`);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -2870,12 +2870,18 @@ function getBusinessIdFromDatabaseId(databaseId) {
|
||||
// ===========================================================================
|
||||
|
||||
// Updates all pickup data for a business by businessId
|
||||
function updateBusinessPickupLabelData(businessId) {
|
||||
function updateBusinessPickupLabelData(businessId, deleted = false) {
|
||||
let businessData = false;
|
||||
|
||||
if (deleted == false) {
|
||||
businessData = getBusinessData(businessId);
|
||||
}
|
||||
|
||||
if (!areServerElementsSupported() || getGame() == V_GAME_MAFIA_ONE || getGame() == V_GAME_GTA_IV) {
|
||||
if (getBusinessData(businessId) == false) {
|
||||
sendBusinessToPlayer(null, businessId, true, "", false, -1, -1, 0, 0, false, false, false);
|
||||
if (businessData == false) {
|
||||
sendBusinessToPlayer(null, businessId, true, "", false, -1, -1, 0, 0, false, false, false, 0);
|
||||
} else {
|
||||
sendBusinessToPlayer(null, businessId, false, getBusinessData(businessId).name, getBusinessData(businessId).entrancePosition, getBusinessEntranceBlipModelForNetworkEvent(businessId), getBusinessEntrancePickupModelForNetworkEvent(businessId), getBusinessData(businessId).buyPrice, getBusinessData(businessId).rentPrice, getBusinessData(businessId).hasInterior, getBusinessData(businessId).locked, doesBusinessHaveAnyItemsToBuy(businessId));
|
||||
sendBusinessToPlayer(null, businessId, false, businessData.name, businessData.entrancePosition, getBusinessEntranceBlipModelForNetworkEvent(businessId), getBusinessEntrancePickupModelForNetworkEvent(businessId), businessData.buyPrice, businessData.rentPrice, businessData.hasInterior, businessData.locked, doesBusinessHaveAnyItemsToBuy(businessId), businessData.entranceFee);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -3242,4 +3248,61 @@ function getBusinessEntrancePickupModelForNetworkEvent(businessIndex) {
|
||||
return pickupModelId;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function getBusinessesInRange(position, distance) {
|
||||
return getServerData().businesses.filter((business) => getDistance(position, business.entrancePosition) <= distance);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function getNearbyBusinessesCommand(command, params, client) {
|
||||
let distance = 10.0;
|
||||
|
||||
if (!areParamsEmpty(params)) {
|
||||
distance = getParam(params, " ", 1);
|
||||
}
|
||||
|
||||
if (isNaN(distance)) {
|
||||
messagePlayerError(client, "The distance must be a number!");
|
||||
return false;
|
||||
}
|
||||
|
||||
distance = toFloat(distance);
|
||||
|
||||
if (distance <= 0) {
|
||||
messagePlayerError(client, "The distance must be more than 0!");
|
||||
return false;
|
||||
}
|
||||
|
||||
let nearbyBusinesses = getBusinessesInRange(getPlayerPosition(client), distance);
|
||||
|
||||
if (nearbyBusinesses.length == 0) {
|
||||
messagePlayerAlert(client, getLocaleString(client, "NoBusinessesWithinRange", distance));
|
||||
return false;
|
||||
}
|
||||
|
||||
let businessesList = nearbyBusinesses.map(function (x) {
|
||||
return `{chatBoxListIndex}${x.index}: {MAINCOLOUR}${x.name} {mediumGrey}(${toFloat(getDistance(getPlayerPosition(client), x.entrancePosition)).toFixed(2)} ${toLowerCase(getLocaleString(client, "Meters"))} ${toLowerCase(getGroupedLocaleString(client, "CardinalDirections", getCardinalDirectionName(getCardinalDirection(getPlayerPosition(client), x.entrancePosition))))})`;
|
||||
});
|
||||
let chunkedList = splitArrayIntoChunks(businessesList, 4);
|
||||
|
||||
messagePlayerNormal(client, makeChatBoxSectionHeader(getLocaleString(client, "HeaderBusinessesInRangeList", `${distance} ${toLowerCase(getLocaleString(client, "Meters"))}`)));
|
||||
for (let i in chunkedList) {
|
||||
messagePlayerInfo(client, chunkedList[i].join(", "));
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function logBusinessItemPurchase(businessId, purchaserId, itemId) {
|
||||
if (getServerConfig().devServer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
quickDatabaseQuery(`INSERT INTO log_biz_buy (log_biz_buy_biz, log_biz_buy_who, log_biz_buy_item, log_biz_buy_when) VALUES (${businessId}, ${purchaserId}, ${itemId}, UNIX_TIMESTAMP())`);
|
||||
|
||||
logItemMove(itemId, V_ITEM_OWNER_BIZFLOOR, businessId, V_ITEM_OWNER_PLAYER, purchaserId)
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -50,14 +50,35 @@ function processPlayerChat(client, messageText) {
|
||||
|
||||
messageText = messageText.substring(0, 128);
|
||||
|
||||
switch (getGlobalConfig().mainChatType) {
|
||||
if (getPlayerData(client).usingPayPhone != -1 && getPayPhoneData(getPlayerData(client).usingPayPhone).state == V_PAYPHONE_STATE_ACTIVE_CALL) {
|
||||
messagePlayerPhoneCall(client, getPlayerData(client).payPhoneOtherPlayer, messageText);
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (getServerConfig().normalChatType) {
|
||||
case V_CHAT_TYPE_TALK:
|
||||
talkToNearbyPlayers(client, messageText);
|
||||
break;
|
||||
|
||||
case V_CHAT_TYPE_SHOUT:
|
||||
shoutToNearbyPlayers(client, messageText);
|
||||
break;
|
||||
|
||||
case V_CHAT_TYPE_WHISPER:
|
||||
whisperToNearbyPlayers(client, messageText);
|
||||
break;
|
||||
|
||||
case V_CHAT_TYPE_LOCAL:
|
||||
oocToNearbyPlayers(client, messageText);
|
||||
break;
|
||||
|
||||
case V_CHAT_TYPE_NONE:
|
||||
messagePlayerError(client, getLocaleString(client, "NormalChatDisabled"));
|
||||
break;
|
||||
|
||||
case V_CHAT_TYPE_GLOBAL:
|
||||
default:
|
||||
chatToAllPlayers(client, messageTest);
|
||||
oocToAllPlayers(client, messageText);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
@@ -68,7 +89,7 @@ function processPlayerChat(client, messageText) {
|
||||
let clients = getClients();
|
||||
for(let i in clients) {
|
||||
let translatedText;
|
||||
translatedText = await translateMessage(messageText, getPlayerData(client).locale, getPlayerData(clients[i]).locale);
|
||||
translatedText = translateMessage(messageText, getPlayerData(client).locale, getPlayerData(clients[i]).locale);
|
||||
|
||||
let original = (getPlayerData(client).locale == getPlayerData(clients[i]).locale) ? `` : ` {ALTCOLOUR}(${messageText})`;
|
||||
messagePlayerNormal(clients[i], `💬 ${getCharacterFullName(client)}: [#FFFFFF]${translatedText}${original}`, clients[i], getColourByName("mediumGrey"));
|
||||
@@ -80,7 +101,51 @@ function processPlayerChat(client, messageText) {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function globalOOCCommand(command, params, client) {
|
||||
if (isPlayerMuted(client)) {
|
||||
messagePlayerError(client, getLocaleString(client, "MutedCantChat"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (areParamsEmpty(params)) {
|
||||
messagePlayerSyntax(client, getCommandSyntaxText(command));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!getServerConfig().globalChatEnabled) {
|
||||
messagePlayerError(client, getLocaleString(client, "GlobalChatDisabled"));
|
||||
return false;
|
||||
}
|
||||
|
||||
oocToAllPlayers(client, params);
|
||||
return true;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function localOOCCommand(command, params, client) {
|
||||
if (isPlayerMuted(client)) {
|
||||
messagePlayerError(client, getLocaleString(client, "MutedCantChat"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (areParamsEmpty(params)) {
|
||||
messagePlayerSyntax(client, getCommandSyntaxText(command));
|
||||
return false;
|
||||
}
|
||||
|
||||
oocToNearbyPlayers(client, params);
|
||||
return true;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function meActionCommand(command, params, client) {
|
||||
if (isPlayerMuted(client)) {
|
||||
messagePlayerError(client, getLocaleString(client, "MutedCantChat"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (areParamsEmpty(params)) {
|
||||
messagePlayerSyntax(client, getCommandSyntaxText(command));
|
||||
return false;
|
||||
@@ -200,7 +265,7 @@ function adminChatCommand(command, params, client) {
|
||||
}
|
||||
}
|
||||
|
||||
messageDiscordAdminChannel(`${getPlayerData(client).accountData.staffTitle} ${getPlayerData(client).accountData.name}: ${messageText}`);
|
||||
messageDiscordAdminChannel(`${getPlayerData(client).accountData.staffTitle} ${getPlayerData(client).accountData.name}: ${params}`);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -216,6 +281,16 @@ function clanChatCommand(command, params, client) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getPlayerClan(client) == -1) {
|
||||
messagePlayerError(client, getLocaleString(client, "InvalidClan"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getClanData(getPlayerClan) == false) {
|
||||
messagePlayerError(client, getLocaleString(client, "InvalidClan"));
|
||||
return false;
|
||||
}
|
||||
|
||||
clanChat(client, params);
|
||||
}
|
||||
|
||||
@@ -437,9 +512,24 @@ function canPlayerUseMegaphone(client) {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function chatToAllPlayers(client, messageText) {
|
||||
messagePlayerNormal(null, `💬 ${getCharacterFullName(client)}: {MAINCOLOUR}${messageText}`, getPlayerColour(client));
|
||||
messageDiscordChatChannel(`💬 ${getCharacterFullName(client)}: ${messageText}`);
|
||||
function oocToAllPlayers(client, messageText) {
|
||||
messagePlayerNormal(null, `💬 ${getCharacterFullName(client)}: {MAINCOLOUR}(( ${messageText} ))`, getPlayerColour(client));
|
||||
messageDiscordChatChannel(`💬 ${getCharacterFullName(client)}: (( ${messageText} ))`);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function oocToNearbyPlayers(client, messageText) {
|
||||
let clients = getClients();
|
||||
for (let i in clients) {
|
||||
if (isPlayerSpawned(clients[i])) {
|
||||
if (hasBitFlag(getPlayerData(clients[i]).accountData.flags.moderation, getModerationFlagValue("CanHearEverything")) || (getDistance(getPlayerPosition(client), getPlayerPosition(clients[i])) <= getGlobalConfig().doActionDistance && getPlayerDimension(client) == getPlayerDimension(clients[i]))) {
|
||||
messagePlayerNormal(clients[i], `💬 ${getCharacterFullName(client)}: {lightGrey}(( ${messageText} ))`, getPlayerColour(client));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
messageDiscordChatChannel(`💬 ${getCharacterFullName(client)}: (( ${messageText} ))`);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -23,11 +23,15 @@ class ClanData {
|
||||
this.colour = COLOUR_WHITE;
|
||||
this.colours = [];
|
||||
this.initialRank = 0;
|
||||
this.members = [];
|
||||
this.ranks = [];
|
||||
this.needsSaved = false;
|
||||
this.motd = false;
|
||||
|
||||
/** @type {Array.<ClanMemberData>} */
|
||||
this.members = [];
|
||||
|
||||
/** @type {Array.<ClanRankData>} */
|
||||
this.ranks = [];
|
||||
|
||||
if (dbAssoc) {
|
||||
this.databaseId = toInteger(dbAssoc["clan_id"]);
|
||||
this.name = dbAssoc["clan_name"];
|
||||
@@ -311,7 +315,7 @@ function deleteClanCommand(command, params, client) {
|
||||
// ===========================================================================
|
||||
|
||||
function setClanOwnerCommand(command, params, client) {
|
||||
if (!doesPlayerHaveClanPermission(client, getClanFlagValue("owner"))) {
|
||||
if (!doesPlayerHaveClanPermission(client, getClanFlagValue("Owner"))) {
|
||||
messagePlayerError(client, "You must be the clan owner to use this command!");
|
||||
return false;
|
||||
}
|
||||
@@ -334,18 +338,20 @@ function setClanOwnerCommand(command, params, client) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let highestRankIndex = getHighestClanRank(clanIndex);
|
||||
|
||||
getClanData(clanIndex).owner = getPlayerCurrentSubAccount(targetClient).databaseId;
|
||||
getPlayerCurrentSubAccount(targetClient).clan = getClanData(clanIndex).databaseId;
|
||||
getPlayerCurrentSubAccount(targetClient).clanRank = getHighestClanRank(clanIndex);
|
||||
getPlayerCurrentSubAccount(targetClient).clanIndex = getClanIndexFromDatabaseId(clanIndex)
|
||||
getPlayerCurrentSubAccount(targetClient).clanRankIndex = getClanRankIndexFromDatabaseId(clanIndex, getPlayerCurrentSubAccount(targetClient).clanRank);
|
||||
getPlayerCurrentSubAccount(targetClient).clanIndex = getClanIndexFromDatabaseId(clanIndex);
|
||||
getPlayerCurrentSubAccount(targetClient).clanRank = getClanRankData(clanIndex, highestRankIndex).databaseId;
|
||||
getPlayerCurrentSubAccount(targetClient).clanRankIndex = highestRankIndex;
|
||||
getClanData(clanIndex).needsSaved = true;
|
||||
|
||||
getPlayerCurrentSubAccount(targetClient).clan = getClanData(clanIndex).databaseId;
|
||||
getPlayerCurrentSubAccount(targetClient).clanFlags = getClanFlagValue("All");
|
||||
|
||||
//messageAdmins(`{adminOrange}${getPlayerName(client)} {MAINCOLOUR}set clan {clanOrange}${getClanData(clanIndex).name} {MAINCOLOUR}owner to {ALTCOLOUR}${getCharacterFullName(targetClient)}`);
|
||||
messagePlayerSuccess(client, `You changed the clan owner to {ALTCOLOUR}${getCharacterFullName(targetClient)}`);
|
||||
messagePlayerSuccess(client, `You changed clan {clanOrange}${getClanData(clanIndex).name}'s {MAINCOLOUR}owner to {ALTCOLOUR}${getCharacterFullName(targetClient)}`);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -1047,7 +1053,12 @@ function createClan(name) {
|
||||
let tempClan = new ClanData(false);
|
||||
tempClan.databaseId = getDatabaseInsertId(dbConnection);
|
||||
tempClan.name = name;
|
||||
getServerData().clans.push(tempClan);
|
||||
let clanId = getServerData().clans.push(tempClan);
|
||||
|
||||
let tempDefaultRank = new ClanRankData(false);
|
||||
tempDefaultRank.name = "Default Rank";
|
||||
tempDefaultRank.needsSaved = true;
|
||||
getServerData().clans[clanId - 1].ranks.push(tempDefaultRank);
|
||||
|
||||
setAllClanDataIndexes();
|
||||
}
|
||||
@@ -1521,7 +1532,7 @@ function getLowestClanRank(clanIndex) {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function getHighestJobRank(clanIndex) {
|
||||
function getHighestClanRank(clanIndex) {
|
||||
let highestRank = 0;
|
||||
for (let i in getServerData().clans[clanIndex].ranks) {
|
||||
if (getClanRankData(clanIndex, i).level > getClanRankData(clanIndex, highestRank).level) {
|
||||
@@ -1531,4 +1542,4 @@ function getHighestJobRank(clanIndex) {
|
||||
return highestRank;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// ===========================================================================
|
||||
|
||||
@@ -16,12 +16,13 @@ const V_RETURNTO_TYPE_SKINSELECT = 2; // "Return to" data is from skin
|
||||
|
||||
/**
|
||||
* @class Representing extra data for a client
|
||||
* @property {AccountData} accountData
|
||||
* @property {Array.<SubAccountData>} subAccounts
|
||||
*/
|
||||
class ClientData {
|
||||
constructor(client, accountData, subAccounts) {
|
||||
/** @type {AccountData} */
|
||||
this.accountData = accountData;
|
||||
|
||||
/** @type {Array.<SubAccountData>} */
|
||||
this.subAccounts = subAccounts; // Characters
|
||||
|
||||
// General Info
|
||||
@@ -129,6 +130,7 @@ class ClientData {
|
||||
this.alcoholLevel = 0;
|
||||
this.pedState = V_PEDSTATE_NONE;
|
||||
this.promptType = V_PROMPT_NONE;
|
||||
this.promptValue = 0;
|
||||
this.privateMessageReplyTo = null;
|
||||
this.enteringExitingProperty = null;
|
||||
this.inProperty = null;
|
||||
@@ -149,6 +151,12 @@ class ClientData {
|
||||
this.casinoChips = 0; // This might become an item with a useId of a business (for chips belonging to specific casinos)
|
||||
this.casinoCardHand = [];
|
||||
this.casinoPlayingGame = V_CASINO_GAME_NONE;
|
||||
|
||||
// PayPhone
|
||||
this.usingPayPhone = -1;
|
||||
this.payPhoneOtherPlayer = null;
|
||||
this.payPhoneCallStart = 0;
|
||||
this.payPhoneInitiatedCall = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -147,7 +147,8 @@ function loadCommands() {
|
||||
new CommandData("bizdelflooritems", deleteBusinessFloorItemsCommand, "", getStaffFlagValue("ManageItems"), true, true, "Destroys all items on the business floor (for-sale items)"),
|
||||
new CommandData("bizdelstorageitems", deleteBusinessStorageItemsCommand, "", getStaffFlagValue("ManageItems"), true, true, "Destroys all items in the business's storage"),
|
||||
new CommandData("bizdealership", setBusinessDealershipCommand, "", getStaffFlagValue("None"), true, true, "Sets the business's door label to vehicle dealership"),
|
||||
//new CommandData("bizpaintball", setBusinessPaintBallCommand, "", getStaffFlagValue("None"), true, true, "Sets the business to a paintball arena"),
|
||||
new CommandData("bizpaintball", setBusinessPaintBallCommand, "", getStaffFlagValue("None"), true, true, "Sets the business to a paintball arena"),
|
||||
new CommandData("nearbiz", getNearbyBusinessesCommand, "[distance]", getStaffFlagValue("None"), true, true, "Shows all businesses within X meters"),
|
||||
],
|
||||
chat: [
|
||||
new CommandData("me", meActionCommand, "<message>", getStaffFlagValue("None"), true, false, "Shows a custom action message in chat"),
|
||||
@@ -167,6 +168,8 @@ function loadCommands() {
|
||||
new CommandData("dm", privateMessageCommand, "<player name/id> <message>", getStaffFlagValue("None"), true, true, "Sends a private message to a player"),
|
||||
new CommandData("msg", privateMessageCommand, "<player name/id> <message>", getStaffFlagValue("None"), true, true, "Sends a private message to a player"),
|
||||
new CommandData("reply", replyToLastPrivateMessageCommand, "<message>", getStaffFlagValue("None"), true, true, "Replies to the last private message you received"),
|
||||
new CommandData("b", localOOCCommand, "<message>", getStaffFlagValue("None"), true, true, "Local OOC (out of character) chat, shows to players in proximity"),
|
||||
new CommandData("o", globalOOCCommand, "<message>", getStaffFlagValue("None"), true, true, "Global OOC (out of character) chat, shows to all players"),
|
||||
],
|
||||
clan: [
|
||||
new CommandData("clans", listClansCommand, "[search text]", getStaffFlagValue("None"), true, true, "List clans (search by partial name, if provided)"),
|
||||
@@ -195,10 +198,10 @@ function loadCommands() {
|
||||
client: [],
|
||||
colour: [],
|
||||
command: [
|
||||
new CommandData("cmdenabletype", enableAllCommandsByType, "<type>", getStaffFlagValue("Developer"), true, true, "Enables all commands by type."),
|
||||
new CommandData("cmddisabletype", disableAllCommandsByType, "<type>", getStaffFlagValue("Developer"), true, true, "Disables all commands by type."),
|
||||
new CommandData("cmdenable", enableCommand, "<command>", getStaffFlagValue("Developer"), true, true, "Enable a specific command"),
|
||||
new CommandData("cmddisable", disableCommand, "<command>", getStaffFlagValue("Developer"), true, true, "Disables a specific command"),
|
||||
new CommandData("cmdenabletype", enableAllCommandsByType, "<type>", getStaffFlagValue("ManageServer"), true, true, "Enables all commands by type."),
|
||||
new CommandData("cmddisabletype", disableAllCommandsByType, "<type>", getStaffFlagValue("ManageServer"), true, true, "Disables all commands by type."),
|
||||
new CommandData("cmdenable", enableCommand, "<command>", getStaffFlagValue("ManageServer"), true, true, "Enable a specific command"),
|
||||
new CommandData("cmddisable", disableCommand, "<command>", getStaffFlagValue("ManageServer"), true, true, "Disables a specific command"),
|
||||
],
|
||||
config: [
|
||||
new CommandData("settime", setTimeCommand, "<hour> [minute]", getStaffFlagValue("ManageWorld"), true, true, "Sets the time. Hours are required, minute is optional and will default to 0"),
|
||||
@@ -236,7 +239,7 @@ function loadCommands() {
|
||||
new CommandData("scode", executeServerCodeCommand, "<code>", getStaffFlagValue("Developer"), true, true, "Execute serverside code"),
|
||||
new CommandData("ccode", executeClientCodeCommand, "<code>", getStaffFlagValue("Developer"), true, true, "Execute clientside code for a player"),
|
||||
new CommandData("gmx", restartGameModeCommand, "", getStaffFlagValue("Developer"), true, true, "Restart this gamemode"),
|
||||
new CommandData("saveall", saveServerDataCommand, "", getStaffFlagValue("Developer"), true, true, "Immediately save all data to database"),
|
||||
new CommandData("saveall", saveServerDataCommand, "", getStaffFlagValue("ManageHouses") | getStaffFlagValue("ManageBusinesses") | getStaffFlagValue("ManageJobs") | getStaffFlagValue("ManagePayPhones"), true, true, "Immediately save all data to database"),
|
||||
new CommandData("docmd", simulateCommandForPlayerCommand, "<player name/id> <command> [params]", getStaffFlagValue("Developer"), true, true, "Force a player to use a command"),
|
||||
new CommandData("docmdall", simulateCommandForAllPlayersCommand, "<command> [params]", getStaffFlagValue("Developer"), true, true, "Force all players to use a command"),
|
||||
new CommandData("addloglevel", addLogLevelCommand, "<log level name>", getStaffFlagValue("Developer"), true, true, "Adds a log level"),
|
||||
@@ -247,7 +250,6 @@ function loadCommands() {
|
||||
new CommandData("streamurlall", streamAudioURLToAllPlayersCommand, "<url> <volume>", getStaffFlagValue("Developer"), true, true, "Plays a URL radio stream for all players"),
|
||||
new CommandData("streamnameall", streamAudioNameToAllPlayersCommand, "<name> <volume>", getStaffFlagValue("Developer"), true, true, "Plays an audio file stream for all players"),
|
||||
|
||||
new CommandData("forceresetpass", forceAccountPasswordResetCommand, "<account name>", getStaffFlagValue("Developer"), true, true),
|
||||
new CommandData("fixblips", fixAllServerBlipsCommand, "", getStaffFlagValue("Developer"), true, true, "Clears and recreates all map blips"),
|
||||
new CommandData("fixpickups", fixAllServerPickupsCommand, "", getStaffFlagValue("Developer"), true, true, "Clears and recreates all pickups"),
|
||||
new CommandData("resetambience", resetAllServerAmbienceElementsCommand, "", getStaffFlagValue("ManageWorld"), true, true, "Clears all current server ambience elements (traffic, peds, etc)"),
|
||||
@@ -260,11 +262,24 @@ function loadCommands() {
|
||||
new CommandData("tax", taxInfoCommand, "", getStaffFlagValue("None"), true, true),
|
||||
new CommandData("wealth", wealthInfoCommand, "", getStaffFlagValue("None"), true, true),
|
||||
new CommandData("forcepayday", forcePlayerPayDayCommand, "<player name/id>", getStaffFlagValue("ManageServer"), true, true, "Gives a player an instant payday."),
|
||||
|
||||
new CommandData("setincomemultiplier", setGrossIncomeMultiplierCommand, "<amount>", getStaffFlagValue("ManageServer"), true, true, "Multiplies pay by this amount. 100% adds nothing extra"),
|
||||
new CommandData("setinflation", setInflationMultiplierCommand, "<amount>", getStaffFlagValue("ManageServer"), true, true, "Sets the server inflation (in percent). 100% is no inflation"),
|
||||
new CommandData("setincometax", setIncomeTaxCommand, "<amount>", getStaffFlagValue("ManageServer"), true, true, "Sets the server income tax (in percent). Players will be taxed this much when getting pay"),
|
||||
new CommandData("sethouseupkeep", setHouseUpkeepCommand, "<amount>", getStaffFlagValue("ManageServer"), true, true, "Sets the base upkeep cost of a house"),
|
||||
new CommandData("setbizupkeep", setBusinessUpkeepCommand, "<amount>", getStaffFlagValue("ManageServer"), true, true, "Sets the base upkeep cost of a business"),
|
||||
new CommandData("setvehupkeep", setVehicleUpkeepCommand, "<amount>", getStaffFlagValue("ManageServer"), true, true, "Sets the base upkeep cost of a vehicle"),
|
||||
new CommandData("setcurrencystring", setCurrencyStringCommand, "<string> MUST INCLUDE {AMOUNT}", getStaffFlagValue("ManageServer"), true, true, "Sets the currency string"),
|
||||
new CommandData("setpassiveincome", setPassiveIncomeCommand, "<amount>", getStaffFlagValue("ManageServer"), true, true, "Sets the base upkeep cost of a vehicle"),
|
||||
],
|
||||
email: [
|
||||
new CommandData("testemail", testEmailCommand, "<email address>", getStaffFlagValue("Developer"), true, true),
|
||||
],
|
||||
fishing: [],
|
||||
fishing: [
|
||||
//new CommandData("fish", castFishingLineCommand, "", getStaffFlagValue("None"), true, true, "Casts your fishing line into the water"),
|
||||
//new CommandData("castline", castFishingLineCommand, "", getStaffFlagValue("None"), true, true, "Casts your fishing line into the water"),
|
||||
//new CommandData("resetline", resetFishingLineCommand, "", getStaffFlagValue("None"), true, true, "Casts your fishing line into the water"),
|
||||
],
|
||||
forensics: [],
|
||||
gate: [
|
||||
new CommandData("gate", triggerGateCommand, "", getStaffFlagValue("None"), true, true, "Opens/closes the nearest gate"),
|
||||
@@ -317,6 +332,7 @@ function loadCommands() {
|
||||
new CommandData("houseentrance", moveHouseEntranceCommand, "", getStaffFlagValue("ManageHouses"), true, true, "Moves a house's entrance (outside/exterior location to enter the house)"),
|
||||
new CommandData("houseexit", moveHouseExitCommand, "", getStaffFlagValue("ManageHouses"), true, true, "Moves a house's exit (inside/interior location to exit the house)"),
|
||||
new CommandData("houseinttype", setHouseInteriorTypeCommand, "<interior template name/business id>", getStaffFlagValue("ManageHouses"), true, true, "Sets a house's interior to a pre-defined type"),
|
||||
//new CommandData("nearhouse", getNearbyHousesCommand, "[distance]", getStaffFlagValue("None"), true, true, "Shows all houses within X meters"),
|
||||
],
|
||||
insurance: [],
|
||||
item: [
|
||||
@@ -333,7 +349,8 @@ function loadCommands() {
|
||||
new CommandData("inv", listPlayerInventoryCommand, "", getStaffFlagValue("None"), true, false, "Shows the items in your inventory"),
|
||||
new CommandData("inventory", listPlayerInventoryCommand, "", getStaffFlagValue("None"), true, false, "Shows the items in your inventory"),
|
||||
|
||||
new CommandData("items", listItemInventoryCommand, "", getStaffFlagValue("None"), true, false, "Shows the items in your inventory"),
|
||||
new CommandData("items", listItemInventoryCommand, "", getStaffFlagValue("None"), true, false, "Shows the items stored in a container item"),
|
||||
new CommandData("vehtrunk", listVehicleTrunkInventoryCommand, "", getStaffFlagValue("None"), true, false, "Shows the items in a vehicle's trunk"),
|
||||
new CommandData("houseitems", listHouseInventoryCommand, "", getStaffFlagValue("None"), true, false, "Shows the items in the house's storage"),
|
||||
new CommandData("bizstorage", listBusinessStorageInventoryCommand, "", getStaffFlagValue("None"), true, false, "Shows the items in the business's extra storage (not buyable)"),
|
||||
new CommandData("bizfloor", listBusinessFloorInventoryCommand, "", getStaffFlagValue("None"), true, false, "Shows the items that can be bought from the business"),
|
||||
@@ -376,7 +393,7 @@ function loadCommands() {
|
||||
new CommandData("quitjob", quitJobCommand, "", getStaffFlagValue("None"), true, false, "Leave your job and be unemployed"),
|
||||
new CommandData("uniform", jobUniformCommand, "[uniform]", getStaffFlagValue("None"), true, false, "Use a job uniform"),
|
||||
new CommandData("equip", jobEquipmentCommand, "[equipment]", getStaffFlagValue("None"), true, false, "Get equipment for your job"),
|
||||
|
||||
new CommandData("jobrank", setPlayerJobRankCommand, "<player name/id> <rank name/id>", getStaffFlagValue("None"), true, true, "Sets a player's job rank"),
|
||||
new CommandData("jobs", jobListCommand, "", getStaffFlagValue("None"), true, false, "Shows a list of all jobs"),
|
||||
new CommandData("joblist", jobListCommand, "", getStaffFlagValue("None"), true, false, "Shows a list of all jobs"),
|
||||
new CommandData("alljobs", jobListCommand, "", getStaffFlagValue("None"), true, false, "Shows a list of all jobs"),
|
||||
@@ -443,6 +460,13 @@ function loadCommands() {
|
||||
new CommandData("jobreloadall", reloadAllJobsCommand, "", getStaffFlagValue("ManageJobs"), true, false),
|
||||
new CommandData("jobinfo", getJobInfoCommand, "", getStaffFlagValue("None"), true, true, "Get info for nearest or specified job"),
|
||||
new CommandData("joblocinfo", getJobLocationInfoCommand, "", getStaffFlagValue("None"), true, true, "Get info for nearest or specified job location"),
|
||||
new CommandData("jobroutes", getJobRoutesCommand, "", getStaffFlagValue("None"), true, false, "Shows a list of job routes for the nearest job location"),
|
||||
new CommandData("jobrouteinfo", getJobRouteInfoCommand, "", getStaffFlagValue("None"), true, false, "Shows info about a job route"),
|
||||
|
||||
new CommandData("jobinvite", jobInviteCommand, "<player name/id>", getStaffFlagValue("None"), true, false, "Invites a player to a job"),
|
||||
new CommandData("jobhire", jobInviteCommand, "<player name/id>", getStaffFlagValue("None"), true, false, "Invites a player to a job"),
|
||||
new CommandData("jobuninvite", jobUninviteCommand, "<player name/id>", getStaffFlagValue("None"), true, false, "Removes a player from their job"),
|
||||
new CommandData("jobfire", jobUninviteCommand, "<player name/id>", getStaffFlagValue("None"), true, false, "Removes a player from their job"),
|
||||
],
|
||||
keybind: [
|
||||
new CommandData("bindkey", addKeyBindCommand, "<key id/name> <command> [params]", getStaffFlagValue("None"), true, false, "Binds a key to a command and optional parameters"),
|
||||
@@ -480,6 +504,8 @@ function loadCommands() {
|
||||
new CommandData("light", lightsCommand, "", getStaffFlagValue("None"), true, false, "Turns on and off the lights for your vehicle, house, or business"),
|
||||
new CommandData("kill", suicideCommand, "", getStaffFlagValue("None"), true, false, "Kills yourself"),
|
||||
new CommandData("suicide", suicideCommand, "", getStaffFlagValue("None"), true, false, "Kills yourself"),
|
||||
new CommandData("scoreboard", scoreBoardCommand, "", getStaffFlagValue("None"), true, false, "Shows the scoreboard (key press only)"),
|
||||
new CommandData("locate", locatePlayerCommand, "<player name/id>", getStaffFlagValue("None"), true, true, "Shows the distance and direction of another player"),
|
||||
],
|
||||
npc: [
|
||||
new CommandData("addnpc", createNPCCommand, "<skin id/name>", getStaffFlagValue("ManageNPCs"), true, false, "Creates an NPC with the specified skin"),
|
||||
@@ -492,6 +518,23 @@ function loadCommands() {
|
||||
//new CommandData("npcrespawn", respawnNPCCommand, "", getStaffFlagValue("ManageNPCs"), true, false, "Respawns the nearest NPC"),
|
||||
],
|
||||
paintball: [],
|
||||
payPhone: [
|
||||
new CommandData("addpayphone", createPayPhoneCommand, "[number]", getStaffFlagValue("ManagePayPhones"), true, false, "Creates an payphone with optional number (random number if not added)"),
|
||||
new CommandData("delpayphone", deletePayPhoneCommand, "[number]", getStaffFlagValue("ManagePayPhones"), true, false, "Deleted a payphone with number (optional, will use closest payphone if no number)"),
|
||||
new CommandData("call", callPayPhoneCommand, "<player name/id>", getStaffFlagValue("None"), true, false, "Calls the player (nearest payphone or their cellphone if applicable"),
|
||||
new CommandData("hangup", hangupPayPhoneCommand, "", getStaffFlagValue("None"), true, false, "Ends a payphone call"),
|
||||
new CommandData("answer", answerPayPhoneCommand, "", getStaffFlagValue("None"), true, false, "Answer's a ringing phone"),
|
||||
new CommandData("givephone", givePayPhoneToPlayerCommand, "<player name/id>", getStaffFlagValue("None"), true, false, "Gives a phone to another player to talk on the call"),
|
||||
new CommandData("payphone", getPayPhoneNumberCommand, "", getStaffFlagValue("None"), true, false, "Shows a phone's number"),
|
||||
new CommandData("number", getPayPhoneNumberCommand, "", getStaffFlagValue("None"), true, false, "Shows a phone's number"),
|
||||
new CommandData("nearpayphone", getNearbyPayPhonesCommand, "[range]", getStaffFlagValue("None"), true, false, "Shows a list of all nearby phones within certain range"),
|
||||
new CommandData("nearpayphones", getNearbyPayPhonesCommand, "[range]", getStaffFlagValue("None"), true, false, "Shows a list of all nearby phones within certain range"),
|
||||
new CommandData("payphoneinfo", getPayPhoneInfoCommand, "[number]", getStaffFlagValue("None"), true, false, "Shows info of nearest payphone (or of payphone with number)"),
|
||||
new CommandData("phoneinfo", getPayPhoneInfoCommand, "[number]", getStaffFlagValue("None"), true, false, "Shows info of nearest payphone (or of payphone with number)"),
|
||||
new CommandData("resetpayphones", resetAllPayPhonesCommand, "", getStaffFlagValue("ManagePayPhones"), true, false, "Resets all payphone states"),
|
||||
new CommandData("fixpayphones", resetAllPayPhonesCommand, "", getStaffFlagValue("ManagePayPhones"), true, false, "Resets all payphone states"),
|
||||
//new CommandData("callphone", callPhoneNumberCommand, "<number>", getStaffFlagValue("None"), true, false, "Rings the payphone with number"),
|
||||
],
|
||||
race: [
|
||||
// Unfinished!
|
||||
//new CommandData("addrace", createRaceCommand, "<name>", getStaffFlagValue("ManageRaces"), true, false, "Creates a race"),
|
||||
@@ -561,7 +604,7 @@ function loadCommands() {
|
||||
new CommandData("plrstafftitle", setPlayerStaffTitleCommand, "", getStaffFlagValue("ManageAdmins"), true, true, "Sets a player's staff title."),
|
||||
new CommandData("playerstafftitle", setPlayerStaffTitleCommand, "", getStaffFlagValue("ManageAdmins"), true, true, "Sets a player's staff title."),
|
||||
new CommandData("stafftitle", setPlayerStaffTitleCommand, "", getStaffFlagValue("ManageAdmins"), true, true, "Sets a player's staff title."),
|
||||
new CommandData("givemoney", givePlayerMoneyCommand, "<player name/id> <amount>", getStaffFlagValue("serverManager"), true, true),
|
||||
new CommandData("givemoney", givePlayerMoneyCommand, "<player name/id> <amount>", getStaffFlagValue("ServerManager"), true, true),
|
||||
new CommandData("nonrpname", forceCharacterNameChangeCommand, "<player name/id>", getStaffFlagValue("BasicModeration"), true, true, "Forces a player to change their current character's name."),
|
||||
new CommandData("setname", forceCharacterNameCommand, "<player name/id> <first name> <last name>", getStaffFlagValue("BasicModeration"), true, true, "Changes a character's name directly."),
|
||||
new CommandData("setskin", forcePlayerSkinCommand, "<player name/id> <skin id/name>", getStaffFlagValue("BasicModeration"), true, true, "Changes a character's skin."),
|
||||
@@ -596,7 +639,9 @@ function loadCommands() {
|
||||
new CommandData("biz", getPlayerCurrentBusinessCommand, "<player name/id>", getStaffFlagValue("BasicModeration"), true, true, "Gets which business a player is at/in"),
|
||||
new CommandData("business", getPlayerCurrentBusinessCommand, "<player name/id>", getStaffFlagValue("BasicModeration"), true, true, "Gets which business a player is at/in"),
|
||||
new CommandData("house", getPlayerCurrentHouseCommand, "<player name/id>", getStaffFlagValue("BasicModeration"), true, true, "Gets which house a player is at/in"),
|
||||
//new CommandData("clearchat", clearChatCommand, "", getStaffFlagValue("None"), true, true, "Clears the chat"),
|
||||
new CommandData("clearchat", clearChatCommand, "", getStaffFlagValue("BasicModeration"), true, true, "Clears the chat"),
|
||||
new CommandData("forceresetpass", forceAccountPasswordResetCommand, "<player name/id>", getStaffFlagValue("ManageServer"), true, true),
|
||||
new CommandData("chattype", setServerDefaultChatTypeCommand, "<chat type name>", getStaffFlagValue("ManageServer"), true, true, "Sets the normal chat type for the server"),
|
||||
],
|
||||
startup: [],
|
||||
subAccount: [
|
||||
@@ -884,11 +929,11 @@ function processPlayerCommand(command, params, client) {
|
||||
return true;
|
||||
}
|
||||
|
||||
let possibleAlias = getPlayerAliasForCommand(command);
|
||||
if (possibleAlias) {
|
||||
// Just change to the command the alias is for, then continue as normal
|
||||
command = possibleAlias.forCommand;
|
||||
}
|
||||
//let possibleAlias = getPlayerAliasForCommand(client, command);
|
||||
//if (possibleAlias) {
|
||||
// // Just change to the command the alias is for, then continue as normal
|
||||
// command = possibleAlias.forCommand;
|
||||
//}
|
||||
|
||||
let commandData = getCommand(toLowerCase(command));
|
||||
|
||||
@@ -902,9 +947,9 @@ function processPlayerCommand(command, params, client) {
|
||||
|
||||
let possibleCommand = getCommandFromParams(command);
|
||||
if (possibleCommand != false && doesPlayerHaveStaffPermission(client, getCommandRequiredPermissions(toLowerCase(possibleCommand.command)))) {
|
||||
messagePlayerError(client, getLocaleString(client, "InvalidCommandPossibleMatchTip", `{ALTCOLOUR}/${command}{MAINCOLOUR}`, `{ALTCOLOUR}${toLowerCase(possibleCommand.command)}{MAINCOLOUR}`));
|
||||
messagePlayerError(client, getLocaleString(client, "CommandNotFoundPossibleMatchTip", `{ALTCOLOUR}/${command}{MAINCOLOUR}`, `{ALTCOLOUR}${toLowerCase(possibleCommand.command)}{MAINCOLOUR}`));
|
||||
} else {
|
||||
messagePlayerError(client, getLocaleString(client, "InvalidCommandHelpTip", `{ALTCOLOUR}/${command}{MAINCOLOUR}`, `{ALTCOLOUR}/help{MAINCOLOUR}`));
|
||||
messagePlayerError(client, getLocaleString(client, "CommandNotFoundHelpTip", `{ALTCOLOUR}/${command}{MAINCOLOUR}`, `{ALTCOLOUR}/help{MAINCOLOUR}`));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -1097,4 +1142,30 @@ function getCommandFromParams(params) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function getPlayerAliasForCommand(client, command) {
|
||||
return command;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
/**
|
||||
* @return {Array.<CommandData>} Array of commands usable by staff flag
|
||||
*/
|
||||
function getCommandsUsableByStaffFlag(flagName) {
|
||||
let usableCommands = [];
|
||||
|
||||
let commands = getCommands();
|
||||
for (let i in commands) {
|
||||
for (let j in commands[i]) {
|
||||
if (hasBitFlag(commands[i][j].requiredStaffFlags, getStaffFlagValue(flagName))) {
|
||||
usableCommands.push(commands[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return usableCommands;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -49,7 +49,6 @@ class ServerConfigData {
|
||||
this.guiTextColourPrimary = [0, 0, 0];
|
||||
this.guiTextColourSecondary = [0, 0, 0];
|
||||
this.showLogo = true;
|
||||
this.inflationMultiplier = 1;
|
||||
this.testerOnly = false;
|
||||
this.devServer = false;
|
||||
this.nameTagDistance = 50.0;
|
||||
@@ -80,12 +79,29 @@ class ServerConfigData {
|
||||
this.useRealTime = false;
|
||||
this.realTimeZone = 0;
|
||||
|
||||
this.normalChatType = V_CHAT_TYPE_GLOBAL;
|
||||
|
||||
this.discordConfig = {
|
||||
sendEvents: true,
|
||||
sendChat: true,
|
||||
sendAdmin: true,
|
||||
};
|
||||
|
||||
this.economy = {
|
||||
inflationMultiplier: 1.0,
|
||||
passiveIncomePerPayDay: 2000,
|
||||
applyTax: true,
|
||||
applyUpkeep: true,
|
||||
grossIncomeMultiplier: 1.0,
|
||||
incomeTaxRate: 0.7,
|
||||
currencyString: "${AMOUNT}",
|
||||
upKeepCosts: {
|
||||
upKeepPerVehicle: 250,
|
||||
upKeepPerHouse: 350,
|
||||
upKeepPerBusiness: 600
|
||||
}
|
||||
};
|
||||
|
||||
if (dbAssoc) {
|
||||
this.databaseId = dbAssoc["svr_id"];
|
||||
this.newCharacter = {
|
||||
@@ -136,12 +152,24 @@ class ServerConfigData {
|
||||
|
||||
this.economy = {
|
||||
inflationMultiplier: toFloat(dbAssoc["svr_inflation_multiplier"]),
|
||||
incomeTaxRate: toFloat(dbAssoc["svr_income_tax_rate"]),
|
||||
passiveIncome: toFloat(dbAssoc["svr_passive_income"]),
|
||||
}
|
||||
incomeTaxRate: toFloat(dbAssoc["svr_tax_income"]),
|
||||
passiveIncomePerPayDay: toFloat(dbAssoc["svr_passive_income"]),
|
||||
applyTax: intToBool(dbAssoc["svr_tax_enabled"]),
|
||||
applyUpkeep: intToBool(dbAssoc["svr_upkeep_enabled"]),
|
||||
grossIncomeMultiplier: toFloat(dbAssoc["svr_gross_income_multiplier"]),
|
||||
currencyString: toString(dbAssoc["svr_currency_string"]),
|
||||
upKeepCosts: {
|
||||
upKeepPerVehicle: toInteger(dbAssoc["svr_upkeep_veh"]),
|
||||
upKeepPerHouse: toInteger(dbAssoc["svr_upkeep_house"]),
|
||||
upKeepPerBusiness: toInteger(dbAssoc["svr_upkeep_biz"]),
|
||||
}
|
||||
};
|
||||
|
||||
this.devServer = intToBool(toInteger(server.getCVar("v_devserver")));
|
||||
this.testerOnly = intToBool(toInteger(server.getCVar("v_testeronly")));
|
||||
|
||||
this.normalChatType = toInteger(dbAssoc["svr_chat_type"]);
|
||||
this.globalChatEnabled = intToBool(dbAssoc["svr_chat_global_enabled"]);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -155,12 +183,12 @@ let gameConfig = false;
|
||||
|
||||
let globalConfig = {
|
||||
keyBind: [],
|
||||
economy: {},
|
||||
database: {},
|
||||
locale: {},
|
||||
accents: {},
|
||||
discord: {},
|
||||
email: {},
|
||||
security: {},
|
||||
accountPasswordHash: "SHA512",
|
||||
npcFarProximity: 100,
|
||||
npcMediumProximity: 40,
|
||||
@@ -191,6 +219,7 @@ let globalConfig = {
|
||||
vehicleRepairDistance: 5,
|
||||
itemActionStateReset: 5000,
|
||||
subAccountNameAllowedCharacters: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
|
||||
alphaNumericCharacters: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
|
||||
emailValidationRegex: /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/,
|
||||
itemActionDelayExtraTimeout: 1000,
|
||||
geoIPCountryDatabaseFilePath: "modules/geoip/geoip-country.mmdb",
|
||||
@@ -210,7 +239,7 @@ let globalConfig = {
|
||||
V_ITEM_USE_TYPE_VEHLIVERY,
|
||||
V_ITEM_USE_TYPE_VEHTIRE,
|
||||
],
|
||||
vehicleInactiveRespawnDelay: 1800000, // 20 minutes
|
||||
vehicleInactiveRespawnDelay: 1000 * 60 * 60, // 60 minutes
|
||||
chatSectionHeaderLength: 96,
|
||||
useServerSideVehiclePurchaseCheck: true,
|
||||
useServerSideVehicleBurnCheck: false,
|
||||
@@ -250,9 +279,10 @@ let globalConfig = {
|
||||
"ChatBoxTimestamps",
|
||||
"ChatEmoji",
|
||||
],
|
||||
mainChatType: V_CHAT_TYPE_TALK,
|
||||
nightMapStartHour: 19,
|
||||
nightMapEndHour: 7,
|
||||
payPhoneGiveDistance: 2.5,
|
||||
payPhoneAnswerDistance: 2.5,
|
||||
};
|
||||
|
||||
// ===========================================================================
|
||||
@@ -273,13 +303,6 @@ function loadGlobalConfig() {
|
||||
thisResource.stop();
|
||||
}
|
||||
|
||||
try {
|
||||
getGlobalConfig().economy = loadEconomyConfig();
|
||||
} catch (error) {
|
||||
logToConsole(LOG_ERROR, `[V.RP.Config] Failed to load economy configuration. Error: ${error}`);
|
||||
thisResource.stop();
|
||||
}
|
||||
|
||||
try {
|
||||
getGlobalConfig().locale = loadLocaleConfig();
|
||||
} catch (error) {
|
||||
@@ -315,6 +338,13 @@ function loadGlobalConfig() {
|
||||
thisResource.stop();
|
||||
}
|
||||
|
||||
try {
|
||||
getGlobalConfig().security = loadSecurityConfig();
|
||||
} catch (error) {
|
||||
logToConsole(LOG_ERROR, `[V.RP.Config] Failed to load security configuration. Error: ${error}`);
|
||||
thisResource.stop();
|
||||
}
|
||||
|
||||
logToConsole(LOG_DEBUG, "[V.RP.Config] Loaded global configuration successfully!");
|
||||
}
|
||||
|
||||
@@ -436,7 +466,6 @@ function saveServerConfigToDatabase() {
|
||||
["svr_charselect_ped_rot_z", getServerConfig().characterSelectPedHeading],
|
||||
["svr_charselect_int", getServerConfig().characterSelectInterior],
|
||||
["svr_charselect_vw", getServerConfig().characterSelectDimension],
|
||||
["svr_inflation_multiplier", getServerConfig().inflationMultiplier],
|
||||
["svr_intro_music", getServerConfig().introMusicURL],
|
||||
["svr_gui", getServerConfig().useGUI],
|
||||
["svr_logo", getServerConfig().showLogo],
|
||||
@@ -451,6 +480,17 @@ function saveServerConfigToDatabase() {
|
||||
["svr_nametag_distance", getServerConfig().nameTagDistance],
|
||||
["svr_real_time", boolToInt(getServerConfig().useRealTime)],
|
||||
["svr_real_time_timezone", getServerConfig().realTimeZone],
|
||||
["svr_inflation_multiplier", getServerConfig().economy.inflationMultiplier],
|
||||
["svr_tax_income", getServerConfig().economy.incomeTaxRate],
|
||||
["svr_passive_income", getServerConfig().economy.passiveIncomePerPayDay],
|
||||
["svr_tax_enabled", boolToInt(getServerConfig().economy.applyTax)],
|
||||
["svr_upkeep_enabled", boolToInt(getServerConfig().economy.applyUpkeep)],
|
||||
["svr_gross_income_multiplier", getServerConfig().economy.grossIncomeMultiplier],
|
||||
["svr_currency_string", getServerConfig().economy.currencyString],
|
||||
["svr_upkeep_veh", getServerConfig().economy.upKeepCosts.upKeepPerVehicle],
|
||||
["svr_upkeep_house", getServerConfig().economy.upKeepCosts.upKeepPerHouse],
|
||||
["svr_upkeep_biz", getServerConfig().economy.upKeepCosts.upKeepPerBusiness],
|
||||
["svr_chat_type", getServerConfig().normalChatType],
|
||||
];
|
||||
|
||||
let dbQuery = null;
|
||||
@@ -897,7 +937,7 @@ function setServerRealWorldTimeZoneCommand(command, params, client) {
|
||||
* @return {bool} Whether or not the command was successful
|
||||
*
|
||||
*/
|
||||
async function reloadServerConfigurationCommand(command, params, client) {
|
||||
function reloadServerConfigurationCommand(command, params, client) {
|
||||
serverConfig = loadServerConfigFromGameAndPort(server.game, server.port);
|
||||
applyConfigToServer(serverConfig);
|
||||
updateServerRules();
|
||||
@@ -994,16 +1034,6 @@ function loadLocaleConfig() {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function loadEconomyConfig() {
|
||||
logToConsole(LOG_DEBUG, "[V.RP.Config] Loading economy configuration ...");
|
||||
let economyConfig = JSON.parse(loadTextFile(`config/economy.json`));
|
||||
if (economyConfig != null) {
|
||||
return economyConfig;
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function loadAccentConfig() {
|
||||
logToConsole(LOG_DEBUG, "[V.RP.Config] Loading accents configuration ...");
|
||||
let accentConfig = JSON.parse(loadTextFile(`config/accents.json`));
|
||||
@@ -1058,6 +1088,17 @@ function loadEmailConfig() {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function loadSecurityConfig() {
|
||||
logToConsole(LOG_DEBUG, "[V.RP.Config] Loading security configuration ...");
|
||||
let securityConfig = JSON.parse(loadTextFile("config/security.json"));
|
||||
if (securityConfig != null) {
|
||||
return securityConfig;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function doesServerHaveGUIEnabled() {
|
||||
return getServerConfig().useGUI;
|
||||
}
|
||||
@@ -1130,6 +1171,12 @@ function getDatabaseConfig() {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function getSecurityConfig() {
|
||||
return getGlobalConfig().security;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function loadServerConfig() {
|
||||
logToConsole(LOG_DEBUG, "[V.RP.Config] Loading server configuration ...");
|
||||
|
||||
|
||||
@@ -9,13 +9,14 @@
|
||||
|
||||
let scriptVersion = "1.3";
|
||||
let serverStartTime = 0;
|
||||
let logLevel = LOG_INFO | LOG_DEBUG | LOG_VERBOSE;
|
||||
let logLevel = LOG_INFO | LOG_DEBUG;
|
||||
|
||||
let playerResourceReady = new Array(server.maxClients).fill(false);
|
||||
let playerResourceStarted = new Array(server.maxClients).fill(false);
|
||||
let playerInitialized = new Array(server.maxClients).fill(false);
|
||||
let playerGUI = new Array(server.maxClients).fill(false);
|
||||
let defaultNoAccountId = 1;
|
||||
let serverStarting = false;
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
@@ -25,7 +26,7 @@ let defaultNoAccountId = 1;
|
||||
* @property {Array.<ClientData>} clients
|
||||
* @property {Array.<BusinessData>} businesses
|
||||
* @property {Array.<HouseData>} houses
|
||||
* @property {Array.<HouseData>} commands
|
||||
* @property {Array} commands
|
||||
* @property {Array.<ItemData>} items
|
||||
* @property {Array.<ItemTypeData>} itemTypes
|
||||
* @property {Array.<ClanData>} clans
|
||||
@@ -35,6 +36,7 @@ let defaultNoAccountId = 1;
|
||||
* @property {Array.<JobData>} jobs
|
||||
* @property {Array.<GateData>} gates
|
||||
* @property {Array.<RadioStationData>} radioStations
|
||||
* @property {Array.<PayPhoneData>} payPhones
|
||||
* @property {Array} locales
|
||||
* @property {Array} localeStrings
|
||||
* @property {Array} groundItemCache
|
||||
@@ -60,6 +62,7 @@ let serverData = {
|
||||
jobs: [],
|
||||
gates: [],
|
||||
radioStations: [],
|
||||
payPhones: [],
|
||||
localeStrings: {},
|
||||
groundItemCache: [],
|
||||
groundPlantCache: [],
|
||||
|
||||
@@ -318,8 +318,8 @@ function executeServerCodeCommand(command, params, client) {
|
||||
}
|
||||
|
||||
messagePlayerSuccess(client, "Server code executed!");
|
||||
messagePlayerNormal(client, `Code: ${params}`, COLOUR_YELLOW);
|
||||
messagePlayerNormal(client, `Returns: ${returnValue} (${typeof returnValue})`, COLOUR_YELLOW);
|
||||
messagePlayerNormal(client, `Code: ${params}`, getColourByName("yellow"));
|
||||
messagePlayerNormal(client, `Returns: ${returnValue} (${typeof returnValue})`, getColourByName("yellow"));
|
||||
logToConsole(LOG_INFO, `Server code executed by ${getPlayerDisplayForConsole(client)}: ${params}`);
|
||||
return true;
|
||||
}
|
||||
@@ -349,7 +349,7 @@ function executeClientCodeCommand(command, params, client) {
|
||||
sendRunCodeToClient(targetClient, targetCode, client);
|
||||
|
||||
messagePlayerSuccess(client, `Executing client code for ${getPlayerName(targetClient)}`);
|
||||
messagePlayerNormal(client, `Code: ${targetCode}`);
|
||||
messagePlayerNormal(client, `Code: ${targetCode}`, getColourByName("yellow"));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -448,7 +448,7 @@ function saveServerDataCommand(command, params, client) {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
async function testEmailCommand(command, params, client) {
|
||||
function testEmailCommand(command, params, client) {
|
||||
sendEmail(params, "Player", "Test email", "Just testing the email system for the server!");
|
||||
|
||||
return true;
|
||||
@@ -483,7 +483,7 @@ function clientRunCodeSuccess(client, returnTo, returnVal) {
|
||||
|
||||
//messagePlayerSuccess(returnClient, `Client code executed for ${getPlayerName(client)}!`);
|
||||
//messagePlayerNormal(returnClient, `Code: ${code}`, getColourByName("yellow"));
|
||||
messagePlayerNormal(returnClient, `(${getPlayerName(client)}) Code returns: ${returnVal}`, getColourByName("white"));
|
||||
messagePlayerNormal(returnClient, `(${getPlayerName(client)}) Code returns: ${returnVal}`, getColourByName("yellow"));
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -548,7 +548,7 @@ function isDevelopmentServer() {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
async function migrateSubAccountsToPerServerData() {
|
||||
function migrateSubAccountsToPerServerData() {
|
||||
let dbConnection = connectToDatabase();
|
||||
let dbAssoc = [];
|
||||
|
||||
@@ -569,7 +569,7 @@ async function migrateSubAccountsToPerServerData() {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
async function resetAllAccountsHotkeysToDefault() {
|
||||
function resetAllAccountsHotkeysToDefault() {
|
||||
let dbConnection = connectToDatabase();
|
||||
let dbAssoc = [];
|
||||
|
||||
@@ -674,13 +674,6 @@ function resetAllServerAmbienceElementsCommand(command, params, client) {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function reloadEconomyConfigurationCommand(command, params, client) {
|
||||
getGlobalConfig().economy = loadEconomyConfig();
|
||||
messageAdmins(`{adminOrange}${getPlayerName(client)} {MAINCOLOUR}has reloaded the economy settings`);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function showLocalePickerTestCommand(command, params, client) {
|
||||
showLocaleChooserForPlayer(client);
|
||||
}
|
||||
|
||||
@@ -31,10 +31,19 @@ function playerPayDay(client) {
|
||||
let grossIncome = getPlayerData(client).payDayAmount;
|
||||
|
||||
// Passive income
|
||||
grossIncome = Math.round(grossIncome + getGlobalConfig().economy.passiveIncomePerPayDay);
|
||||
grossIncome = Math.round(grossIncome + getServerConfig().economy.passiveIncomePerPayDay);
|
||||
|
||||
// Job Pay
|
||||
if (getPlayerJob(client) != -1) {
|
||||
if (!getJobRankData(getPlayerJob(client), getPlayerJobRank(client))) {
|
||||
grossIncome = grossIncome + 0;
|
||||
} else {
|
||||
grossIncome = Math.round(grossIncome + getJobRankData(getPlayerJob(client), getPlayerJobRank(client)).pay);
|
||||
}
|
||||
}
|
||||
|
||||
// Payday bonus
|
||||
grossIncome = Math.round(grossIncome * getGlobalConfig().economy.grossIncomeMultiplier);
|
||||
grossIncome = Math.round(grossIncome * getServerConfig().economy.grossIncomeMultiplier);
|
||||
|
||||
// Double bonus
|
||||
if (isDoubleBonusActive()) {
|
||||
@@ -50,7 +59,7 @@ function playerPayDay(client) {
|
||||
messagePlayerInfo(client, `Taxes: {ALTCOLOUR}${getCurrencyString(incomeTaxAmount)}`);
|
||||
messagePlayerInfo(client, `You receive: {ALTCOLOUR}${getCurrencyString(netIncome)}`);
|
||||
if (netIncome < incomeTaxAmount) {
|
||||
let totalCash = getPlayerCash(client);
|
||||
let totalCash = getPlayerCurrentSubAccount(client);
|
||||
let canPayNow = totalCash + netIncome;
|
||||
if (incomeTaxAmount <= canPayNow) {
|
||||
takePlayerCash(client, canPayNow);
|
||||
@@ -75,6 +84,7 @@ function playerPayDay(client) {
|
||||
}
|
||||
|
||||
givePlayerCash(client, netIncome);
|
||||
getPlayerData(client).payDayAmount = 0;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -84,9 +94,9 @@ function calculateWealth(client) {
|
||||
let houses = getAllHousesOwnedByPlayer(client);
|
||||
let businesses = getAllBusinessesOwnedByPlayer(client);
|
||||
|
||||
let vehicleUpKeep = applyServerInflationMultiplier(vehicles.length * getGlobalConfig().economy.upKeepCosts.upKeepPerVehicle);
|
||||
let houseUpKeep = applyServerInflationMultiplier(houses.length * getGlobalConfig().economy.upKeepCosts.upKeepPerHouse);
|
||||
let businessUpKeep = applyServerInflationMultiplier(businesses.length * getGlobalConfig().economy.upKeepCosts.upKeepPerBusiness);
|
||||
let vehicleUpKeep = applyServerInflationMultiplier(vehicles.length * getServerConfig().economy.upKeepCosts.upKeepPerVehicle);
|
||||
let houseUpKeep = applyServerInflationMultiplier(houses.length * getServerConfig().economy.upKeepCosts.upKeepPerHouse);
|
||||
let businessUpKeep = applyServerInflationMultiplier(businesses.length * getServerConfig().economy.upKeepCosts.upKeepPerBusiness);
|
||||
|
||||
return vehicleUpKeep + houseUpKeep + businessUpKeep;
|
||||
}
|
||||
@@ -94,7 +104,7 @@ function calculateWealth(client) {
|
||||
// ===========================================================================
|
||||
|
||||
function calculateIncomeTax(amount) {
|
||||
return amount * getGlobalConfig().economy.incomeTaxRate;
|
||||
return amount * getServerConfig().economy.incomeTaxRate;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -117,26 +127,6 @@ function forcePlayerPayDayCommand(command, params, client) {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function setPayDayBonusMultiplier(command, params, client) {
|
||||
if (areParamsEmpty(params)) {
|
||||
messagePlayerSyntax(client, getCommandSyntaxText(command));
|
||||
return false;
|
||||
}
|
||||
|
||||
let newMultiplier = params;
|
||||
|
||||
if (isNaN(newMultiplier)) {
|
||||
messagePlayerError(client, getLocaleString(client, "AmountNotNumber"));
|
||||
return false;
|
||||
}
|
||||
|
||||
getGlobalConfig().economy.grossIncomeMultiplier = newMultiplier;
|
||||
|
||||
announceAdminAction(`PaydayBonusSet`, `{adminOrange}${getPlayerName(client)}{MAINCOLOUR}`, `{ALTCOLOUR}${newMultiplier * 100}%{MAINCOLOUR}`);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function taxInfoCommand(command, params, client) {
|
||||
let wealth = calculateWealth(client);
|
||||
let tax = calculateIncomeTax(wealth);
|
||||
@@ -168,19 +158,19 @@ function repossessFirstAsset(client) {
|
||||
let vehicles = getAllVehiclesOwnedByPlayer(client);
|
||||
if (vehicles.length > 0) {
|
||||
deleteVehicle(vehicles[0]);
|
||||
return getGlobalConfig().economy.upKeepCosts.upKeepPerVehicle;
|
||||
return getServerConfig().economy.upKeepCosts.upKeepPerVehicle;
|
||||
}
|
||||
|
||||
let houses = getAllHousesOwnedByPlayer(client);
|
||||
if (houses.length > 0) {
|
||||
deleteHouse(houses[0].index);
|
||||
return getGlobalConfig().economy.upKeepCosts.upKeepPerHouse;
|
||||
return getServerConfig().economy.upKeepCosts.upKeepPerHouse;
|
||||
}
|
||||
|
||||
let businesses = getAllBusinessesOwnedByPlayer(client);
|
||||
if (businesses.length > 0) {
|
||||
deleteBusiness(businesses[0].index);
|
||||
return getGlobalConfig().economy.upKeepCosts.upKeepPerBusiness;
|
||||
return getServerConfig().economy.upKeepCosts.upKeepPerBusiness;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,9 +205,202 @@ function isDoubleBonusActive() {
|
||||
// ===========================================================================
|
||||
|
||||
function getCurrencyString(amount) {
|
||||
let tempString = getGlobalConfig().economy.currencyString;
|
||||
let tempString = getServerConfig().economy.currencyString;
|
||||
tempString = tempString.replace("{AMOUNT}", toString(makeLargeNumberReadable(amount)));
|
||||
return tempString;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function setPassiveIncomeCommand(command, params, client) {
|
||||
if (areParamsEmpty(params)) {
|
||||
messagePlayerSyntax(client, getCommandSyntaxText(command));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isNaN(params)) {
|
||||
messagePlayerError(client, "The amount needs to be a number!");
|
||||
return false;
|
||||
}
|
||||
|
||||
let amount = toInteger(params);
|
||||
|
||||
if (amount <= 0) {
|
||||
messagePlayerError(client, "The amount can't be negative!");
|
||||
return false;
|
||||
}
|
||||
|
||||
getServerConfig().economy.passiveIncomePerPayDay = amount;
|
||||
getServerConfig().needsSaved = true;
|
||||
messageAdmins(`{adminOrange}${client.name}{MAINCOLOUR} set the passive income to {ALTCOLOUR}${getCurrencyString(amount)}`);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function setCurrencyStringCommand(command, params, client) {
|
||||
if (areParamsEmpty(params)) {
|
||||
messagePlayerSyntax(client, getCommandSyntaxText(command));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (params.indexOf("{AMOUNT}") == -1) {
|
||||
messagePlayerError(client, "The currency text must include {AMOUNT}");
|
||||
return false;
|
||||
}
|
||||
|
||||
getServerConfig().economy.currencyString = params;
|
||||
getServerConfig().needsSaved = true;
|
||||
messageAdmins(`{adminOrange}${client.name}{MAINCOLOUR} set the to currency string to {ALTCOLOUR}${params}. Example: ${getCurrencyString(1000)}`);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function setVehicleUpkeepCommand(command, params, client) {
|
||||
if (areParamsEmpty(params)) {
|
||||
messagePlayerSyntax(client, getCommandSyntaxText(command));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isNaN(params)) {
|
||||
messagePlayerError(client, "The amount needs to be a number!");
|
||||
return false;
|
||||
}
|
||||
|
||||
let amount = toInteger(params);
|
||||
|
||||
if (amount <= 0) {
|
||||
messagePlayerError(client, "The amount can't be negative!");
|
||||
return false;
|
||||
}
|
||||
|
||||
getServerConfig().economy.upKeepCosts.upKeepPerVehicle = amount;
|
||||
getServerConfig().needsSaved = true;
|
||||
messageAdmins(`{adminOrange}${client.name}{MAINCOLOUR} set the base upkeep per vehicle to {ALTCOLOUR}${getCurrencyString(amount)}`);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function setBusinessUpkeepCommand(command, params, client) {
|
||||
if (areParamsEmpty(params)) {
|
||||
messagePlayerSyntax(client, getCommandSyntaxText(command));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isNaN(params)) {
|
||||
messagePlayerError(client, "The amount needs to be a number!");
|
||||
return false;
|
||||
}
|
||||
|
||||
let amount = toInteger(params);
|
||||
|
||||
if (amount <= 0) {
|
||||
messagePlayerError(client, "The amount can't be negative!");
|
||||
return false;
|
||||
}
|
||||
|
||||
getServerConfig().economy.upKeepCosts.upKeepPerBusiness = amount;
|
||||
getServerConfig().needsSaved = true;
|
||||
messageAdmins(`{adminOrange}${client.name}{MAINCOLOUR} set the base upkeep per business to {ALTCOLOUR}${getCurrencyString(amount)}`);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function setHouseUpkeepCommand(command, params, client) {
|
||||
if (areParamsEmpty(params)) {
|
||||
messagePlayerSyntax(client, getCommandSyntaxText(command));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isNaN(params)) {
|
||||
messagePlayerError(client, "The amount needs to be a number!");
|
||||
return false;
|
||||
}
|
||||
|
||||
let amount = toInteger(params);
|
||||
|
||||
if (amount <= 0) {
|
||||
messagePlayerError(client, "The amount can't be negative!");
|
||||
return false;
|
||||
}
|
||||
|
||||
getServerConfig().economy.upKeepCosts.upKeepPerHouse = amount;
|
||||
getServerConfig().needsSaved = true;
|
||||
messageAdmins(`{adminOrange}${client.name}{MAINCOLOUR} set the base upkeep per house to {ALTCOLOUR}${getCurrencyString(amount)}`);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function setIncomeTaxCommand(command, params, client) {
|
||||
if (areParamsEmpty(params)) {
|
||||
messagePlayerSyntax(client, getCommandSyntaxText(command));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isNaN(params)) {
|
||||
messagePlayerError(client, "The amount needs to be a number!");
|
||||
return false;
|
||||
}
|
||||
|
||||
let amount = toInteger(params);
|
||||
|
||||
if (amount <= 0) {
|
||||
messagePlayerError(client, "The amount can't be negative!");
|
||||
return false;
|
||||
}
|
||||
|
||||
getServerConfig().economy.incomeTaxRate = amount / 100;
|
||||
getServerConfig().needsSaved = true;
|
||||
messageAdmins(`{adminOrange}${client.name}{MAINCOLOUR} set the income tax rate to {ALTCOLOUR}${amount}%`);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function setGrossIncomeMultiplierCommand(command, params, client) {
|
||||
if (areParamsEmpty(params)) {
|
||||
messagePlayerSyntax(client, getCommandSyntaxText(command));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isNaN(params)) {
|
||||
messagePlayerError(client, "The amount needs to be a number!");
|
||||
return false;
|
||||
}
|
||||
|
||||
let amount = toInteger(params);
|
||||
|
||||
if (amount <= 0) {
|
||||
messagePlayerError(client, "The amount can't be negative!");
|
||||
return false;
|
||||
}
|
||||
|
||||
getServerConfig().economy.grossIncomeMultiplier = amount / 100;
|
||||
getServerConfig().needsSaved = true;
|
||||
messageAdmins(`{adminOrange}${client.name}{MAINCOLOUR} set the gross income multiplier to {ALTCOLOUR}${amount}%`);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function setInflationMultiplierCommand(command, params, client) {
|
||||
if (areParamsEmpty(params)) {
|
||||
messagePlayerSyntax(client, getCommandSyntaxText(command));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isNaN(params)) {
|
||||
messagePlayerError(client, "The amount needs to be a number!");
|
||||
return false;
|
||||
}
|
||||
|
||||
let amount = toInteger(params);
|
||||
|
||||
if (amount <= 0) {
|
||||
messagePlayerError(client, "The amount can't be negative!");
|
||||
return false;
|
||||
}
|
||||
|
||||
getServerConfig().economy.inflationMultiplier = amount / 100;
|
||||
getServerConfig().needsSaved = true;
|
||||
messageAdmins(`{adminOrange}${client.name}{MAINCOLOUR} set the server inflation {ALTCOLOUR}${amount}%`);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -21,28 +21,28 @@ function initEmailScript() {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
async function sendEmail(toEmail, toName, subject, body) {
|
||||
function sendEmail(toEmail, toName, subject, body) {
|
||||
switch (getEmailConfig().method) {
|
||||
case V_EMAIL_METHOD_SMTP_MODULE:
|
||||
if (!checkForSMTPModule()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Promise.resolve().then(() => {
|
||||
module.smtp.send(
|
||||
getEmailConfig().smtp.host,
|
||||
getEmailConfig().smtp.port,
|
||||
intToBool(getEmailConfig().smtp.useTLS),
|
||||
getEmailConfig().smtp.username,
|
||||
getEmailConfig().smtp.password,
|
||||
toEmail,
|
||||
toName,
|
||||
subject,
|
||||
body,
|
||||
getEmailConfig().smtp.from,
|
||||
getEmailConfig().smtp.fromName
|
||||
);
|
||||
});
|
||||
//Promise.resolve().then(() => {
|
||||
module.smtp.send(
|
||||
getEmailConfig().smtp.host,
|
||||
getEmailConfig().smtp.port,
|
||||
intToBool(getEmailConfig().smtp.useTLS),
|
||||
getEmailConfig().smtp.username,
|
||||
getEmailConfig().smtp.password,
|
||||
toEmail,
|
||||
toName,
|
||||
subject,
|
||||
body,
|
||||
getEmailConfig().smtp.from,
|
||||
getEmailConfig().smtp.fromName
|
||||
);
|
||||
//});
|
||||
break;
|
||||
|
||||
case V_EMAIL_METHOD_GET_REQUEST:
|
||||
|
||||
@@ -15,38 +15,6 @@ function initEventScript() {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function addAllEventHandlers() {
|
||||
addEventHandler("onResourceStart", onResourceStart);
|
||||
addEventHandler("onResourceStop", onResourceStop);
|
||||
addEventHandler("onProcess", onProcess);
|
||||
addEventHandler("onPlayerConnect", onPlayerConnect);
|
||||
addEventHandler("onPlayerJoin", onPlayerJoin);
|
||||
addEventHandler("onPlayerJoined", onPlayerJoined);
|
||||
addEventHandler("onPlayerChat", onPlayerChat);
|
||||
addEventHandler("onPlayerQuit", onPlayerQuit);
|
||||
addEventHandler("onElementStreamIn", onElementStreamIn);
|
||||
addEventHandler("onElementStreamOut", onElementStreamOut);
|
||||
addEventHandler("onPedSpawn", onPedSpawn);
|
||||
|
||||
if (getGame() <= V_GAME_GTA_IV) {
|
||||
addEventHandler("onPedEnteredVehicleEx", onPedEnteredVehicle);
|
||||
addEventHandler("onPedExitedVehicleEx", onPedExitedVehicle);
|
||||
addEventHandler("onPedEnteredSphereEx", onPedEnteredSphere);
|
||||
addEventHandler("onPedExitedSphereEx", onPedExitedSphere);
|
||||
}
|
||||
|
||||
if (getGame() <= V_GAME_GTA_SA) {
|
||||
addEventHandler("OnPickupCollected", onPedPickupPickedUp);
|
||||
}
|
||||
|
||||
if (getGame() == V_GAME_MAFIA_ONE) {
|
||||
addEventHandler("onPedEnteringVehicleEx", onPedEnteredVehicle);
|
||||
addEventHandler("onPedExitingVehicleEx", onPedExitedVehicle);
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function onPlayerConnect(event, ipAddress, port) {
|
||||
logToConsole(LOG_INFO, `[V.RP.Event] onPlayerConnect - Client connecting (IP: ${ipAddress})`);
|
||||
//if(isIpAddressBanned(ipAddress)) {
|
||||
@@ -148,7 +116,7 @@ function onPlayerQuit(event, client, quitReasonId) {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
async function onPlayerChat(event, client, messageText) {
|
||||
function onPlayerChat(event, client, messageText) {
|
||||
event.preventDefault();
|
||||
processPlayerChat(client, messageText);
|
||||
}
|
||||
@@ -451,7 +419,7 @@ function onPedSpawn(ped) {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
async function onPlayerSpawn(client) {
|
||||
function onPlayerSpawn(client) {
|
||||
logToConsole(LOG_WARN | LOG_DEBUG, `[V.RP.Event] Player ${getPlayerDisplayForConsole(client)} spawned!`);
|
||||
//logToConsole(LOG_DEBUG, `[V.RP.Event] Checking for ${getPlayerDisplayForConsole(client)}'s player ped`);
|
||||
//if(getPlayerPed(client) == null) {
|
||||
@@ -462,7 +430,7 @@ async function onPlayerSpawn(client) {
|
||||
//logToConsole(LOG_DEBUG, `[V.RP.Event] ${getPlayerDisplayForConsole(client)}'s player ped is valid. Continuing spawn processing ...`);
|
||||
|
||||
if (areServerElementsSupported()) {
|
||||
await waitUntil(() => client != null && getPlayerPed(client) != null);
|
||||
waitUntil(() => client != null && getPlayerPed(client) != null);
|
||||
}
|
||||
|
||||
stopRadioStreamForPlayer(client);
|
||||
@@ -547,7 +515,7 @@ async function onPlayerSpawn(client) {
|
||||
}
|
||||
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Event] Sending ${getPlayerDisplayForConsole(client)}'s job type to their client (${getJobIndexFromDatabaseId(getPlayerCurrentSubAccount(client))})`);
|
||||
sendPlayerJobType(client, getPlayerCurrentSubAccount(client).job);
|
||||
sendPlayerJobType(client, (getPlayerCurrentSubAccount(client).job != 0) ? getPlayerCurrentSubAccount(client).jobIndex : -1);
|
||||
|
||||
if (isGameFeatureSupported("rendering2D")) {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Event] Enabling all rendering states for ${getPlayerDisplayForConsole(client)}`);
|
||||
@@ -587,6 +555,16 @@ async function onPlayerSpawn(client) {
|
||||
let keyId = getPlayerKeyBindForCommand(client, "enter");
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Event] Sending custom enter property key ID (${keyId.key}, ${toUpperCase(getKeyNameFromId(keyId.key))}) to ${getPlayerDisplayForConsole(client)}`);
|
||||
sendPlayerEnterPropertyKey(client, keyId.key);
|
||||
} else {
|
||||
sendPlayerEnterPropertyKey(client, -1);
|
||||
}
|
||||
|
||||
if (!doesPlayerHaveKeyBindsDisabled(client) && doesPlayerHaveKeyBindForCommand(client, "scoreboard")) {
|
||||
let keyId = getPlayerKeyBindForCommand(client, "scoreboard");
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Event] Sending scoreboard key ID (${keyId.key}, ${toUpperCase(getKeyNameFromId(keyId.key))}) to ${getPlayerDisplayForConsole(client)}`);
|
||||
sendPlayerScoreBoardKey(client, keyId.key);
|
||||
} else {
|
||||
sendPlayerScoreBoardKey(client, -1);
|
||||
}
|
||||
|
||||
sendPlayerChatBoxTimeStampsState(client, isPlayerAccountSettingEnabled(client, "ChatBoxTimestamps"));
|
||||
@@ -638,6 +616,7 @@ async function onPlayerSpawn(client) {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Event] Sending properties, jobs, and vehicles to ${getPlayerDisplayForConsole(client)} (no server elements)`);
|
||||
sendAllBusinessesToPlayer(client);
|
||||
sendAllHousesToPlayer(client);
|
||||
sendAllPayPhonesToPlayer(client);
|
||||
if (getGame() != V_GAME_GTA_IV) {
|
||||
sendAllJobsToPlayer(client);
|
||||
}
|
||||
@@ -768,7 +747,7 @@ function onPedExitedVehicle(event, ped, vehicle, seat) {
|
||||
|
||||
getVehicleData(vehicle).lastActiveTime = getCurrentUnixTimestamp();
|
||||
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Event] ${getPlayerDisplayForConsole(client)} exited a ${getVehicleName(vehicle)} (ID: ${vehicle.getData("v.rp.dataSlot")}, Database ID: ${getVehicleData(vehicle).databaseId})`);
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Event] ${getPlayerDisplayForConsole(client)} exited a ${getVehicleName(vehicle)} (ID: ${getVehicleDataIndexFromVehicle(vehicle)}, Database ID: ${getVehicleData(vehicle).databaseId})`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -803,7 +782,7 @@ function onPedEnteredVehicle(event, ped, vehicle, seat) {
|
||||
return false;
|
||||
}
|
||||
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Event] ${getPlayerDisplayForConsole(client)} entered a ${getVehicleName(vehicle)} (ID: ${vehicle.getData("v.rp.dataSlot")}, Database ID: ${getVehicleData(vehicle).databaseId})`);
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Event] ${getPlayerDisplayForConsole(client)} entered a ${getVehicleName(vehicle)} (ID: ${getVehicleDataIndexFromVehicle(vehicle)}, Database ID: ${getVehicleData(vehicle).databaseId})`);
|
||||
|
||||
getPlayerData(client).lastVehicle = vehicle;
|
||||
getVehicleData(vehicle).lastActiveTime = getCurrentUnixTimestamp();
|
||||
|
||||
@@ -22,6 +22,29 @@ const V_FISHING_LINE_STATE_HOOKED = 5;
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
class FishingLocationData {
|
||||
constructor(dbAssoc = false) {
|
||||
this.databaseId = 0;
|
||||
this.serverId = 0;
|
||||
this.index = -1;
|
||||
this.position = toVector3(0.0, 0.0, 0.0);
|
||||
this.enabled = false;
|
||||
this.whoAdded = 0;
|
||||
this.whenAdded = 0;
|
||||
|
||||
if (dbAssoc) {
|
||||
this.databaseId = toInteger(dbAssoc["fish_loc_id"]);
|
||||
this.serverId = toInteger(dbAssoc["fish_loc_server"]);
|
||||
this.enabled = intToBool(dbAssoc["fish_loc_enabled"]);
|
||||
this.position = toVector3(toFloat(dbAssoc["fish_loc_pos_x"]), toFloat(dbAssoc["fish_loc_pos_y"]), toFloat(dbAssoc["fish_loc_pos_z"]));
|
||||
this.whoAdded = toInteger(dbAssoc["fish_loc_who_added"]);
|
||||
this.whenAdded = toInteger(dbAssoc["fish_loc_when_added"]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
let fishingCollectables = [
|
||||
// Fish
|
||||
["Salmon", V_FISHING_CATCH_TYPE_FISH],
|
||||
@@ -63,7 +86,11 @@ let fishingAnimations = {
|
||||
[V_GAME_GTA_SA]: {
|
||||
"fishingLineCasting": "none",
|
||||
"fishingLineReeling": "none",
|
||||
}
|
||||
},
|
||||
//[V_GAME_MAFIA_ONE]: {
|
||||
// "fishingLineCasting": "none",
|
||||
// "fishingLineReeling": "none",
|
||||
//}
|
||||
};
|
||||
|
||||
// ===========================================================================
|
||||
@@ -205,4 +232,16 @@ function isPlayerFishing(client) {
|
||||
return (getPlayerData(client).fishingLineState != V_FISHING_LINE_STATE_NONE);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function getClosestFishingLocation(position) {
|
||||
let closest = 0;
|
||||
for (let i in getServerData().fishingLocations) {
|
||||
if (getDistance(position, getServerData().fishingLocations[i].position) < getDistance(position, getServerData().fishingLocations[closest].position))
|
||||
closest = i;
|
||||
}
|
||||
|
||||
return closest;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -15,6 +15,7 @@ function initHelpScript() {
|
||||
// ===========================================================================
|
||||
|
||||
let randomTips = [
|
||||
/*
|
||||
`{MAINCOLOUR}Look for yellow dots on your map for job locations.`,
|
||||
`{MAINCOLOUR}You can set custom key binds. Use {ALTCOLOUR}/info keys {MAINCOLOUR} for details.`,
|
||||
`{MAINCOLOUR}Use /notips if you don't want to see tips and extra information`,
|
||||
@@ -43,6 +44,7 @@ let randomTips = [
|
||||
//`{MAINCOLOUR}Banks can provide loans. Use {ALTCOLOUR}/info loans {MAINCOLOUR} for more details.`,
|
||||
`{MAINCOLOUR}Want to make a clan? Use {ALTCOLOUR}/info clans {MAINCOLOUR} for details.`,
|
||||
`{MAINCOLOUR}Legal weapons can be purchased at any ammunation.`,
|
||||
*/
|
||||
];
|
||||
|
||||
// ===========================================================================
|
||||
@@ -87,13 +89,13 @@ function helpCommand(command, params, client) {
|
||||
showRulesHelpMessage(client);
|
||||
break;
|
||||
|
||||
case "website":
|
||||
showWebsiteHelpMessage(client);
|
||||
break;
|
||||
//case "website":
|
||||
// showWebsiteHelpMessage(client);
|
||||
// break;
|
||||
|
||||
case "discord":
|
||||
showDiscordHelpMessage(client);
|
||||
break;
|
||||
//case "discord":
|
||||
// showDiscordHelpMessage(client);
|
||||
// break;
|
||||
|
||||
case "anim":
|
||||
case "anims":
|
||||
@@ -147,6 +149,14 @@ function helpCommand(command, params, client) {
|
||||
showWealthAndTaxHelpMessage(client);
|
||||
break;
|
||||
|
||||
case "admin":
|
||||
showAdminHelpMessage(client, getParam(params, " ", 2));
|
||||
break;
|
||||
|
||||
//case "items":
|
||||
// showItemsHelpMessage(client);
|
||||
// break;
|
||||
|
||||
default:
|
||||
showMainHelpMessage(client);
|
||||
break;
|
||||
@@ -184,8 +194,8 @@ function helpCommand(command, params, client) {
|
||||
function showMainHelpMessage(client) {
|
||||
messagePlayerInfo(client, makeChatBoxSectionHeader(getLocaleString(client, "HelpMainListHeader")));
|
||||
messagePlayerNormal(client, `{clanOrange}• {MAINCOLOUR}Use /info <category> for commands and info. Example: {ALTCOLOUR}/info vehicle`);
|
||||
messagePlayerNormal(client, `{clanOrange}• {MAINCOLOUR}Help Categories: [#A9A9A9]account, command, vehicle, job, chat, rules, website, animation`);
|
||||
messagePlayerNormal(client, `{clanOrange}• [#A9A9A9]skin, mechanic, dealership, discord, colour, keybind`);
|
||||
messagePlayerNormal(client, `{clanOrange}• {MAINCOLOUR}Help Categories: [#A9A9A9]account, command, vehicle, job, chat, rules, animation`);
|
||||
messagePlayerNormal(client, `{clanOrange}• [#A9A9A9]skin, mechanic, dealership, colour, keybind`);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -252,6 +262,7 @@ function showRulesHelpMessage(client) {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
/*
|
||||
function showWebsiteHelpMessage(client) {
|
||||
messagePlayerInfo(client, makeChatBoxSectionHeader(getLocaleString(client, "HeaderWebsiteInfo")));
|
||||
messagePlayerHelpContent(client, `{MAINCOLOUR}${server.getRule("Website")}`);
|
||||
@@ -263,6 +274,7 @@ function showDiscordHelpMessage(client) {
|
||||
messagePlayerInfo(client, makeChatBoxSectionHeader(getLocaleString(client, "HeaderDiscordInfo")));
|
||||
messagePlayerHelpContent(client, `{MAINCOLOUR}${server.getRule("Discord")}`);
|
||||
}
|
||||
*/
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
@@ -326,14 +338,39 @@ function showRadioHelpMessage(client) {
|
||||
|
||||
function showWealthAndTaxHelpMessage(client) {
|
||||
messagePlayerInfo(client, makeChatBoxSectionHeader(getLocaleString(client, "HeaderWealthandTaxHelp")));
|
||||
messagePlayerHelpContent(client, getGroupedLocaleString(client, "WealthAndTaxHelp", 0, `{ALTCOLOUR}${100 * getGlobalConfig().economy.incomeTaxRate}%{MAINCOLOUR}`));
|
||||
messagePlayerHelpContent(client, getGroupedLocaleString(client, "WealthAndTaxHelp", 0, `{ALTCOLOUR}${100 * getServerConfig().economy.incomeTaxRate}%{MAINCOLOUR}`));
|
||||
messagePlayerHelpContent(client, getGroupedLocaleString(client, "WealthAndTaxHelp", 1));
|
||||
messagePlayerHelpContent(client, getGroupedLocaleString(client, "WealthAndTaxHelp", 2, `{ALTCOLOUR}${getGlobalConfig().economy.upKeepCosts.upKeepPerVehicle}{MAINCOLOUR}`, `{ALTCOLOUR}${getGlobalConfig().economy.upKeepCosts.upKeepPerHouse}{MAINCOLOUR}`, `{ALTCOLOUR}${getGlobalConfig().economy.upKeepCosts.upKeepPerBusiness}{MAINCOLOUR}`));
|
||||
messagePlayerHelpContent(client, getGroupedLocaleString(client, "WealthAndTaxHelp", 2, `{ALTCOLOUR}${getServerConfig().economy.upKeepCosts.upKeepPerVehicle}{MAINCOLOUR}`, `{ALTCOLOUR}${getServerConfig().economy.upKeepCosts.upKeepPerHouse}{MAINCOLOUR}`, `{ALTCOLOUR}${getServerConfig().economy.upKeepCosts.upKeepPerBusiness}{MAINCOLOUR}`));
|
||||
messagePlayerHelpContent(client, getGroupedLocaleString(client, "WealthAndTaxHelp", 3, `{ALTCOLOUR}/wealth{MAINCOLOUR}`, `{ALTCOLOUR}/tax{MAINCOLOUR}`));
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function showAdminHelpMessage(client, flagName) {
|
||||
if (getPlayerData(client).accountData.flags.admin == 0) {
|
||||
messagePlayerError(client, getLocaleString(client, "CommandNoPermissions", `{ALTCOLOUR}/info admin`));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!flagName) {
|
||||
messagePlayerSyntax(client, `${getCommandSyntaxText("help")} admin <flag name>`);
|
||||
messagePlayerInfo(client, `Use /staffflags to see a list of staff flags`);
|
||||
return false;
|
||||
}
|
||||
|
||||
let commandList = getCommandsUsableByStaffFlag(flagName).map(function (x) {
|
||||
return `/${x.command}`;
|
||||
});
|
||||
let chunkedList = splitArrayIntoChunks(commandList, 8);
|
||||
|
||||
messagePlayerNormal(client, makeChatBoxSectionHeader(getLocaleString(client, "HeaderCommandsForStaffFlagList", flagName)));
|
||||
for (let i in chunkedList) {
|
||||
messagePlayerNormal(client, `{ALTCOLOUR}${chunkedList[i].join(", ")}{MAINCOLOUR}`);
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function showCommandHelpMessage(client, commandName) {
|
||||
if (!commandName) {
|
||||
messagePlayerSyntax(client, `${getCommandSyntaxText("help")}command <command name>`);
|
||||
|
||||
@@ -213,7 +213,16 @@ function createHouseCommand(command, params, client) {
|
||||
return false;
|
||||
}
|
||||
|
||||
createHouse(params, getPlayerPosition(client), toVector3(0.0, 0.0, 0.0), getGameConfig().pickupModels[getGame()].House, -1, getPlayerInterior(client), getPlayerDimension(client), getPlayerData(client).interiorScene);
|
||||
createHouse(
|
||||
params,
|
||||
getPlayerPosition(client),
|
||||
toVector3(0.0, 0.0, 0.0),
|
||||
(isGameFeatureSupported("pickup")) ? getGameConfig().pickupModels[getGame()].House : -1,
|
||||
-1,
|
||||
getPlayerInterior(client),
|
||||
getPlayerDimension(client),
|
||||
getPlayerData(client).interiorScene
|
||||
);
|
||||
messageAdmins(`{adminOrange}${getPlayerName(client)}{MAINCOLOUR} created house: {houseGreen}${params}`, true);
|
||||
}
|
||||
|
||||
@@ -461,7 +470,7 @@ function setHousePickupCommand(command, params, client) {
|
||||
getHouseData(houseId).entrancePickupModel = toInteger(typeParam);
|
||||
}
|
||||
|
||||
deleteHouseEntrancePickup(houseId);
|
||||
despawnHouseEntrancePickup(houseId);
|
||||
spawnHouseEntrancePickup(houseId);
|
||||
|
||||
getHouseData(houseId).needsSaved = true;
|
||||
@@ -525,8 +534,8 @@ function setHouseInteriorTypeCommand(command, params, client) {
|
||||
getHouseData(houseId).hasInterior = true;
|
||||
}
|
||||
|
||||
deleteHouseEntrancePickup(houseId);
|
||||
deleteHouseExitPickup(houseId);
|
||||
despawnHouseEntrancePickup(houseId);
|
||||
despawnHouseExitPickup(houseId);
|
||||
spawnHouseEntrancePickup(houseId);
|
||||
spawnHouseExitPickup(houseId);
|
||||
|
||||
@@ -652,8 +661,8 @@ function moveHouseExitCommand(command, params, client) {
|
||||
//createAllHouseBlips(houseId);
|
||||
//createAllHousePickups(houseId);
|
||||
|
||||
deleteHouseExitPickup(houseId);
|
||||
deleteHouseExitBlip(houseId);
|
||||
despawnHouseExitPickup(houseId);
|
||||
despawnHouseExitBlip(houseId);
|
||||
spawnHouseExitPickup(houseId);
|
||||
spawnHouseExitBlip(houseId);
|
||||
|
||||
@@ -714,11 +723,11 @@ function deleteHouse(houseIndex, whoDeleted = 0) {
|
||||
disconnectFromDatabase(dbConnection);
|
||||
}
|
||||
|
||||
deleteHouseEntrancePickup(houseIndex);
|
||||
deleteHouseExitPickup(houseIndex);
|
||||
despawnHouseEntrancePickup(houseIndex);
|
||||
despawnHouseExitPickup(houseIndex);
|
||||
|
||||
deleteHouseEntranceBlip(houseIndex);
|
||||
deleteHouseExitBlip(houseIndex);
|
||||
despawnHouseEntranceBlip(houseIndex);
|
||||
despawnHouseExitBlip(houseIndex);
|
||||
|
||||
removePlayersFromHouse(houseIndex);
|
||||
|
||||
@@ -1049,35 +1058,45 @@ function spawnHouseEntrancePickup(houseId) {
|
||||
// return false;
|
||||
//}
|
||||
|
||||
if (houseData.entrancePickupModel == -1) {
|
||||
return false;
|
||||
}
|
||||
logToConsole(LOG_VERBOSE, `[V.RP.House]: Creating entrance pickup for house ${houseData.description} (${houseData.databaseId})`);
|
||||
|
||||
if (areServerElementsSupported() && getGame() != V_GAME_MAFIA_ONE && getGame() != V_GAME_GTA_IV) {
|
||||
let entrancePickup = null;
|
||||
if (isGameFeatureSupported("pickup")) {
|
||||
let pickupModelId = getGameConfig().pickupModels[getGame()].House;
|
||||
|
||||
if (houseData.entrancePickupModel == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getServerData().houses[houseId].entrancePickupModel != 0) {
|
||||
pickupModelId = getHouseData(houseId).entrancePickupModel;
|
||||
}
|
||||
|
||||
entrancePickup = createGamePickup(pickupModelId, houseData.entrancePosition, getGameConfig().pickupTypes[getGame()].house);
|
||||
} else if (isGameFeatureSupported("dummyElement")) {
|
||||
entrancePickup = createGameDummyElement(houseData.exitPosition);
|
||||
}
|
||||
|
||||
if (entrancePickup != null) {
|
||||
setElementOnAllDimensions(entrancePickup, false);
|
||||
setElementDimension(entrancePickup, getHouseData(houseId).entranceDimension);
|
||||
setElementStreamInDistance(entrancePickup, getGlobalConfig().housePickupStreamInDistance);
|
||||
setElementStreamOutDistance(entrancePickup, getGlobalConfig().housePickupStreamOutDistance);
|
||||
setElementTransient(entrancePickup, false);
|
||||
if (houseData.entranceDimension != -1) {
|
||||
setElementDimension(entrancePickup, houseData.entranceDimension);
|
||||
setElementOnAllDimensions(entrancePickup, false);
|
||||
} else {
|
||||
setElementOnAllDimensions(entrancePickup, true);
|
||||
}
|
||||
|
||||
if (getGlobalConfig().housePickupStreamInDistance == -1 || getGlobalConfig().housePickupStreamOutDistance == -1) {
|
||||
entrancePickup.netFlags.distanceStreaming = false;
|
||||
} else {
|
||||
setElementStreamInDistance(entrancePickup, getGlobalConfig().housePickupStreamInDistance);
|
||||
setElementStreamOutDistance(entrancePickup, getGlobalConfig().housePickupStreamInDistance);
|
||||
}
|
||||
setElementTransient(entrancePickup, false);
|
||||
getHouseData(houseId).entrancePickup = entrancePickup;
|
||||
updateHousePickupLabelData(houseId);
|
||||
}
|
||||
}
|
||||
|
||||
updateHousePickupLabelData(houseId);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -1482,7 +1501,7 @@ function doesHouseHaveInterior(houseId) {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function deleteHouseEntrancePickup(houseId) {
|
||||
function despawnHouseEntrancePickup(houseId) {
|
||||
if (!areServerElementsSupported()) {
|
||||
return false;
|
||||
}
|
||||
@@ -1496,7 +1515,7 @@ function deleteHouseEntrancePickup(houseId) {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function deleteHouseExitPickup(houseId) {
|
||||
function despawnHouseExitPickup(houseId) {
|
||||
if (!areServerElementsSupported()) {
|
||||
return false;
|
||||
}
|
||||
@@ -1510,7 +1529,7 @@ function deleteHouseExitPickup(houseId) {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function deleteHouseEntranceBlip(houseId) {
|
||||
function despawnHouseEntranceBlip(houseId) {
|
||||
if (!areServerElementsSupported()) {
|
||||
return false;
|
||||
}
|
||||
@@ -1524,7 +1543,7 @@ function deleteHouseEntranceBlip(houseId) {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function deleteHouseExitBlip(houseId) {
|
||||
function despawnHouseExitBlip(houseId) {
|
||||
if (!areServerElementsSupported()) {
|
||||
return false;
|
||||
}
|
||||
@@ -1556,10 +1575,10 @@ function reloadAllHousesCommand(command, params, client) {
|
||||
}
|
||||
|
||||
for (let i in getServerData().houses) {
|
||||
deleteHouseExitBlip(i);
|
||||
deleteHouseEntranceBlip(i);
|
||||
deleteHouseExitPickup(i);
|
||||
deleteHouseEntrancePickup(i);
|
||||
despawnHouseExitBlip(i);
|
||||
despawnHouseEntranceBlip(i);
|
||||
despawnHouseExitPickup(i);
|
||||
despawnHouseEntrancePickup(i);
|
||||
}
|
||||
|
||||
clearArray(getServerData().houses);
|
||||
@@ -1700,8 +1719,8 @@ function canPlayerLockUnlockHouse(client, houseId) {
|
||||
// ===========================================================================
|
||||
|
||||
function resetHousePickups(houseId) {
|
||||
deleteHouseEntrancePickup(houseId);
|
||||
deleteHouseExitPickup(houseId);
|
||||
despawnHouseEntrancePickup(houseId);
|
||||
despawnHouseExitPickup(houseId);
|
||||
spawnHouseEntrancePickup(houseId);
|
||||
spawnHouseExitPickup(houseId);
|
||||
}
|
||||
@@ -1709,8 +1728,8 @@ function resetHousePickups(houseId) {
|
||||
// ===========================================================================
|
||||
|
||||
function resetHouseBlips(houseId) {
|
||||
deleteHouseEntranceBlip(houseId);
|
||||
deleteHouseExitBlip(houseId);
|
||||
despawnHouseEntranceBlip(houseId);
|
||||
despawnHouseExitBlip(houseId);
|
||||
spawnHouseEntranceBlip(houseId);
|
||||
spawnHouseExitBlip(houseId);
|
||||
}
|
||||
@@ -1778,13 +1797,17 @@ function getHouseFromParams(params) {
|
||||
// ===========================================================================
|
||||
|
||||
function updateHousePickupLabelData(houseId) {
|
||||
let houseData = getHouseData(houseId);
|
||||
|
||||
if (!areServerElementsSupported() || getGame() == V_GAME_MAFIA_ONE || getGame() == V_GAME_GTA_IV) {
|
||||
sendHouseToPlayer(null, houseId, getHouseData(houseId).description, getHouseData(houseId).entrancePosition, getHouseEntranceBlipModelForNetworkEvent(houseId), getHouseEntrancePickupModelForNetworkEvent(houseId), getHouseData(houseId).buyPrice, getHouseData(houseId).rentPrice, getHouseData(houseId).hasInterior, getHouseData(houseId).locked);
|
||||
if (houseData == false) {
|
||||
sendHouseToPlayer(null, houseId, true, "", false, -1, -1, 0, 0, false, false, false);
|
||||
} else {
|
||||
sendHouseToPlayer(null, houseId, false, houseData.description, houseData.entrancePosition, getHouseEntranceBlipModelForNetworkEvent(houseId), getHouseEntrancePickupModelForNetworkEvent(houseId), houseData.buyPrice, houseData.rentPrice, houseData.hasInterior, houseData.locked);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
let houseData = getHouseData(houseId);
|
||||
|
||||
if (houseData.entrancePickup != null) {
|
||||
setEntityData(houseData.entrancePickup, "v.rp.owner.type", V_PICKUP_HOUSE_ENTRANCE, false);
|
||||
setEntityData(houseData.entrancePickup, "v.rp.owner.id", houseId, false);
|
||||
@@ -1813,8 +1836,8 @@ function updateHousePickupLabelData(houseId) {
|
||||
|
||||
function deleteAllHouseBlips() {
|
||||
for (let i in getServerData().houses) {
|
||||
deleteHouseEntranceBlip(i);
|
||||
deleteHouseExitBlip(i);
|
||||
despawnHouseEntranceBlip(i);
|
||||
despawnHouseExitBlip(i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1822,21 +1845,21 @@ function deleteAllHouseBlips() {
|
||||
|
||||
function deleteAllHousePickups() {
|
||||
for (let i in getServerData().houses) {
|
||||
deleteHouseEntrancePickup(i);
|
||||
deleteHouseExitPickup(i);
|
||||
despawnHouseEntrancePickup(i);
|
||||
despawnHouseExitPickup(i);
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function createHouseBlips(houseId) {
|
||||
function spawnHouseBlips(houseId) {
|
||||
spawnHouseEntranceBlip(houseId);
|
||||
spawnHouseExitBlip(houseId);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function createHousePickups(houseId) {
|
||||
function spawnHousePickups(houseId) {
|
||||
spawnHouseEntrancePickup(houseId);
|
||||
spawnHouseExitPickup(houseId);
|
||||
}
|
||||
@@ -1890,4 +1913,49 @@ function getHouseEntrancePickupModelForNetworkEvent(houseIndex) {
|
||||
return pickupModelId;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function getNearbyBusinessesCommand(command, params, client) {
|
||||
let distance = 10.0;
|
||||
|
||||
if (!areParamsEmpty(params)) {
|
||||
distance = getParam(params, " ", 1);
|
||||
}
|
||||
|
||||
if (isNaN(distance)) {
|
||||
messagePlayerError(client, "The distance must be a number!");
|
||||
return false;
|
||||
}
|
||||
|
||||
distance = toFloat(distance);
|
||||
|
||||
if (distance <= 0) {
|
||||
messagePlayerError(client, "The distance must be more than 0!");
|
||||
return false;
|
||||
}
|
||||
|
||||
let nearbyHouses = getHousesInRange(getPlayerPosition(client), distance);
|
||||
|
||||
if (nearbyHouses.length == 0) {
|
||||
messagePlayerAlert(client, getLocaleString(client, "NoHousesWithinRange", distance));
|
||||
return false;
|
||||
}
|
||||
|
||||
let housesList = nearbyHouses.map(function (x) {
|
||||
return `{chatBoxListIndex}${x.index}: {MAINCOLOUR}${x.description} {mediumGrey}(${toFloat(getDistance(getPlayerPosition(client), x.entrancePosition)).toFixed(2)} ${toLowerCase(getLocaleString(client, "Meters"))} ${toLowerCase(getGroupedLocaleString(client, "CardinalDirections", getCardinalDirectionName(getCardinalDirection(getPlayerPosition(client), x.entrancePosition))))})`;
|
||||
});
|
||||
let chunkedList = splitArrayIntoChunks(housesList, 4);
|
||||
|
||||
messagePlayerNormal(client, makeChatBoxSectionHeader(getLocaleString(client, "HeaderHousesInRangeList", `${distance} ${toLowerCase(getLocaleString(client, "Meters"))}`)));
|
||||
for (let i in chunkedList) {
|
||||
messagePlayerInfo(client, chunkedList[i].join(", "));
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function getHousesInRange(position, distance) {
|
||||
return getServerData().houses.filter((house) => getDistance(position, house.entrancePosition) <= distance);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -347,6 +347,8 @@ function createItem(itemTypeId, value, ownerType, ownerId, amount = 1) {
|
||||
let index = slot - 1;
|
||||
getServerData().items[slot - 1].index = index;
|
||||
getServerData().items[slot - 1].itemTypeIndex = itemTypeId;
|
||||
|
||||
saveItemToDatabase(slot - 1);
|
||||
return index;
|
||||
}
|
||||
|
||||
@@ -828,7 +830,7 @@ function createItemTypeCommand(command, params, client) {
|
||||
}
|
||||
|
||||
let itemTypeIndex = createItemType(params);
|
||||
messageAdmins(`{ALTCOLOUR}${getPlayerName(client)} created new item type: {ALTCOLOUR}${params}. {MAINCOLOUR}ID: ${itemTypeIndex}/${getItemTypeData(itemTypeIndex).databaseId}!`, true);
|
||||
messageAdmins(`{ALTCOLOUR}${getPlayerName(client)}{MAINCOLOUR} created new item type: {ALTCOLOUR}${params}. {MAINCOLOUR}ID: ${itemTypeIndex}/${getItemTypeData(itemTypeIndex).databaseId}!`, true);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -857,9 +859,14 @@ function setItemTypeDropModelCommand(command, params, client) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isNaN(orderPrice)) {
|
||||
messagePlayerError(client, `The model index must be a number!`);
|
||||
return false;
|
||||
}
|
||||
|
||||
getItemTypeData(itemTypeIndex).dropModel = modelIndex;
|
||||
getItemTypeData(itemTypeIndex).needsSaved = true;
|
||||
messageAdmins(`{ALTCOLOUR}${getPlayerName(client)} set item type {ALTCOLOUR}${getItemTypeData(itemTypeIndex).name}'s{MAINCOLOUR} dropped object model index to ${modelIndex}`, true);
|
||||
messageAdmins(`{ALTCOLOUR}${getPlayerName(client)}{MAINCOLOUR} set item type {ALTCOLOUR}${getItemTypeData(itemTypeIndex).name}'s{MAINCOLOUR} dropped object model index to ${modelIndex}`, true);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -888,9 +895,14 @@ function setItemTypeOrderPriceCommand(command, params, client) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isNaN(orderPrice)) {
|
||||
messagePlayerError(client, `The order price must be a number!`);
|
||||
return false;
|
||||
}
|
||||
|
||||
getItemTypeData(itemTypeIndex).orderPrice = orderPrice;
|
||||
getItemTypeData(itemTypeIndex).needsSaved = true;
|
||||
messageAdmins(`{ALTCOLOUR}${getPlayerName(client)} set item type {ALTCOLOUR}${getItemTypeData(itemTypeIndex).name}{MAINCOLOUR} base price to {ALTCOLOUR}${getCurrencyString(orderPrice)}`, true);
|
||||
messageAdmins(`{ALTCOLOUR}${getPlayerName(client)}{MAINCOLOUR} set item type {ALTCOLOUR}${getItemTypeData(itemTypeIndex).name}{MAINCOLOUR} base price to {ALTCOLOUR}${getCurrencyString(orderPrice)}`, true);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -919,9 +931,14 @@ function setItemTypeOrderValueCommand(command, params, client) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isNaN(orderValue)) {
|
||||
messagePlayerError(client, `The order value must be a number!`);
|
||||
return false;
|
||||
}
|
||||
|
||||
getItemTypeData(itemTypeIndex).orderValue = orderValue;
|
||||
getItemTypeData(itemTypeIndex).needsSaved = true;
|
||||
messageAdmins(`{ALTCOLOUR}${getPlayerName(client)} set item type {ALTCOLOUR}${getItemTypeData(itemTypeIndex).name}{MAINCOLOUR} order value to {ALTCOLOUR}${orderValue}`, true);
|
||||
messageAdmins(`{ALTCOLOUR}${getPlayerName(client)}{MAINCOLOUR} set item type {ALTCOLOUR}${getItemTypeData(itemTypeIndex).name}{MAINCOLOUR} order value to {ALTCOLOUR}${orderValue}`, true);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -950,9 +967,14 @@ function setItemTypeRiskMultiplierCommand(command, params, client) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isNaN(riskMultiplier)) {
|
||||
messagePlayerError(client, `The risk multiplier must be a number!`);
|
||||
return false;
|
||||
}
|
||||
|
||||
getItemTypeData(itemTypeIndex).riskMultiplier = riskMultiplier / 100;
|
||||
getItemTypeData(itemTypeIndex).needsSaved = true;
|
||||
messageAdmins(`{ALTCOLOUR}${getPlayerName(client)} set item type {ALTCOLOUR}${getItemTypeData(itemTypeIndex).name}{MAINCOLOUR} risk multiplier to {ALTCOLOUR}${riskMultiplier}%`, true);
|
||||
messageAdmins(`{ALTCOLOUR}${getPlayerName(client)}{MAINCOLOUR} set item type {ALTCOLOUR}${getItemTypeData(itemTypeIndex).name}{MAINCOLOUR} risk multiplier to {ALTCOLOUR}${riskMultiplier}%`, true);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -981,7 +1003,7 @@ function toggleItemTypeEnabledCommand(command, params, client) {
|
||||
|
||||
getItemTypeData(itemTypeIndex).enabled = !getItemTypeData(itemTypeIndex).enabled;
|
||||
getItemTypeData(itemTypeIndex).needsSaved = true;
|
||||
messageAdmins(`{ALTCOLOUR}${getPlayerName(client)} ${getEnabledDisabledFromBool(getItemTypeData(itemTypeIndex).enabled)} item type {ALTCOLOUR}${getItemTypeData(itemTypeIndex).name}`, true);
|
||||
messageAdmins(`{ALTCOLOUR}${getPlayerName(client)}{MAINCOLOUR} ${getEnabledDisabledFromBool(getItemTypeData(itemTypeIndex).enabled)} item type {ALTCOLOUR}${getItemTypeData(itemTypeIndex).name}`, true);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -1010,9 +1032,14 @@ function setItemTypeUseTypeCommand(command, params, client) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isNaN(useType)) {
|
||||
messagePlayerError(client, `The use type must be a number!`);
|
||||
return false;
|
||||
}
|
||||
|
||||
getItemTypeData(itemTypeIndex).useType = useType;
|
||||
getItemTypeData(itemTypeIndex).needsSaved = true;
|
||||
messageAdmins(`{ALTCOLOUR}${getPlayerName(client)} set item type {ALTCOLOUR}${getItemTypeData(itemTypeIndex).name}{MAINCOLOUR} use type to {ALTCOLOUR}${useType}`, true);
|
||||
messageAdmins(`{ALTCOLOUR}${getPlayerName(client)}{MAINCOLOUR} set item type {ALTCOLOUR}${getItemTypeData(itemTypeIndex).name}{MAINCOLOUR} use type to {ALTCOLOUR}${useType}`, true);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -1043,7 +1070,7 @@ function setItemTypeUseValueCommand(command, params, client) {
|
||||
|
||||
getItemTypeData(itemTypeIndex).useValue = useValue;
|
||||
getItemTypeData(itemTypeIndex).needsSaved = true;
|
||||
messageAdmins(`{ALTCOLOUR}${getPlayerName(client)} set item type {ALTCOLOUR}${getItemTypeData(itemTypeIndex).name}{MAINCOLOUR} use value to {ALTCOLOUR}${useValue}`, true);
|
||||
messageAdmins(`{ALTCOLOUR}${getPlayerName(client)}{MAINCOLOUR} set item type {ALTCOLOUR}${getItemTypeData(itemTypeIndex).name}{MAINCOLOUR} use value to {ALTCOLOUR}${useValue}`, true);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -1073,13 +1100,13 @@ function setItemTypeDropFrontDistanceCommand(command, params, client) {
|
||||
}
|
||||
|
||||
if (isNaN(dropFrontDistance)) {
|
||||
messagePlayerError(client, `The distance must be a number!`);
|
||||
messagePlayerError(client, `The front distance must be a number!`);
|
||||
return false;
|
||||
}
|
||||
|
||||
getItemTypeData(itemTypeIndex).dropFrontDistance = dropFrontDistance;
|
||||
getItemTypeData(itemTypeIndex).needsSaved = true;
|
||||
messageAdmins(`{ALTCOLOUR}${getPlayerName(client)} set item type {ALTCOLOUR}${getItemTypeData(itemTypeIndex).name}{MAINCOLOUR} drop front distance to {ALTCOLOUR}${dropFrontDistance.toFixed(2)}`, true);
|
||||
messageAdmins(`{ALTCOLOUR}${getPlayerName(client)}{MAINCOLOUR} set item type {ALTCOLOUR}${getItemTypeData(itemTypeIndex).name}{MAINCOLOUR} drop front distance to {ALTCOLOUR}${dropFrontDistance.toFixed(2)}`, true);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -1119,7 +1146,7 @@ function setItemTypeDropPositionCommand(command, params, client) {
|
||||
|
||||
getItemTypeData(itemTypeIndex).dropPosition = dropPosition;
|
||||
getItemTypeData(itemTypeIndex).needsSaved = true;
|
||||
messageAdmins(`{ALTCOLOUR}${getPlayerName(client)} set item type {ALTCOLOUR}${getItemTypeData(itemTypeIndex).name}{MAINCOLOUR} drop position offset to {ALTCOLOUR}${dropPosition.x.toFixed(2)}, ${dropPosition.y.toFixed(2)}, ${dropPosition.z.toFixed(2)}`, true);
|
||||
messageAdmins(`{ALTCOLOUR}${getPlayerName(client)}{MAINCOLOUR} set item type {ALTCOLOUR}${getItemTypeData(itemTypeIndex).name}{MAINCOLOUR} drop position offset to {ALTCOLOUR}${dropPosition.x.toFixed(2)}, ${dropPosition.y.toFixed(2)}, ${dropPosition.z.toFixed(2)}`, true);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -1151,7 +1178,7 @@ function setItemTypeDropRotationCommand(command, params, client) {
|
||||
}
|
||||
|
||||
if (isNaN(x) || isNaN(y) || isNaN(z)) {
|
||||
messagePlayerError(client, `The positions must be numbers!`);
|
||||
messagePlayerError(client, `The rotation values must be numbers!`);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1159,7 +1186,7 @@ function setItemTypeDropRotationCommand(command, params, client) {
|
||||
|
||||
getItemTypeData(itemTypeIndex).dropRotation = dropRotation;
|
||||
getItemTypeData(itemTypeIndex).needsSaved = true;
|
||||
messageAdmins(`{ALTCOLOUR}${getPlayerName(client)} set item type {ALTCOLOUR}${getItemTypeData(itemTypeIndex).name}{MAINCOLOUR} drop rotation to {ALTCOLOUR}${dropRotation.x.toFixed(2)}, ${dropRotation.y.toFixed(2)}, ${dropRotation.z.toFixed(2)}`, true);
|
||||
messageAdmins(`{ALTCOLOUR}${getPlayerName(client)}{MAINCOLOUR} set item type {ALTCOLOUR}${getItemTypeData(itemTypeIndex).name}{MAINCOLOUR} drop rotation to {ALTCOLOUR}${dropRotation.x.toFixed(2)}, ${dropRotation.y.toFixed(2)}, ${dropRotation.z.toFixed(2)}`, true);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -1191,7 +1218,7 @@ function setItemTypeDropScaleCommand(command, params, client) {
|
||||
}
|
||||
|
||||
if (isNaN(x) || isNaN(y) || isNaN(z)) {
|
||||
messagePlayerError(client, `The positions must be numbers!`);
|
||||
messagePlayerError(client, `The scale values must be numbers!`);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1199,7 +1226,7 @@ function setItemTypeDropScaleCommand(command, params, client) {
|
||||
|
||||
getItemTypeData(itemTypeIndex).dropScale = dropScale;
|
||||
getItemTypeData(itemTypeIndex).needsSaved = true;
|
||||
messageAdmins(`{ALTCOLOUR}${getPlayerName(client)} set item type {ALTCOLOUR}${getItemTypeData(itemTypeIndex).name}{MAINCOLOUR} drop scale to {ALTCOLOUR}${dropScale.x.toFixed(2)}, ${dropScale.y.toFixed(2)}, ${dropScale.z.toFixed(2)}`, true);
|
||||
messageAdmins(`{ALTCOLOUR}${getPlayerName(client)}{MAINCOLOUR} set item type {ALTCOLOUR}${getItemTypeData(itemTypeIndex).name}{MAINCOLOUR} drop scale to {ALTCOLOUR}${dropScale.x.toFixed(2)}, ${dropScale.y.toFixed(2)}, ${dropScale.z.toFixed(2)}`, true);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -1235,7 +1262,7 @@ function setItemTypeDemandMultiplierCommand(command, params, client) {
|
||||
|
||||
getItemTypeData(itemTypeIndex).demandMultiplier = demandMultiplier / 100;
|
||||
getItemTypeData(itemTypeIndex).needsSaved = true;
|
||||
messageAdmins(`{ALTCOLOUR}${getPlayerName(client)} set item type {ALTCOLOUR}${getItemTypeData(itemTypeIndex).name}{MAINCOLOUR} demand multiplier to {ALTCOLOUR}${demandMultiplier}%`, true);
|
||||
messageAdmins(`{ALTCOLOUR}${getPlayerName(client)}{MAINCOLOUR} set item type {ALTCOLOUR}${getItemTypeData(itemTypeIndex).name}{MAINCOLOUR} demand multiplier to {ALTCOLOUR}${demandMultiplier}%`, true);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -1271,7 +1298,7 @@ function setItemTypeMaxValueCommand(command, params, client) {
|
||||
|
||||
getItemTypeData(itemTypeIndex).maxValue = maxValue;
|
||||
getItemTypeData(itemTypeIndex).needsSaved = true;
|
||||
messageAdmins(`{ALTCOLOUR}${getPlayerName(client)} set item type {ALTCOLOUR}${getItemTypeData(itemTypeIndex).name}{MAINCOLOUR} max value to {ALTCOLOUR}${maxValue}`, true);
|
||||
messageAdmins(`{ALTCOLOUR}${getPlayerName(client)}{MAINCOLOUR} set item type {ALTCOLOUR}${getItemTypeData(itemTypeIndex).name}{MAINCOLOUR} max value to {ALTCOLOUR}${maxValue}`, true);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -1307,7 +1334,7 @@ function setItemTypeSizeCommand(command, params, client) {
|
||||
|
||||
getItemTypeData(itemTypeIndex).size = size;
|
||||
getItemTypeData(itemTypeIndex).needsSaved = true;
|
||||
messageAdmins(`{ALTCOLOUR}${getPlayerName(client)} set item type {ALTCOLOUR}${getItemTypeData(itemTypeIndex).name}{MAINCOLOUR} size to {ALTCOLOUR}${size}`, true);
|
||||
messageAdmins(`{ALTCOLOUR}${getPlayerName(client)}{MAINCOLOUR} set item type {ALTCOLOUR}${getItemTypeData(itemTypeIndex).name}{MAINCOLOUR} size to {ALTCOLOUR}${size}`, true);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -1343,7 +1370,7 @@ function setItemTypeCapacityCommand(command, params, client) {
|
||||
|
||||
getItemTypeData(itemTypeIndex).capacity = capacity;
|
||||
getItemTypeData(itemTypeIndex).needsSaved = true;
|
||||
messageAdmins(`{ALTCOLOUR}${getPlayerName(client)} set item type {ALTCOLOUR}${getItemTypeData(itemTypeIndex).name}{MAINCOLOUR} capacity to {ALTCOLOUR}${capacity}`, true);
|
||||
messageAdmins(`{ALTCOLOUR}${getPlayerName(client)}{MAINCOLOUR} set item type {ALTCOLOUR}${getItemTypeData(itemTypeIndex).name}{MAINCOLOUR} capacity to {ALTCOLOUR}${capacity}`, true);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -1518,13 +1545,13 @@ function playerUseItem(client, hotBarSlot) {
|
||||
|
||||
itemData.value = itemData.value - itemTypeData.useValue;
|
||||
if (itemData.value <= 0) {
|
||||
destroyItem(itemIndex);
|
||||
deleteItem(itemIndex);
|
||||
}
|
||||
|
||||
markPlayerActionTipSeen(client, "VehicleRepairItemUsage");
|
||||
} else {
|
||||
messagePlayerError(client, getLocaleString(client, "VehicleTooFar"));
|
||||
}
|
||||
|
||||
markPlayerActionTipSeen(client, "VehicleRepairItemUsage");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1583,7 +1610,7 @@ function playerUseItem(client, hotBarSlot) {
|
||||
|
||||
itemData.value = itemData.value - itemTypeData.useValue;
|
||||
//if(itemData.value <= 0) {
|
||||
// destroyItem(itemIndex);
|
||||
// deleteItem(itemIndex);
|
||||
//}
|
||||
}
|
||||
} else {
|
||||
@@ -1644,6 +1671,7 @@ function playerUseItem(client, hotBarSlot) {
|
||||
if (getPlayerData(client).incomingDamageMultiplier < 0.25) {
|
||||
getPlayerData(client).incomingDamageMultiplier = 0.25;
|
||||
}
|
||||
sendIncomingDamageMultiplierToClient(client, getPlayerData(client).incomingDamageMultiplier);
|
||||
deleteItem(itemIndex);
|
||||
switchPlayerActiveHotBarSlot(client, -1);
|
||||
break;
|
||||
@@ -1655,6 +1683,7 @@ function playerUseItem(client, hotBarSlot) {
|
||||
if (getPlayerData(client).incomingDamageMultiplier < 0.25) {
|
||||
getPlayerData(client).incomingDamageMultiplier = 0.25;
|
||||
}
|
||||
sendIncomingDamageMultiplierToClient(client, getPlayerData(client).incomingDamageMultiplier);
|
||||
deleteItem(itemIndex);
|
||||
switchPlayerActiveHotBarSlot(client, -1);
|
||||
break;
|
||||
@@ -1666,6 +1695,7 @@ function playerUseItem(client, hotBarSlot) {
|
||||
if (getPlayerData(client).incomingDamageMultiplier < 0.25) {
|
||||
getPlayerData(client).incomingDamageMultiplier = 0.25;
|
||||
}
|
||||
sendIncomingDamageMultiplierToClient(client, getPlayerData(client).incomingDamageMultiplier);
|
||||
deleteItem(itemIndex);
|
||||
switchPlayerActiveHotBarSlot(client, -1);
|
||||
break;
|
||||
@@ -1675,7 +1705,7 @@ function playerUseItem(client, hotBarSlot) {
|
||||
meActionToNearbyPlayers(client, `bends down and plants a ${itemTypeData.name} in the ground`);
|
||||
createGroundPlant(itemIndex);
|
||||
if (itemData.value == 0) {
|
||||
destroyItem(itemIndex);
|
||||
deleteItem(itemIndex);
|
||||
switchPlayerActiveHotBarSlot(client, -1);
|
||||
}
|
||||
break;
|
||||
@@ -1767,14 +1797,18 @@ function playerDropItem(client, hotBarSlot) {
|
||||
updatePlayerHotBar(client);
|
||||
clearPlayerWeapons(client);
|
||||
|
||||
let position = getPosInFrontOfPos(getPlayerPosition(client), getPlayerHeading(client), getItemTypeData(getItemData(itemId).itemTypeIndex).dropFrontDistance);
|
||||
|
||||
getItemData(itemId).ownerType = V_ITEM_OWNER_GROUND;
|
||||
getItemData(itemId).ownerId = 0;
|
||||
getItemData(itemId).position = getPosInFrontOfPos(getPlayerPosition(client), getPlayerHeading(client), getItemTypeData(getItemData(itemId).itemTypeIndex).dropFrontDistance);
|
||||
getItemData(itemId).position = position;
|
||||
getItemData(itemId).dimension = getPlayerDimension(client);
|
||||
//getItemData(itemId).interior = getPlayerInterior(client);
|
||||
spawnGroundItemObject(itemId);
|
||||
getItemData(itemId).needsSaved = true;
|
||||
getServerData().groundItemCache.push(itemId);
|
||||
|
||||
logItemMove(getItemData(itemId).databaseId, V_ITEM_OWNER_PLAYER, getPlayerCurrentSubAccount(client).databaseId, V_ITEM_OWNER_GROUND, 0, position);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1854,6 +1888,8 @@ function playerPickupItem(client, itemId) {
|
||||
|
||||
getPlayerData(client).hotBarItems[firstSlot] = itemId;
|
||||
updatePlayerHotBar(client);
|
||||
|
||||
logItemMove(getItemData(itemId).databaseId, V_ITEM_OWNER_GROUND, 0, V_ITEM_OWNER_PLAYER, getPlayerCurrentSubAccount(client).databaseId, position);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2378,6 +2414,8 @@ function listPlayerInventoryCommand(command, params, client) {
|
||||
//showPlayerInventoryToPlayer(client, targetClient);
|
||||
|
||||
showPlayerInventoryToPlayer(client, client);
|
||||
|
||||
markPlayerActionTipSeen(client, "ViewInventory");
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -3304,4 +3342,14 @@ function despawnAllGroundItemObjects() {
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function logItemMove(itemId, fromType, fromId, toType, toId, position = toVector3(0.0, 0.0, 0.0)) {
|
||||
if (getServerConfig().devServer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
quickDatabaseQuery(`INSERT INTO log_item_move (log_item_move_item, log_item_move_from_type, log_item_move_from_id, log_item_move_to_type, log_item_move_to_id, log_item_move_when, log_item_move_pos_x, log_item_move_pos_y, log_item_move_pos_z) VALUES (${itemId}, ${fromType}, ${fromId}, ${toType}, ${toId}, UNIX_TIMESTAMP(), ${position.x}, ${position.y}, ${position.z})`);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -44,13 +44,6 @@ const V_JOB_ROUTE_LOC_TYPE_FIRE = 5; // Scripted fire, placed on build
|
||||
|
||||
/**
|
||||
* @class Representing a job's data. Loaded and saved in the database
|
||||
* @property {Array.<JobEquipmentData>} equipment
|
||||
* @property {Array.<JobUniformData>} uniforms
|
||||
* @property {Array.<JobLocationData>} locations
|
||||
* @property {Array.<JobRouteData>} routes
|
||||
* @property {Array.<JobWhiteListData>} whiteList
|
||||
* @property {Array.<JobBlackListData>} blackList
|
||||
* @property {Array.<JobRankData>} ranks
|
||||
*/
|
||||
class JobData {
|
||||
constructor(dbAssoc = false) {
|
||||
@@ -70,12 +63,25 @@ class JobData {
|
||||
this.whoCreated = 0;
|
||||
this.whenCreated = 0;
|
||||
|
||||
/** @type {Array.<JobEquipmentData>} */
|
||||
this.equipment = [];
|
||||
|
||||
/** @type {Array.<JobUniformData>} */
|
||||
this.uniforms = [];
|
||||
|
||||
/** @type {Array.<JobLocationData>} */
|
||||
this.locations = [];
|
||||
|
||||
/** @type {Array.<JobWhiteListData>} */
|
||||
this.whiteList = [];
|
||||
|
||||
/** @type {Array.<JobBlackListData>} */
|
||||
this.blackList = [];
|
||||
|
||||
/** @type {Array.<JobRouteData>} */
|
||||
this.routes = [];
|
||||
|
||||
/** @type {Array.<JobRankData>} */
|
||||
this.ranks = [];
|
||||
|
||||
if (dbAssoc) {
|
||||
@@ -130,11 +136,13 @@ class JobRouteData {
|
||||
//this.failedMessage = "";
|
||||
this.locationArriveMessage = "";
|
||||
this.locationGotoMessage = "";
|
||||
this.locations = [];
|
||||
this.whoCreated = 0;
|
||||
this.whenCreated = 0;
|
||||
this.sphere = null;
|
||||
|
||||
/** @type {Array.<JobRouteLocationData>} */
|
||||
this.locations = [];
|
||||
|
||||
if (dbAssoc) {
|
||||
this.databaseId = toInteger(dbAssoc["job_route_id"]);
|
||||
this.name = toString(dbAssoc["job_route_name"]);
|
||||
@@ -213,10 +221,12 @@ class JobEquipmentData {
|
||||
this.index = -1;
|
||||
this.jobIndex = -1;
|
||||
this.needsSaved = false;
|
||||
this.items = [];
|
||||
this.whoCreated = 0;
|
||||
this.whenCreated = 0;
|
||||
|
||||
/** @type {Array.<JobEquipmentItemData>} */
|
||||
this.items = [];
|
||||
|
||||
if (dbAssoc) {
|
||||
this.databaseId = dbAssoc["job_equip_id"];
|
||||
this.job = dbAssoc["job_equip_job"];
|
||||
@@ -391,6 +401,7 @@ class JobRankData {
|
||||
this.whenCreated = 0;
|
||||
this.flags = 0;
|
||||
this.needsSaved = false;
|
||||
this.public = false;
|
||||
|
||||
if (dbAssoc) {
|
||||
this.databaseId = toInteger(dbAssoc["job_rank_id"]);
|
||||
@@ -402,6 +413,7 @@ class JobRankData {
|
||||
this.whoCreated = toInteger(dbAssoc["job_rank_who_added"]);
|
||||
this.whenCreated = toInteger(dbAssoc["job_rank_when_added"]);
|
||||
this.flags = toInteger(dbAssoc["job_rank_flags"]);
|
||||
this.public = intToBool(dbAssoc["job_rank_public"]);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -458,7 +470,7 @@ class JobBlackListData {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
class JobRouteLocationType {
|
||||
class JobRouteLocationTypeData {
|
||||
constructor(jobRouteLocationTypeId, name, animStart = "", animStop = "", inVehicle = false, nearVehicle = false, nearVehicleDistance = 5.0) {
|
||||
|
||||
}
|
||||
@@ -469,59 +481,59 @@ class JobRouteLocationType {
|
||||
// For use with the /jobrouteloctype command
|
||||
let jobRouteLocationTypes = {
|
||||
[V_GAME_GTA_III]: [
|
||||
new JobRouteLocationType(V_JOB_ROUTE_LOC_TYPE_CHECKPOINT, "Checkpoint"),
|
||||
new JobRouteLocationType(V_JOB_ROUTE_LOC_TYPE_GROUND_GARBAGE, "GroundGarbage"),
|
||||
new JobRouteLocationType(V_JOB_ROUTE_LOC_TYPE_GARBAGE_BIN, "GarbagePickup"),
|
||||
new JobRouteLocationType(V_JOB_ROUTE_LOC_TYPE_BURNING_VEHICLE, "BurningVehicle"),
|
||||
new JobRouteLocationType(V_JOB_ROUTE_LOC_TYPE_INJURED_PED, "InjuredPed"),
|
||||
new JobRouteLocationTypeData(V_JOB_ROUTE_LOC_TYPE_CHECKPOINT, "Checkpoint"),
|
||||
new JobRouteLocationTypeData(V_JOB_ROUTE_LOC_TYPE_GROUND_GARBAGE, "GroundGarbage"),
|
||||
new JobRouteLocationTypeData(V_JOB_ROUTE_LOC_TYPE_GARBAGE_BIN, "GarbagePickup"),
|
||||
new JobRouteLocationTypeData(V_JOB_ROUTE_LOC_TYPE_BURNING_VEHICLE, "BurningVehicle"),
|
||||
new JobRouteLocationTypeData(V_JOB_ROUTE_LOC_TYPE_INJURED_PED, "InjuredPed"),
|
||||
],
|
||||
|
||||
[V_GAME_GTA_VC]: [
|
||||
new JobRouteLocationType(V_JOB_ROUTE_LOC_TYPE_CHECKPOINT, "Checkpoint"),
|
||||
new JobRouteLocationType(V_JOB_ROUTE_LOC_TYPE_GROUND_GARBAGE, "GroundGarbage"),
|
||||
new JobRouteLocationType(V_JOB_ROUTE_LOC_TYPE_GARBAGE_BIN, "GarbagePickup"),
|
||||
new JobRouteLocationType(V_JOB_ROUTE_LOC_TYPE_BURNING_VEHICLE, "BurningVehicle"),
|
||||
new JobRouteLocationType(V_JOB_ROUTE_LOC_TYPE_INJURED_PED, "InjuredPed"),
|
||||
new JobRouteLocationTypeData(V_JOB_ROUTE_LOC_TYPE_CHECKPOINT, "Checkpoint"),
|
||||
new JobRouteLocationTypeData(V_JOB_ROUTE_LOC_TYPE_GROUND_GARBAGE, "GroundGarbage"),
|
||||
new JobRouteLocationTypeData(V_JOB_ROUTE_LOC_TYPE_GARBAGE_BIN, "GarbagePickup"),
|
||||
new JobRouteLocationTypeData(V_JOB_ROUTE_LOC_TYPE_BURNING_VEHICLE, "BurningVehicle"),
|
||||
new JobRouteLocationTypeData(V_JOB_ROUTE_LOC_TYPE_INJURED_PED, "InjuredPed"),
|
||||
],
|
||||
|
||||
[V_GAME_GTA_SA]: [
|
||||
new JobRouteLocationType(V_JOB_ROUTE_LOC_TYPE_CHECKPOINT, "Checkpoint"),
|
||||
new JobRouteLocationType(V_JOB_ROUTE_LOC_TYPE_GROUND_GARBAGE, "GroundGarbage"),
|
||||
new JobRouteLocationType(V_JOB_ROUTE_LOC_TYPE_GARBAGE_BIN, "GarbagePickup"),
|
||||
new JobRouteLocationType(V_JOB_ROUTE_LOC_TYPE_BURNING_VEHICLE, "BurningVehicle"),
|
||||
new JobRouteLocationType(V_JOB_ROUTE_LOC_TYPE_INJURED_PED, "InjuredPed"),
|
||||
new JobRouteLocationTypeData(V_JOB_ROUTE_LOC_TYPE_CHECKPOINT, "Checkpoint"),
|
||||
new JobRouteLocationTypeData(V_JOB_ROUTE_LOC_TYPE_GROUND_GARBAGE, "GroundGarbage"),
|
||||
new JobRouteLocationTypeData(V_JOB_ROUTE_LOC_TYPE_GARBAGE_BIN, "GarbagePickup"),
|
||||
new JobRouteLocationTypeData(V_JOB_ROUTE_LOC_TYPE_BURNING_VEHICLE, "BurningVehicle"),
|
||||
new JobRouteLocationTypeData(V_JOB_ROUTE_LOC_TYPE_INJURED_PED, "InjuredPed"),
|
||||
],
|
||||
|
||||
[V_GAME_GTA_IV]: [
|
||||
new JobRouteLocationType(V_JOB_ROUTE_LOC_TYPE_CHECKPOINT, "Checkpoint"),
|
||||
new JobRouteLocationType(V_JOB_ROUTE_LOC_TYPE_GROUND_GARBAGE, "GroundGarbage"),
|
||||
new JobRouteLocationType(V_JOB_ROUTE_LOC_TYPE_GARBAGE_BIN, "GarbagePickup"),
|
||||
new JobRouteLocationType(V_JOB_ROUTE_LOC_TYPE_BURNING_VEHICLE, "BurningVehicle"),
|
||||
new JobRouteLocationType(V_JOB_ROUTE_LOC_TYPE_INJURED_PED, "InjuredPed"),
|
||||
new JobRouteLocationTypeData(V_JOB_ROUTE_LOC_TYPE_CHECKPOINT, "Checkpoint"),
|
||||
new JobRouteLocationTypeData(V_JOB_ROUTE_LOC_TYPE_GROUND_GARBAGE, "GroundGarbage"),
|
||||
new JobRouteLocationTypeData(V_JOB_ROUTE_LOC_TYPE_GARBAGE_BIN, "GarbagePickup"),
|
||||
new JobRouteLocationTypeData(V_JOB_ROUTE_LOC_TYPE_BURNING_VEHICLE, "BurningVehicle"),
|
||||
new JobRouteLocationTypeData(V_JOB_ROUTE_LOC_TYPE_INJURED_PED, "InjuredPed"),
|
||||
],
|
||||
|
||||
[V_GAME_MAFIA_ONE]: [
|
||||
new JobRouteLocationType(V_JOB_ROUTE_LOC_TYPE_CHECKPOINT, "Checkpoint"),
|
||||
new JobRouteLocationType(V_JOB_ROUTE_LOC_TYPE_GROUND_GARBAGE, "GroundGarbage"),
|
||||
new JobRouteLocationType(V_JOB_ROUTE_LOC_TYPE_GARBAGE_BIN, "GarbagePickup"),
|
||||
new JobRouteLocationType(V_JOB_ROUTE_LOC_TYPE_BURNING_VEHICLE, "BurningVehicle"),
|
||||
new JobRouteLocationType(V_JOB_ROUTE_LOC_TYPE_INJURED_PED, "InjuredPed"),
|
||||
new JobRouteLocationTypeData(V_JOB_ROUTE_LOC_TYPE_CHECKPOINT, "Checkpoint"),
|
||||
new JobRouteLocationTypeData(V_JOB_ROUTE_LOC_TYPE_GROUND_GARBAGE, "GroundGarbage"),
|
||||
new JobRouteLocationTypeData(V_JOB_ROUTE_LOC_TYPE_GARBAGE_BIN, "GarbagePickup"),
|
||||
new JobRouteLocationTypeData(V_JOB_ROUTE_LOC_TYPE_BURNING_VEHICLE, "BurningVehicle"),
|
||||
new JobRouteLocationTypeData(V_JOB_ROUTE_LOC_TYPE_INJURED_PED, "InjuredPed"),
|
||||
],
|
||||
|
||||
[V_GAME_MAFIA_TWO]: [
|
||||
new JobRouteLocationType(V_JOB_ROUTE_LOC_TYPE_CHECKPOINT, "Checkpoint"),
|
||||
new JobRouteLocationType(V_JOB_ROUTE_LOC_TYPE_GROUND_GARBAGE, "GroundGarbage"),
|
||||
new JobRouteLocationType(V_JOB_ROUTE_LOC_TYPE_GARBAGE_BIN, "GarbagePickup"),
|
||||
new JobRouteLocationType(V_JOB_ROUTE_LOC_TYPE_BURNING_VEHICLE, "BurningVehicle"),
|
||||
new JobRouteLocationType(V_JOB_ROUTE_LOC_TYPE_INJURED_PED, "InjuredPed"),
|
||||
new JobRouteLocationTypeData(V_JOB_ROUTE_LOC_TYPE_CHECKPOINT, "Checkpoint"),
|
||||
new JobRouteLocationTypeData(V_JOB_ROUTE_LOC_TYPE_GROUND_GARBAGE, "GroundGarbage"),
|
||||
new JobRouteLocationTypeData(V_JOB_ROUTE_LOC_TYPE_GARBAGE_BIN, "GarbagePickup"),
|
||||
new JobRouteLocationTypeData(V_JOB_ROUTE_LOC_TYPE_BURNING_VEHICLE, "BurningVehicle"),
|
||||
new JobRouteLocationTypeData(V_JOB_ROUTE_LOC_TYPE_INJURED_PED, "InjuredPed"),
|
||||
],
|
||||
|
||||
[V_GAME_MAFIA_ONE_DE]: [
|
||||
new JobRouteLocationType(V_JOB_ROUTE_LOC_TYPE_CHECKPOINT, "Checkpoint"),
|
||||
new JobRouteLocationType(V_JOB_ROUTE_LOC_TYPE_GROUND_GARBAGE, "GroundGarbage"),
|
||||
new JobRouteLocationType(V_JOB_ROUTE_LOC_TYPE_GARBAGE_BIN, "GarbagePickup"),
|
||||
new JobRouteLocationType(V_JOB_ROUTE_LOC_TYPE_BURNING_VEHICLE, "BurningVehicle"),
|
||||
new JobRouteLocationType(V_JOB_ROUTE_LOC_TYPE_INJURED_PED, "InjuredPed"),
|
||||
new JobRouteLocationTypeData(V_JOB_ROUTE_LOC_TYPE_CHECKPOINT, "Checkpoint"),
|
||||
new JobRouteLocationTypeData(V_JOB_ROUTE_LOC_TYPE_GROUND_GARBAGE, "GroundGarbage"),
|
||||
new JobRouteLocationTypeData(V_JOB_ROUTE_LOC_TYPE_GARBAGE_BIN, "GarbagePickup"),
|
||||
new JobRouteLocationTypeData(V_JOB_ROUTE_LOC_TYPE_BURNING_VEHICLE, "BurningVehicle"),
|
||||
new JobRouteLocationTypeData(V_JOB_ROUTE_LOC_TYPE_INJURED_PED, "InjuredPed"),
|
||||
],
|
||||
}
|
||||
|
||||
@@ -1184,7 +1196,7 @@ function stopWorking(client) {
|
||||
setPlayerSkin(client, getPlayerCurrentSubAccount(client).skin);
|
||||
deleteJobItems(client);
|
||||
restorePlayerTempLockerItems(client);
|
||||
respawnJobVehicle(client);
|
||||
//respawnJobVehicle(client);
|
||||
sendPlayerStopJobRoute(client);
|
||||
|
||||
let jobId = getPlayerJob(client);
|
||||
@@ -1303,7 +1315,7 @@ function jobUniformCommand(command, params, client) {
|
||||
let uniformList = jobData.uniforms.map(function (x) { return `{MAINCOLOUR}${toInteger(x.index) + 1}: {ALTCOLOUR}${x.name}` });
|
||||
let chunkedList = splitArrayIntoChunks(uniformList, 4);
|
||||
|
||||
messagePlayerNormal(client, makeChatBoxSectionHeader(getLocaleString(client, "HeaderJobUniformList")));
|
||||
messagePlayerNormal(client, makeChatBoxSectionHeader(getLocaleString(client, "HeaderJobUniformList", jobData.name)));
|
||||
for (let i in chunkedList) {
|
||||
messagePlayerInfo(client, chunkedList[i].join(", "));
|
||||
}
|
||||
@@ -1523,7 +1535,7 @@ function quitJob(client) {
|
||||
getPlayerCurrentSubAccount(client).jobRank = 0;
|
||||
getPlayerCurrentSubAccount(client).jobIndex = -1;
|
||||
getPlayerCurrentSubAccount(client).jobRankIndex = -1;
|
||||
sendPlayerJobType(client, 0);
|
||||
sendPlayerJobType(client, -1);
|
||||
updateJobBlipsForPlayer(client);
|
||||
}
|
||||
|
||||
@@ -1540,7 +1552,7 @@ function takeJob(client, jobId) {
|
||||
getPlayerCurrentSubAccount(client).jobRank = rankId;
|
||||
getPlayerCurrentSubAccount(client).jobIndex = jobId;
|
||||
getPlayerCurrentSubAccount(client).jobRankIndex = rankIndex;
|
||||
sendPlayerJobType(client, getJobData(jobId).databaseId);
|
||||
sendPlayerJobType(client, jobId);
|
||||
updateJobBlipsForPlayer(client);
|
||||
}
|
||||
|
||||
@@ -1553,11 +1565,11 @@ function reloadAllJobsCommand(command, params, client) {
|
||||
deleteAllJobPickups();
|
||||
clearArray(getServerData().jobs);
|
||||
|
||||
Promise.resolve().then(() => {
|
||||
getServerData().jobs = loadJobsFromDatabase();
|
||||
spawnAllJobPickups();
|
||||
spawnAllJobBlips();
|
||||
});
|
||||
//Promise.resolve().then(() => {
|
||||
getServerData().jobs = loadJobsFromDatabase();
|
||||
spawnAllJobPickups();
|
||||
spawnAllJobBlips();
|
||||
//});
|
||||
|
||||
announceAdminAction("AllJobsReloaded");
|
||||
}
|
||||
@@ -1618,7 +1630,7 @@ function createJobLocationCommand(command, params, client) {
|
||||
function deleteJobLocationCommand(command, params, client) {
|
||||
let closestJobLocation = getClosestJobLocation(getPlayerPosition(client), getPlayerDimension(client));
|
||||
|
||||
deleteJobLocation(closestJobLocation.jobIndex, closestJobLocation.index);
|
||||
deleteJobLocation(closestJobLocation.jobIndex, closestJobLocation.index, getPlayerData(client).accountData.databaseId);
|
||||
messageAdmins(`{adminOrange}${getPlayerName(client)}{MAINCOLOUR} deleted location {ALTCOLOUR}${closestJobLocation.index} (DB ID ${closestJobLocation.databaseId}){MAINCOLOUR} for the {jobYellow}${getJobData(closestJobLocation.jobIndex).name}{MAINCOLOUR} job`);
|
||||
}
|
||||
|
||||
@@ -1787,6 +1799,46 @@ function setJobPickupCommand(command, params, client) {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function setPlayerJobRankCommand(command, params, client) {
|
||||
if (areParamsEmpty(params)) {
|
||||
messagePlayerSyntax(client, getCommandSyntaxText(command));
|
||||
return false;
|
||||
}
|
||||
|
||||
let jobIndex = getPlayerJob(client);
|
||||
|
||||
if (getJobData(jobIndex) == false) {
|
||||
messagePlayerError(client, getLocaleString(client, "InvalidJob"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!doesPlayerHaveJobPermission(client, getJobFlagValue("SetRank"))) {
|
||||
messagePlayerError(client, getLocaleString(client, "JobRankTooLow"));
|
||||
return false;
|
||||
}
|
||||
|
||||
let targetClient = getPlayerFromParams(getParam(params, " ", 1));
|
||||
let rankIndex = getJobRankFromParams(jobIndex, params.split(" ").slice(2).join(" "));
|
||||
|
||||
if (!targetClient) {
|
||||
messagePlayerError(client, getLocaleString(client, "InvalidPlayer"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rankIndex == -1) {
|
||||
messagePlayerError(client, getLocaleString(client, "InvalidJobRank"));
|
||||
return false;
|
||||
}
|
||||
|
||||
getPlayerCurrentSubAccount(targetClient).jobRankIndex = rankIndex;
|
||||
getPlayerCurrentSubAccount(targetClient).jobRank = getJobRankData(jobIndex, rankIndex).databaseId;
|
||||
|
||||
messagePlayerSuccess(client, `You set {ALTCOLOUR}${getCharacterFullName(targetClient)}'s{MAINCOLOUR} job rank to {ALTCOLOUR}${getJobRankData(jobIndex, rankIndex).name} (level ${getJobRankData(jobIndex, rankIndex).level}){MAINCOLOUR}`);
|
||||
messagePlayerAlert(client, `{ALTCOLOUR}${getCharacterFullName(client)}{MAINCOLOUR} set your job rank to {ALTCOLOUR}${getJobRankData(jobIndex, rankIndex).name} (level ${getJobRankData(jobIndex, rankIndex).level}){MAINCOLOUR}`);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function toggleJobRouteEnabledCommand(command, params, client) {
|
||||
let jobId = getPlayerJob(client);
|
||||
let jobRoute = getPlayerJobRoute(client);
|
||||
@@ -2187,7 +2239,7 @@ function setJobRoutePayCommand(command, params, client) {
|
||||
let amount = getParam(params, " ", 1);
|
||||
|
||||
if (isNaN(amount)) {
|
||||
getLocaleString(client, "MustBeNumber", "amount");
|
||||
getLocaleString(client, "MustBeNumber");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2480,8 +2532,10 @@ function startJobRoute(client, forceRoute = -1) {
|
||||
getPlayerData(client).jobRouteLocation = 0;
|
||||
getPlayerData(client).jobRouteVehicle = getPlayerVehicle(client);
|
||||
|
||||
getPlayerVehicle(client).colour1 = getJobRouteData(jobId, jobRoute).vehicleColour1;
|
||||
getPlayerVehicle(client).colour2 = getJobRouteData(jobId, jobRoute).vehicleColour2;
|
||||
if (isGameFeatureSupported("vehicleColour")) {
|
||||
getPlayerVehicle(client).colour1 = getJobRouteData(jobId, jobRoute).vehicleColour1;
|
||||
getPlayerVehicle(client).colour2 = getJobRouteData(jobId, jobRoute).vehicleColour2;
|
||||
}
|
||||
|
||||
messagePlayerNormal(client, replaceJobRouteStringsInMessage(getJobRouteData(jobId, jobRoute).startMessage, jobId, jobRoute));
|
||||
|
||||
@@ -2528,7 +2582,7 @@ function stopJobRoute(client, successful = false, alertPlayer = true) {
|
||||
|
||||
stopReturnToJobVehicleCountdown(client);
|
||||
sendPlayerStopJobRoute(client);
|
||||
respawnVehicle(getPlayerData(client).jobRouteVehicle);
|
||||
//respawnVehicle(getPlayerData(client).jobRouteVehicle);
|
||||
|
||||
getPlayerData(client).jobRouteVehicle = false;
|
||||
getPlayerData(client).jobRoute = -1;
|
||||
@@ -2558,6 +2612,7 @@ function getPlayerJobRouteVehicle(client) {
|
||||
// ===========================================================================
|
||||
|
||||
function startReturnToJobVehicleCountdown(client) {
|
||||
/*
|
||||
getPlayerData(client).returnToJobVehicleTick = getGlobalConfig().returnToJobVehicleTime;
|
||||
getPlayerData(client).returnToJobVehicleTimer = setInterval(function () {
|
||||
//logToConsole(LOG_DEBUG, getPlayerData(client).returnToJobVehicleTick);
|
||||
@@ -2572,6 +2627,7 @@ function startReturnToJobVehicleCountdown(client) {
|
||||
stopJobRoute(client, false, true);
|
||||
}
|
||||
}, 1000);
|
||||
*/
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -2608,14 +2664,20 @@ function canPlayerUseJob(client, jobId) {
|
||||
}
|
||||
}
|
||||
|
||||
// Check if lowest rank is public rank
|
||||
let lowestRank = getLowestJobRank(jobId);
|
||||
if (getJobRankData(jobId, lowestRank).public == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function deleteJobLocation(jobIndex, jobLocationIndex) {
|
||||
function deleteJobLocation(jobIndex, jobLocationIndex, whoDeleted = defaultNoAccountId) {
|
||||
if (jobLocationData.databaseId > 0) {
|
||||
quickDatabaseQuery(`DELETE FROM job_loc WHERE job_loc_id = ${getJobLocationData(jobIndex, jobLocationIndex).databaseId}`);
|
||||
quickDatabaseQuery(`UPDATE job_loc SET job_loc_deleted = 1, job_loc_who_deleted = ${whoDeleted}, job_loc_when_deleted = UNIX_TIMESTAMP() WHERE job_loc_id = ${getJobLocationData(jobIndex, jobLocationIndex).databaseId}`);
|
||||
}
|
||||
|
||||
deleteJobLocationBlip(jobIndex, jobLocationIndex);
|
||||
@@ -2688,8 +2750,8 @@ function setAllJobDataIndexes() {
|
||||
}
|
||||
|
||||
for (let v in getServerData().jobs[i].whiteList) {
|
||||
getServerData().jobs[i].blackList[v].index = v;
|
||||
getServerData().jobs[i].blackList[v].jobIndex = i;
|
||||
getServerData().jobs[i].whiteList[v].index = v;
|
||||
getServerData().jobs[i].whiteList[v].jobIndex = i;
|
||||
}
|
||||
|
||||
for (let t in getServerData().jobs[i].routes) {
|
||||
@@ -2803,6 +2865,7 @@ function saveJobRankToDatabase(jobRankData) {
|
||||
["job_rank_level", jobRankData.level],
|
||||
["job_rank_who_added", jobRankData.whoCreated],
|
||||
["job_rank_when_added", jobRankData.whenCreated],
|
||||
["job_rank_public", boolToInt(jobRankData.public)],
|
||||
];
|
||||
|
||||
let dbQuery = null;
|
||||
@@ -2827,6 +2890,13 @@ function saveJobRankToDatabase(jobRankData) {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
/**
|
||||
* Saves a job route to database
|
||||
*
|
||||
* @param {JobRouteData} jobRouteData - The data of the job route
|
||||
* @return {boolean} Whether the data saved (true) or not (false)
|
||||
*
|
||||
*/
|
||||
function saveJobRouteToDatabase(jobRouteData) {
|
||||
if (!jobRouteData) {
|
||||
// Invalid job route data
|
||||
@@ -2886,6 +2956,13 @@ function saveJobRouteToDatabase(jobRouteData) {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
/**
|
||||
* Saves a job route location to database
|
||||
*
|
||||
* @param {JobRouteLocationData} jobRouteLocationData - The data of the job route location
|
||||
* @return {boolean} Whether the data saved (true) or not (false)
|
||||
*
|
||||
*/
|
||||
function saveJobRouteLocationToDatabase(jobRouteLocationData) {
|
||||
if (!jobRouteLocationData) {
|
||||
// Invalid job route position data
|
||||
@@ -2893,7 +2970,7 @@ function saveJobRouteLocationToDatabase(jobRouteLocationData) {
|
||||
}
|
||||
|
||||
if (jobRouteLocationData.needsSaved == false) {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Job]: Job route location ${jobRouteLocationData.name} (DB ID ${jobRouteLocationData.databaseId}) doesn't need saved. Skipping ...`);
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Job]: Job route location ${jobRouteLocationData.name} (DB ID ${jobRouteLocationData.index}) doesn't need saved. Skipping ...`);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2929,13 +3006,20 @@ function saveJobRouteLocationToDatabase(jobRouteLocationData) {
|
||||
disconnectFromDatabase(dbConnection);
|
||||
return true;
|
||||
}
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Job]: Saved job route location ${jobRoutePositionData.name} (${jobRouteLocationData.databaseId}) to database!`);
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Job]: Saved job route location ${jobRouteLocationData.name} (${jobRouteLocationData.index}) to database!`);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
/**
|
||||
* Saves a job location to database
|
||||
*
|
||||
* @param {JobLocationData} jobLocationData - The data of the job location
|
||||
* @return {boolean} Whether the data saved (true) or not (false)
|
||||
*
|
||||
*/
|
||||
function saveJobLocationToDatabase(jobLocationData) {
|
||||
if (jobLocationData == null) {
|
||||
// Invalid job location data
|
||||
@@ -2985,18 +3069,26 @@ function saveJobLocationToDatabase(jobLocationData) {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
/**
|
||||
* Saves a job equipment to database
|
||||
*
|
||||
* @param {JobEquipmentData} jobEquipmentData - The data of the job equipment
|
||||
* @return {boolean} Whether the data saved (true) or not (false)
|
||||
*
|
||||
*/
|
||||
function saveJobEquipmentToDatabase(jobEquipmentData) {
|
||||
if (jobEquipmentData == null) {
|
||||
// Invalid job equipment data
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Job]: Job equipment ${jobEquipmentData.index} is invalid. Skipping ...`);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!jobEquipmentData.needsSaved) {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Job]: Job equipment ${jobEquipmentData.name} (${jobEquipmentData.databaseId}) doesn't need saved. Skipping ...`);
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Job]: Job equipment ${jobEquipmentData.name} (${jobEquipmentData.index}) doesn't need saved. Skipping ...`);
|
||||
return false;
|
||||
}
|
||||
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Job]: Saving job equipment ${jobEquipmentData.databaseId} to database ...`);
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Job]: Saving job equipment ${jobEquipmentData.index} to database ...`);
|
||||
let dbConnection = connectToDatabase();
|
||||
if (dbConnection) {
|
||||
let safeName = escapeDatabaseString(dbConnection, jobEquipmentData.name);
|
||||
@@ -3024,25 +3116,33 @@ function saveJobEquipmentToDatabase(jobEquipmentData) {
|
||||
disconnectFromDatabase(dbConnection);
|
||||
return true;
|
||||
}
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Job]: Saved job equipment ${jobEquipmentData.databaseId} to database`);
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Job]: Saved job equipment ${jobEquipmentData.index} to database`);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
/**
|
||||
* Saves a job equipment item to database
|
||||
*
|
||||
* @param {JobEquipmentItemData} jobEquipmentItemData - The data of the job equipment item
|
||||
* @return {boolean} Whether the data saved (true) or not (false)
|
||||
*
|
||||
*/
|
||||
function saveJobEquipmentItemToDatabase(jobEquipmentItemData) {
|
||||
if (jobEquipmentItemData == null) {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Job]: Job equipment item ${jobEquipmentItemData.index} is invalid. Skipping ...`);
|
||||
// Invalid job equipment weapon data
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!jobEquipmentItemData.needsSaved) {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Job]: Job equipment item ${jobEquipmentItemData.databaseId} doesn't need saved. Skipping ...`);
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Job]: Job equipment item ${jobEquipmentItemData.index} doesn't need saved. Skipping ...`);
|
||||
return false;
|
||||
}
|
||||
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Job]: Saving job equipment weapon ${jobEquipmentItemData.databaseId} to database ...`);
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Job]: Saving job equipment weapon ${jobEquipmentItemData.index} to database ...`);
|
||||
let dbConnection = connectToDatabase();
|
||||
if (dbConnection) {
|
||||
let data = [
|
||||
@@ -3069,25 +3169,32 @@ function saveJobEquipmentItemToDatabase(jobEquipmentItemData) {
|
||||
disconnectFromDatabase(dbConnection);
|
||||
return true;
|
||||
}
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Job]: Saved job equipment weapon ${jobEquipmentItemData.databaseId} to database`);
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Job]: Saved job equipment weapon ${jobEquipmentItemData.index} to database`);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
/**
|
||||
* Saves a job uniform to database
|
||||
*
|
||||
* @param {JobUniformData} jobUniformData - The data of the job uniform
|
||||
* @return {boolean} Whether the data saved (true) or not (false)
|
||||
*
|
||||
*/
|
||||
function saveJobUniformToDatabase(jobUniformData) {
|
||||
if (jobUniformData == null) {
|
||||
// Invalid job uniform data
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Job]: Job uniform ${jobUniformData.index} is invalid. Skipping ...`);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!jobUniformData.needSaved) {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Job]: Job uniform ${jobUniformData.databaseId} doesn't need saved. Skipping ...`);
|
||||
if (jobUniformData.needSaved == false) {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Job]: Job uniform ${jobUniformData.index} doesn't need saved. Skipping ...`);
|
||||
return false;
|
||||
}
|
||||
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Job]: Saving job uniform ${jobUniformData.databaseId} to database ...`);
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Job]: Saving job uniform ${jobUniformData.index} to database ...`);
|
||||
let dbConnection = connectToDatabase();
|
||||
if (dbConnection) {
|
||||
let safeName = escapeDatabaseString(dbConnection, jobUniformData.name);
|
||||
@@ -3116,7 +3223,7 @@ function saveJobUniformToDatabase(jobUniformData) {
|
||||
disconnectFromDatabase(dbConnection);
|
||||
return true;
|
||||
}
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Job]: Saved job uniform ${jobUniformData.databaseId} to database`);
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Job]: Saved job uniform ${jobUniformData.index} to database`);
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -3580,7 +3687,7 @@ function createJobUniformCommand(command, params, client) {
|
||||
}
|
||||
|
||||
createJobUniform(jobId, skinIndex);
|
||||
messageAdmins(`{adminOrange}${getPlayerName(client)}{MAINCOLOUR} created uniform with skin {ALTCOLOUR}${getSkinNameFromIndex(skinIndex)} (${getGameConfig().skins[skinIndex][0]}){MAINCOLOUR} for job {jobYellow}${getJobData(jobId).name}`);
|
||||
messageAdmins(`{adminOrange}${getPlayerName(client)}{MAINCOLOUR} created uniform with skin {ALTCOLOUR}${getSkinNameFromIndex(skinIndex)} (${getGameConfig().skins[getGame()][skinIndex][0]}){MAINCOLOUR} for job {jobYellow}${getJobData(jobId).name}`);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3638,10 +3745,12 @@ function createJobUniform(jobId, skinIndex) {
|
||||
let tempJobUniformData = new JobUniformData(false);
|
||||
tempJobUniformData.skin = skinIndex;
|
||||
tempJobUniformData.jobIndex = jobId;
|
||||
tempJobUniformData.job = getJobData(jobId);
|
||||
tempJobUniformData.job = getJobData(jobId).databaseId;
|
||||
tempJobUniformData.name = getGameConfig().skins[getGame()][skinIndex][1];
|
||||
tempJobUniformData.needsSaved = true;
|
||||
|
||||
getJobData(jobId).uniforms.push(tempJobUniformData);
|
||||
|
||||
setAllJobDataIndexes();
|
||||
}
|
||||
|
||||
@@ -3653,7 +3762,7 @@ function deleteJobRouteLocationCommand(command, params, client) {
|
||||
messageAdmins(`{adminOrange}${getPlayerName(client)}{MAINCOLOUR} deleted route location {ALTCOLOUR}${closestJobRouteLocation.index} (DB ID ${closestJobRouteLocation.databaseId}){MAINCOLOUR} for the {ALTCOLOUR}${closestJobRouteLocation.name}{jobYellow} route of the {jobYellow}${getJobData(closestJobLocation.jobIndex).name}{MAINCOLOUR} job`);
|
||||
|
||||
if (closestJobRouteLocation.databaseId > 0) {
|
||||
quickDatabaseQuery(`DELETE FROM job_route_loc WHERE job_route_loc_id = ${closestJobRouteLocation.databaseId}`);
|
||||
quickDatabaseQuery(`UPDATE job_route_loc SET job_route_loc_deleted = 1, job_route_loc_who_deleted = ${getPlayerData(client).accountData.databaseId}, job_route_loc_when_deleted = UNIX_TIMESTAMP() WHERE job_route_loc_id = ${closestJobRouteLocation.databaseId}`);
|
||||
}
|
||||
|
||||
let tempIndex = closestJobRouteLocation.index;
|
||||
@@ -3691,8 +3800,8 @@ function deleteJobRouteCommand(command, params, client) {
|
||||
messageAdmins(`{adminOrange}${getPlayerName(client)}{MAINCOLOUR} deleted route {ALTCOLOUR}${jobRouteData.name} (DB ID ${jobRouteData.databaseId}){MAINCOLOUR} for the {jobYellow}${getJobData(jobId).name}{MAINCOLOUR} job`);
|
||||
|
||||
if (jobRouteData.databaseId > 0) {
|
||||
quickDatabaseQuery(`DELETE FROM job_route WHERE job_route_id = ${jobRouteData.databaseId}`);
|
||||
quickDatabaseQuery(`DELETE FROM job_route_loc WHERE job_route_loc_route = ${jobRouteData.databaseId}`);
|
||||
quickDatabaseQuery(`UPDATE job_route SET job_route_deleted = 1, job_route_who_deleted = ${getPlayerData(client).accountData.databaseId}, job_route_when_deleted = UNIX_TIMESTAMP() WHERE job_route_id = ${jobRouteData.databaseId}`);
|
||||
quickDatabaseQuery(`UPDATE job_route_loc SET job_route_loc_deleted = 1, job_route_loc_who_deleted = ${getPlayerData(client).accountData.databaseId}, job_route_loc_when_deleted = UNIX_TIMESTAMP() WHERE job_route_loc_route = ${jobRouteData.databaseId}`);
|
||||
}
|
||||
|
||||
clearArray(getServerData().jobs[jobId].routes[jobRoute].locations);
|
||||
@@ -3714,7 +3823,7 @@ function deleteJobUniformCommand(command, params, client) {
|
||||
}
|
||||
|
||||
if (isNaN(uniformIndex)) {
|
||||
messagePlayerError(client, getLocaleString(client, "MustBeNumber", "uniform ID"));
|
||||
messagePlayerError(client, getLocaleString(client, "MustBeNumber"));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -3723,7 +3832,7 @@ function deleteJobUniformCommand(command, params, client) {
|
||||
return false;
|
||||
}
|
||||
|
||||
quickDatabaseQuery(`DELETE FROM job_uniform WHERE job_uniform_id = ${getJobData(jobId).uniforms[uniformIndex].databaseId}`);
|
||||
quickDatabaseQuery(`UPDATE job_uniform SET job_uniform_deleted = 1, job_uniform_who_deleted = ${getPlayerData(client).accountData.databaseId}, job_uniform_when_deleted = UNIX_TIMESTAMP() WHERE job_uniform_id = ${getJobData(jobId).uniforms[uniformIndex].databaseId}`);
|
||||
getJobData(jobId).uniforms.splice(uniformIndex, 1);
|
||||
|
||||
setAllJobDataIndexes();
|
||||
@@ -3893,7 +4002,7 @@ function getJobEquipmentItemData(jobIndex, equipmentIndex, equipmentItemIndex) {
|
||||
/**
|
||||
* @param {number} jobIndex - The data index of the job
|
||||
* @param {number} rankIndex - The data index of the job rank
|
||||
* @return {JobRouteData} The job rank's data (class instance)
|
||||
* @return {JobRankData} The job rank's data (class instance)
|
||||
*/
|
||||
function getJobRankData(jobIndex, rankIndex) {
|
||||
if (typeof getServerData().jobs[jobIndex] == "undefined") {
|
||||
@@ -4010,7 +4119,7 @@ function finishSuccessfulJobRoute(client) {
|
||||
|
||||
stopReturnToJobVehicleCountdown(client);
|
||||
sendPlayerStopJobRoute(client);
|
||||
respawnVehicle(getPlayerData(client).jobRouteVehicle);
|
||||
//respawnVehicle(getPlayerData(client).jobRouteVehicle);
|
||||
|
||||
getPlayerData(client).jobRouteVehicle = false;
|
||||
getPlayerData(client).jobRoute = -1;
|
||||
@@ -4179,4 +4288,178 @@ function doesJobLocationHaveAnyRoutes(jobLocationData) {
|
||||
return (getRandomJobRouteForLocation(jobLocationData) != -1);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
/**
|
||||
* @param {Number} jobIndex - The job index to search ranks for
|
||||
* @param {String} params - The params to search for
|
||||
* @return {Number} The data index of a matching job
|
||||
*/
|
||||
function getJobRankFromParams(jobIndex, params) {
|
||||
if (isNaN(params)) {
|
||||
for (let i in getJobData(jobIndex).ranks) {
|
||||
if ((toLowerCase(getJobData(jobIndex).ranks[i].name).indexOf(toLowerCase(params)) != -1)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (let i in getJobData(jobIndex).ranks) {
|
||||
if (getJobData(jobIndex).ranks[i].level == toInteger(params)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function getJobRoutesCommand(command, params, client) {
|
||||
let closestJobLocation = getClosestJobLocation(getPlayerPosition(client));
|
||||
|
||||
if (!closestJobLocation) {
|
||||
messagePlayerAlert(client, getLocaleString(client, "InvalidJob"));
|
||||
return false;
|
||||
}
|
||||
|
||||
let jobData = getJobData(closestJobLocation.jobIndex);
|
||||
|
||||
let jobRoutesList = jobData.routes.map(function (r) {
|
||||
return `{chatBoxListIndex}${r.index}: ${(r.enabled) ? "{softGreen}" : "{softRed}"}${r.name} {ALTCOLOUR}(${r.locations.length} stops, added ${getTimeDifferenceDisplay(getCurrentUnixTimestamp(), r.whenCreated)} ago)`;
|
||||
});
|
||||
let chunkedList = splitArrayIntoChunks(jobRoutesList, 2);
|
||||
|
||||
messagePlayerNormal(client, makeChatBoxSectionHeader(getLocaleString(client, "HeaderJobRoutesList", `${jobData.name}, Location ${closestJobLocation.index}`)));
|
||||
for (let i in chunkedList) {
|
||||
messagePlayerInfo(client, chunkedList[i].join(", "));
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function getJobRouteInfoCommand(command, params, client) {
|
||||
if (areParamsEmpty(params)) {
|
||||
messagePlayerSyntax(client, getCommandSyntaxText(command));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!areThereEnoughParams(params, 2, " ")) {
|
||||
messagePlayerSyntax(client, getCommandSyntaxText(command));
|
||||
return false;
|
||||
}
|
||||
|
||||
let jobIndex = getJobFromParams(getParam(params, " ", 1));
|
||||
if (jobIndex == -1) {
|
||||
messagePlayerSyntax(client, getLocaleString(client, "InvalidJob"));
|
||||
return false;
|
||||
}
|
||||
|
||||
let routeIndex = getJobRouteFromParams(getParam(params, " ", 2), jobIndex);
|
||||
if (routeIndex == -1) {
|
||||
messagePlayerSyntax(client, getLocaleString(client, "InvalidJobRoute"));
|
||||
return false;
|
||||
}
|
||||
|
||||
let jobRouteData = getJobRouteData(jobIndex, routeIndex);
|
||||
let jobData = getJobData(jobRouteData.jobIndex);
|
||||
|
||||
let tempStats = [
|
||||
[`ID`, `${jobRouteData.index}/${jobRouteData.databaseId}`],
|
||||
[`Job`, `${jobData.name}`],
|
||||
[`Name`, `${jobRouteData.name}`],
|
||||
[`Added By`, `${loadAccountFromId(jobRouteData.whoCreated).name}`],
|
||||
[`Added On`, `${new Date(jobRouteData.whenCreated * 1000).toLocaleDateString("en-GB")}`],
|
||||
[`Enabled`, `${getYesNoFromBool(jobRouteData.enabled)}`],
|
||||
[`Stops`, `${jobRouteData.locations.length}`],
|
||||
[`Pay`, `${getCurrencyString(jobRouteData.pay)}`],
|
||||
//[`Start Message`, `${jobRouteData.startMessage}`],
|
||||
//[`Finish Message`, `${jobRouteData.finishMessage}`],
|
||||
//[`Location Goto Message`, `${jobRouteData.locationGotoMessage}`],
|
||||
//[`Location Arrive Message`, `${jobRouteData.locationArriveMessage}`],
|
||||
//[`Location Arrive Message`, `${jobRouteData.locationArriveMessage}`],
|
||||
[`Vehicle Colour`, `${getVehicleColourInfoString(jobRouteData.vehicleColour1, false)}, ${getVehicleColourInfoString(jobRouteData.vehicleColour2, false)}`],
|
||||
];
|
||||
|
||||
let stats = tempStats.map(stat => `{chatBoxListIndex}${stat[0]}: {ALTCOLOUR}${stat[1]}{MAINCOLOUR}`);
|
||||
|
||||
messagePlayerNormal(client, makeChatBoxSectionHeader(getLocaleString(client, "HeaderJobRouteInfo", `${jobData.name}, Location ${jobRouteData.index}`)));
|
||||
let chunkedList = splitArrayIntoChunks(stats, 4);
|
||||
for (let i in chunkedList) {
|
||||
messagePlayerInfo(client, chunkedList[i].join(", "));
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function jobInviteCommand(command, params, client) {
|
||||
if (areParamsEmpty(params)) {
|
||||
messagePlayerSyntax(client, getCommandSyntaxText(command));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getPlayerJob(client) == -1) {
|
||||
messagePlayerError(client, getLocaleString(client, "InvalidJob"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!doesPlayerHaveJobPermission(client, getJobFlagValue("AddMember"))) {
|
||||
messagePlayerError(client, getLocaleString(client, "CantAddJobMembers"));
|
||||
return false;
|
||||
}
|
||||
|
||||
let targetClient = getPlayerFromParams(params);
|
||||
|
||||
if (getPlayerJob(targetClient) != -1) {
|
||||
messagePlayerError(client, getLocaleString(client, "JobInviteAlreadyHasJob"));
|
||||
return false;
|
||||
}
|
||||
|
||||
messagePlayerSuccess(client, getLocaleString(client, "JobInviteSent", `{ALTCOLOUR}${getCharacterFullName(targetClient)}{MAINCOLOUR}`));
|
||||
showPlayerPrompt(targetClient, getLocaleString(targetClient, "JobInviteRequest", `{ALTCOLOUR}${getCharacterFullName(client)}{MAINCOLOUR}`, `{jobYellow}${getJobData(getPlayerJob(client)).name}{MAINCOLOUR}`, getLocaleString(targetClient, "GUIAlertTitle"), getLocaleString(targetClient, "Yes"), getLocaleString(targetClient, "No")));
|
||||
getPlayerData(targetClient).promptType = V_PROMPT_JOBINVITE;
|
||||
getPlayerData(targetClient).promptValue = getPlayerJob(client);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function jobUninviteCommand(command, params, client) {
|
||||
if (areParamsEmpty(params)) {
|
||||
messagePlayerSyntax(client, getCommandSyntaxText(command));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getPlayerJob(client) == -1) {
|
||||
messagePlayerError(client, getLocaleString(client, "InvalidJob"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!doesPlayerHaveJobPermission(client, getJobFlagValue("RemoveMember"))) {
|
||||
messagePlayerError(client, getLocaleString(client, "CantRemoveJobMembers"));
|
||||
return false;
|
||||
}
|
||||
|
||||
let targetClient = getPlayerFromParams(params);
|
||||
|
||||
if (getPlayerJob(targetClient) != getPlayerJob(client)) {
|
||||
messagePlayerError(client, getLocaleString(client, "JobUnInviteNotInJob"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getJobRankData(getPlayerJob(client), getPlayerJobRank(client)).level <= getJobRankData(getPlayerJob(targetClient), getPlayerJobRank(targetClient)).level) {
|
||||
messagePlayerError(client, getLocaleString(client, "JobUnInviteTooLow"));
|
||||
return false;
|
||||
}
|
||||
|
||||
messagePlayerSuccess(client, getLocaleString(client, "PlayerRemovedFromJob", `{ALTCOLOUR}${getCharacterFullName(targetClient)}{MAINCOLOUR}`));
|
||||
messagePlayerAlert(targetClient, getLocaleString(client, "RemovedFromJob", `{ALTCOLOUR}${getCharacterFullName(client)}{MAINCOLOUR}`));
|
||||
|
||||
stopWorking(targetClient);
|
||||
|
||||
getPlayerCurrentSubAccount(targetClient).job = 0;
|
||||
getPlayerCurrentSubAccount(targetClient).jobIndex = -1;
|
||||
getPlayerCurrentSubAccount(targetClient).jobRank = 0;
|
||||
getPlayerCurrentSubAccount(targetClient).jobRankIndex = -1;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -58,7 +58,7 @@ function addKeyBindCommand(command, params, client) {
|
||||
if (!keyId) {
|
||||
messagePlayerError(client, getLocaleString(client, "InvalidKeyBindName"));
|
||||
messagePlayerTip(client, getLocaleString(client, "KeyBindNameTip"));
|
||||
messagePlayerInfo(client, getLocaleString(client, "UniversalInlineExampleList", `{ALTCOLOUR}1, 2, a, b, numplus, num1, f1, f2, pageup, delete, insert, rightshift, leftctrl{MAINCOLOR}`));
|
||||
messagePlayerInfo(client, getLocaleString(client, "UniversalInlineExamplesList", `{ALTCOLOUR}1, 2, a, b, numplus, num1, f1, f2, pageup, delete, insert, rightshift, leftctrl{MAINCOLOR}`));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -264,34 +264,34 @@ function reloadLocaleConfigurationCommand(command, params, client) {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
async function translateMessage(messageText, translateFrom = getGlobalConfig().locale.defaultLanguageId, translateTo = getGlobalConfig().locale.defaultLanguageId) {
|
||||
return new Promise(resolve => {
|
||||
if (translateFrom == translateTo) {
|
||||
resolve(messageText);
|
||||
}
|
||||
function translateMessage(messageText, translateFrom = getGlobalConfig().locale.defaultLanguageId, translateTo = getGlobalConfig().locale.defaultLanguageId) {
|
||||
//return new Promise(resolve => {
|
||||
if (translateFrom == translateTo) {
|
||||
resolve(messageText);
|
||||
}
|
||||
|
||||
for (let i in cachedTranslations[translateFrom][translateTo]) {
|
||||
if (cachedTranslations[translateFrom][translateTo][i][0] == messageText) {
|
||||
logToConsole(LOG_DEBUG, `[Translate]: Using existing translation for ${getGlobalConfig().locale.locales[translateFrom].englishName} to ${getGlobalConfig().locale.locales[translateTo].englishName} - (${messageText}), (${cachedTranslations[translateFrom][translateTo][i][1]})`);
|
||||
resolve(cachedTranslations[translateFrom][translateTo][i][1]);
|
||||
return true;
|
||||
}
|
||||
for (let i in cachedTranslations[translateFrom][translateTo]) {
|
||||
if (cachedTranslations[translateFrom][translateTo][i][0] == messageText) {
|
||||
logToConsole(LOG_DEBUG, `[Translate]: Using existing translation for ${getGlobalConfig().locale.locales[translateFrom].englishName} to ${getGlobalConfig().locale.locales[translateTo].englishName} - (${messageText}), (${cachedTranslations[translateFrom][translateTo][i][1]})`);
|
||||
resolve(cachedTranslations[translateFrom][translateTo][i][1]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
let thisTranslationURL = getGlobalConfig().locale.translateURL.format(encodeURIComponent(messageText), toUpperCase(getGlobalConfig().locale.locales[translateFrom].isoCode), toUpperCase(getGlobalConfig().locale.locales[translateTo].isoCode), getGlobalConfig().locale.apiEmail);
|
||||
httpGet(
|
||||
thisTranslationURL,
|
||||
"",
|
||||
function (data) {
|
||||
data = ArrayBufferToString(data);
|
||||
let translationData = JSON.parse(data);
|
||||
cachedTranslations[translateFrom][translateTo].push([messageText, translationData.responseData.translatedText]);
|
||||
resolve(translationData.responseData.translatedText);
|
||||
},
|
||||
function (data) {
|
||||
}
|
||||
);
|
||||
});
|
||||
let thisTranslationURL = getGlobalConfig().locale.translateURL.format(encodeURIComponent(messageText), toUpperCase(getGlobalConfig().locale.locales[translateFrom].isoCode), toUpperCase(getGlobalConfig().locale.locales[translateTo].isoCode), getGlobalConfig().locale.apiEmail);
|
||||
httpGet(
|
||||
thisTranslationURL,
|
||||
"",
|
||||
function (data) {
|
||||
data = ArrayBufferToString(data);
|
||||
let translationData = JSON.parse(data);
|
||||
cachedTranslations[translateFrom][translateTo].push([messageText, translationData.responseData.translatedText]);
|
||||
resolve(translationData.responseData.translatedText);
|
||||
},
|
||||
function (data) {
|
||||
}
|
||||
);
|
||||
//});
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
@@ -136,6 +136,12 @@ function messagePlayerTalk(client, talkingClient, messageText) {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function messagePlayerPhone(client, talkingClient, messageText) {
|
||||
messagePlayerNormal(client, `🗣️ ${getPlayerAccentInlineOutput(talkingClient)}${getClientSubAccountName(talkingClient)} says (phone): ${messageText}`, getColourByType("talkMessage"));
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function messagePlayerWhisper(client, whisperingClient, messageText) {
|
||||
messagePlayerNormal(client, `🤫 ${getPlayerAccentInlineOutput(whisperingClient)}${getClientSubAccountName(whisperingClient)} whispers: ${messageText}`, getColourByType("whisperMessage"));
|
||||
}
|
||||
@@ -244,22 +250,47 @@ function messagePlayerPrivateMessage(toClient, fromClient, messageText) {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function showPlayerInfo(client, infoMessage, infoTitle = "Info") {
|
||||
//if (doesPlayerUseGUI(client)) {
|
||||
// showPlayerErrorGUI(client, errorMessage, errorTitle, getLocaleString(client, "GUIOkButton"));
|
||||
//} else {
|
||||
messagePlayerInfo(client, infoMessage);
|
||||
//}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function showPlayerError(client, errorMessage, errorTitle = "Error") {
|
||||
if (doesPlayerUseGUI(client)) {
|
||||
showPlayerErrorGUI(client, errorMessage, errorTitle);
|
||||
} else {
|
||||
messagePlayerError(client, errorMessage);
|
||||
}
|
||||
//if (doesPlayerUseGUI(client)) {
|
||||
// showPlayerErrorGUI(client, errorMessage, errorTitle, getLocaleString(client, "GUIOkButton"));
|
||||
//} else {
|
||||
messagePlayerError(client, errorMessage);
|
||||
//}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function showPlayerAlert(client, alertMessage, alertTitle = "Alert") {
|
||||
if (doesPlayerUseGUI(client)) {
|
||||
showPlayerInfoGUI(client, alertMessage, alertTitle);
|
||||
} else {
|
||||
messagePlayerAlert(client, alertMessage);
|
||||
//if (doesPlayerUseGUI(client)) {
|
||||
// showPlayerInfoGUI(client, alertMessage, alertTitle);
|
||||
//} else {
|
||||
messagePlayerAlert(client, alertMessage);
|
||||
//}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function messagePlayerPhoneCall(talkingPlayer, receivingPlayer, messageText) {
|
||||
let clients = getClients();
|
||||
for (let i in clients) {
|
||||
if (isPlayerSpawned(clients[i])) {
|
||||
if (hasBitFlag(getPlayerData(clients[i]).accountData.flags.moderation, getModerationFlagValue("CanHearEverything")) || (getDistance(getPlayerPosition(talkingPlayer), getPlayerPosition(clients[i])) <= getGlobalConfig().talkDistance && getPlayerDimension(talkingPlayer) == getPlayerDimension(clients[i]))) {
|
||||
messagePlayerPhone(clients[i], talkingPlayer, messageText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
messagePlayerNormal(receivingPlayer, `📞 {ALTCOLOUR}(On Phone): {MAINCOLOUR}${messageText}`);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -364,19 +364,23 @@ function enterExitPropertyCommand(command, params, client) {
|
||||
getPlayerData(client).enteringExitingProperty = [(isBusiness) ? V_PROPERTY_TYPE_BUSINESS : V_PROPERTY_TYPE_HOUSE, closestProperty.index];
|
||||
|
||||
meActionToNearbyPlayers(client, getLanguageLocaleString(englishId, "EntersProperty", typeString, nameString));
|
||||
|
||||
if (closestProperty.exitScene != "" && isGameFeatureSupported("interiorScene")) {
|
||||
getPlayerCurrentSubAccount(client).spawnPosition = closestProperty.exitPosition;
|
||||
if (isMainWorldScene(closestProperty.exitScene) || closestProperty.exitScene == "V.MAINWORLD") {
|
||||
setPlayerScene(client, getGameConfig().mainWorldScene[getGame()]);
|
||||
} else {
|
||||
setPlayerScene(client, closestProperty.exitScene);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
setPlayerDimension(client, 50000 + getPlayerId(client));
|
||||
|
||||
if (isFadeCameraSupported()) {
|
||||
fadePlayerCamera(client, false, 1000);
|
||||
fadePlayerCamera(client, false, 2000);
|
||||
}
|
||||
|
||||
if (closestProperty.exitScene != "" && isGameFeatureSupported("interiorScene")) {
|
||||
setTimeout(function () {
|
||||
getPlayerCurrentSubAccount(client).spawnPosition = closestProperty.exitPosition;
|
||||
if (isMainWorldScene(closestProperty.exitScene)) {
|
||||
setPlayerScene(client, getGameConfig().mainWorldScene[getGame()]);
|
||||
} else {
|
||||
setPlayerScene(client, closestProperty.exitScene);
|
||||
}
|
||||
}, 2000);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
setTimeout(function () {
|
||||
@@ -397,21 +401,22 @@ function enterExitPropertyCommand(command, params, client) {
|
||||
|
||||
meActionToNearbyPlayers(client, getLanguageLocaleString(englishId, "ExitsProperty", typeString, nameString));
|
||||
|
||||
if (closestProperty.entranceScene != "" && isGameFeatureSupported("interiorScene")) {
|
||||
getPlayerCurrentSubAccount(client).spawnPosition = closestProperty.entrancePosition;
|
||||
if (isMainWorldScene(closestProperty.entranceScene) || closestProperty.entranceScene == "V.MAINWORLD") {
|
||||
destroyGameElement(client.player);
|
||||
setPlayerScene(client, getGameConfig().mainWorldScene[getGame()]);
|
||||
} else {
|
||||
destroyGameElement(client.player);
|
||||
setPlayerScene(client, closestProperty.entranceScene);
|
||||
}
|
||||
|
||||
return false;
|
||||
if (isFadeCameraSupported()) {
|
||||
fadePlayerCamera(client, false, 2000);
|
||||
}
|
||||
|
||||
if (isFadeCameraSupported()) {
|
||||
fadePlayerCamera(client, false, 1000);
|
||||
if (closestProperty.entranceScene != "" && isGameFeatureSupported("interiorScene")) {
|
||||
setTimeout(function () {
|
||||
getPlayerCurrentSubAccount(client).spawnPosition = closestProperty.entrancePosition;
|
||||
if (isMainWorldScene(closestProperty.entranceScene)) {
|
||||
destroyGameElement(client.player);
|
||||
setPlayerScene(client, getGameConfig().mainWorldScene[getGame()]);
|
||||
} else {
|
||||
destroyGameElement(client.player);
|
||||
setPlayerScene(client, closestProperty.entranceScene);
|
||||
}
|
||||
}, 2000);
|
||||
return false;
|
||||
}
|
||||
|
||||
setTimeout(function () {
|
||||
@@ -468,7 +473,7 @@ function getPlayerInfoCommand(command, params, client) {
|
||||
["Account", `${getPlayerData(targetClient).accountData.name}{mediumGrey}[${getPlayerData(targetClient).accountData.databaseId}]{ALTCOLOUR}`],
|
||||
["Character", `${getCharacterFullName(targetClient)}{mediumGrey}[${getPlayerCurrentSubAccount(targetClient).databaseId}]{ALTCOLOUR}`],
|
||||
["Connected", `${getTimeDifferenceDisplay(getCurrentUnixTimestamp(), getPlayerData(targetClient).connectTime)} ago`],
|
||||
["Registered", `${registerDate.toLocaleDateString()}`],
|
||||
["Registered", `${registerDate.toLocaleDateString("en-GB")}`],
|
||||
["Game Version", `${targetClient.gameVersion}`],
|
||||
["Script Version", `${scriptVersion}`],
|
||||
["Client Version", `${getPlayerData(targetClient).clientVersion}`],
|
||||
@@ -476,7 +481,7 @@ function getPlayerInfoCommand(command, params, client) {
|
||||
["Skin", `${skinName}{mediumGrey}[Model: ${skinModel}/Index: ${skinIndex}]{ALTCOLOUR}`],
|
||||
["Clan", `${clan}`],
|
||||
["Job", `${job}`],
|
||||
["Current Date", `${currentDate.toLocaleDateString()}`],
|
||||
["Current Date", `${currentDate.toLocaleDateString("en-GB")}`],
|
||||
];
|
||||
|
||||
let stats = tempStats.map(stat => `{MAINCOLOUR}${stat[0]}: {ALTCOLOUR}${stat[1]} {MAINCOLOUR}`);
|
||||
@@ -521,12 +526,12 @@ function checkPlayerSpawning() {
|
||||
// ===========================================================================
|
||||
|
||||
function showPlayerPrompt(client, promptMessage, promptTitle, yesButtonText, noButtonText) {
|
||||
if (doesPlayerUseGUI(client)) {
|
||||
showPlayerPromptGUI(client, promptMessage, promptTitle, yesButtonText, noButtonText);
|
||||
} else {
|
||||
messagePlayerNormal(client, `🛎️ ${promptMessage} `);
|
||||
messagePlayerInfo(client, getLocaleString(client, "PromptResponseTip", `{ALTCOLOUR}/yes{MAINCOLOUR}`, `{ALTCOLOUR}/no{MAINCOLOUR}`));
|
||||
}
|
||||
//if (doesPlayerUseGUI(client)) {
|
||||
// showPlayerPromptGUI(client, promptMessage, promptTitle, yesButtonText, noButtonText);
|
||||
//} else {
|
||||
messagePlayerNormal(client, `🛎️ ${promptMessage} `);
|
||||
messagePlayerInfo(client, getLocaleString(client, "PromptResponseTip", `{ALTCOLOUR}/yes{MAINCOLOUR}`, `{ALTCOLOUR}/no{MAINCOLOUR}`));
|
||||
//}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -1012,4 +1017,39 @@ function getPlayerInPropertyData(client) {
|
||||
getPlayerData(client).inProperty = null;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function scoreBoardCommand(command, params, client) {
|
||||
// Handled client side
|
||||
return false;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function locatePlayerCommand(client) {
|
||||
if (isPlayerSpawned(client)) {
|
||||
messagePlayerError(client, getLocaleString(client, "MustBeSpawned"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (areParamsEmpty(params)) {
|
||||
messagePlayerSyntax(client, getCommandSyntaxText(command));
|
||||
return false;
|
||||
}
|
||||
|
||||
let targetClient = getPlayerFromParams(client);
|
||||
|
||||
if (!targetClient) {
|
||||
messagePlayerError(client, getLocaleString(client, "InvalidPlayer"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isPlayerSpawned(targetClient)) {
|
||||
messagePlayerError(client, getLocaleString(client, "InvalidPlayer"));
|
||||
return false;
|
||||
}
|
||||
|
||||
messagePlayerInfo(client, getLocaleString(client, "PlayerLocateDistanceAndDirection", `{ALTCOLOUR}${getCharacterFullName(targetClient)}{MAINCOLOUR}`, `{ALTCOLOUR}${getDistance(getPlayerPosition(client), getPlayerPosition(targetClient))}{MAINCOLOUR}`, `{ALTCOLOUR}${getLocaleString(client, getCardinalDirectionName(getCardinalDirection(getPlayerPosition(client), getPlayerPosition(targetClient))))}`))
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -499,7 +499,7 @@ function getPlayerName(client) {
|
||||
// ===========================================================================
|
||||
|
||||
function getServerName() {
|
||||
return "Asshat Gaming RP";
|
||||
return "Connected Roleplay";
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -619,9 +619,9 @@ function setVehicleEngine(vehicle, engine) {
|
||||
// ===========================================================================
|
||||
|
||||
function setVehicleLocked(vehicle, locked) {
|
||||
vehicle.locked = locked;
|
||||
setEntityData(vehicle, "v.rp.locked", locked, true);
|
||||
sendNetworkEventToPlayer("v.rp.veh.locked", null, vehicle.id, locked);
|
||||
vehicle.locked = locked;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -815,29 +815,18 @@ function getVehicleName(vehicle) {
|
||||
// ===========================================================================
|
||||
|
||||
function getElementModel(element) {
|
||||
if (typeof element.modelIndex != "undefined") {
|
||||
return element.modelIndex;
|
||||
}
|
||||
|
||||
if (typeof element.model != "undefined") {
|
||||
return element.model;
|
||||
}
|
||||
return element.modelIndex;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function givePlayerWeaponAmmo(client, ammo) {
|
||||
givePlayerWeapon(client, getPlayerWeapon(client), getPlayerWeaponAmmo(client) + ammo);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function getPlayerWeapon(client) {
|
||||
if (areServerElementsSupported(client)) {
|
||||
return getPlayerPed(client).weapon;
|
||||
} else {
|
||||
return getPlayerData(client).syncWeapon;
|
||||
}
|
||||
return getPlayerPed(client).weapon;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -889,10 +878,10 @@ function disconnectFromDatabase(dbConnection, force = false) {
|
||||
function queryDatabase(dbConnection, queryString, useThread = false) {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Database] Query string: ${queryString}`);
|
||||
if (useThread == true) {
|
||||
Promise.resolve().then(() => {
|
||||
let queryResult = dbConnection.query(queryString);
|
||||
return queryResult;
|
||||
});
|
||||
//Promise.resolve().then(() => {
|
||||
let queryResult = dbConnection.query(queryString);
|
||||
return queryResult;
|
||||
//});
|
||||
} else {
|
||||
return dbConnection.query(queryString);
|
||||
}
|
||||
@@ -1021,72 +1010,6 @@ function executeDatabaseQueryCommand(command, params, client) {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function setConstantsAsGlobalVariablesInDatabase() {
|
||||
let dbConnection = connectToDatabase();
|
||||
let entries = Object.entries(global);
|
||||
for (let i in entries) {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Database] Checking entry ${i} (${entries[i]})`);
|
||||
if (toString(i).slice(0, 3).indexOf("V_") != -1) {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Database] Adding ${i} (${entries[i]}) to database global variables`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function createDatabaseInsertQuery(tableName, data) {
|
||||
let fields = [];
|
||||
let values = [];
|
||||
|
||||
for (let i in data) {
|
||||
if (data[i][1] != "undefined" && data[i][1] != NaN && data[i][0] != 'NaN') {
|
||||
if (data[i][1] != "undefined" && data[i][1] != NaN && data[i][1] != 'NaN') {
|
||||
fields.push(data[i][0]);
|
||||
|
||||
if (typeof data[i][1] == "string") {
|
||||
if (data[i][1] == "{UNIXTIMESTAMP}") {
|
||||
values.push("UNIX_TIMESTAMP()");
|
||||
} else {
|
||||
values.push(`'${data[i][1]}'`);
|
||||
}
|
||||
} else {
|
||||
values.push(data[i][1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let queryString = `INSERT INTO ${tableName} (${fields.join(", ")}) VALUES (${values.join(", ")})`;
|
||||
return queryString;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function createDatabaseUpdateQuery(tableName, data, whereClause) {
|
||||
let values = [];
|
||||
|
||||
for (let i in data) {
|
||||
if (data[i][0] != "undefined" && data[i][0] != NaN && data[i][0] != 'NaN') {
|
||||
if (data[i][1] != "undefined" && data[i][1] != NaN && data[i][1] != 'NaN') {
|
||||
if (typeof data[i][1] == "string") {
|
||||
if (data[i][1] == "{UNIXTIMESTAMP}") {
|
||||
values.push(`${data[i][0]}=UNIX_TIMESTAMP()`);
|
||||
} else {
|
||||
values.push(`${data[i][0]}='${data[i][1]}'`);
|
||||
}
|
||||
} else {
|
||||
values.push(`${data[i][0]}=${data[i][1]}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let queryString = `UPDATE ${tableName} SET ${values.join(", ")} WHERE ${whereClause}`;
|
||||
return queryString;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function sendNetworkEventToPlayer(eventName, client, ...args) {
|
||||
let argsArray = [eventName, client];
|
||||
argsArray = argsArray.concat(args);
|
||||
@@ -1391,38 +1314,6 @@ function setVehicleTrunkState(vehicle, trunkState) {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
/*
|
||||
function addAllEventHandlers() {
|
||||
bindServerEventHandler("onResourceStart", onResourceStart)
|
||||
bindServerEventHandler("onResourceStop", onResourceStart)
|
||||
addServerEventHandler("onServerStop", onResourceStart);
|
||||
|
||||
addServerEventHandler("onResourceStart", onResourceStart);
|
||||
addServerEventHandler("onResourceStop", onResourceStop);
|
||||
addServerEventHandler("onServerStop", onResourceStop);
|
||||
|
||||
addServerEventHandler("onProcess", onProcess);
|
||||
addServerEventHandler("onEntityProcess", onEntityProcess);
|
||||
|
||||
addServerEventHandler("onPlayerConnect", onInitialConnectionToServer);
|
||||
addServerEventHandler("onPlayerJoin", onPlayerJoin);
|
||||
addServerEventHandler("onPlayerJoined", onPlayerJoined);
|
||||
addServerEventHandler("onPlayerChat", onPlayerChat);
|
||||
addServerEventHandler("onPlayerQuit", onPlayerQuit);
|
||||
addServerEventHandler("onElementStreamIn", onElementStreamIn);
|
||||
addServerEventHandler("onElementStreamOut", onElementStreamOut);
|
||||
|
||||
addServerEventHandler("onPedSpawn", onPedSpawn);
|
||||
addServerEventHandler("onPedEnterVehicle", onPedEnteringVehicle);
|
||||
addServerEventHandler("onPedExitVehicle", onPedExitingVehicle);
|
||||
|
||||
addServerEventHandler("onPedEnteringVehicle", onPedEnteringVehicle);
|
||||
addServerEventHandler("onPedExitingVehicle", onPedExitingVehicle);
|
||||
}
|
||||
*/
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function addServerCommandHandler(command, handlerFunction) {
|
||||
addCommandHandler(command, handlerFunction);
|
||||
}
|
||||
@@ -1533,7 +1424,7 @@ function setServerName(name) {
|
||||
// ===========================================================================
|
||||
|
||||
function setServerPassword(password) {
|
||||
server.setPassword(password);
|
||||
//server.setPassword(password);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -1548,4 +1439,51 @@ function setServerRule(ruleName, ruleValue) {
|
||||
server.setRule(ruleName, ruleValue);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function addAllEventHandlers() {
|
||||
addEventHandler("onResourceStart", onResourceStart);
|
||||
addEventHandler("onResourceStop", onResourceStop);
|
||||
addEventHandler("onProcess", onProcess);
|
||||
addEventHandler("onPlayerConnect", onPlayerConnect);
|
||||
addEventHandler("onPlayerJoin", onPlayerJoin);
|
||||
addEventHandler("onPlayerJoined", onPlayerJoined);
|
||||
addEventHandler("onPlayerChat", onPlayerChat);
|
||||
addEventHandler("onPlayerQuit", onPlayerQuit);
|
||||
addEventHandler("onElementStreamIn", onElementStreamIn);
|
||||
addEventHandler("onElementStreamOut", onElementStreamOut);
|
||||
addEventHandler("onPedSpawn", onPedSpawn);
|
||||
|
||||
if (getGame() <= V_GAME_GTA_IV) {
|
||||
addEventHandler("onPedEnteredVehicleEx", onPedEnteredVehicle);
|
||||
addEventHandler("onPedExitedVehicleEx", onPedExitedVehicle);
|
||||
addEventHandler("onPedEnteredSphereEx", onPedEnteredSphere);
|
||||
addEventHandler("onPedExitedSphereEx", onPedExitedSphere);
|
||||
}
|
||||
|
||||
if (getGame() <= V_GAME_GTA_SA) {
|
||||
addEventHandler("OnPickupCollected", onPedPickupPickedUp);
|
||||
}
|
||||
|
||||
if (getGame() == V_GAME_MAFIA_ONE) {
|
||||
addEventHandler("onPedEnteringVehicleEx", onPedEnteredVehicle);
|
||||
addEventHandler("onPedExitingVehicleEx", onPedExitedVehicle);
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function getVehicleOccupants(vehicle) {
|
||||
let occupants = [];
|
||||
|
||||
let clients = getClients();
|
||||
for (let i in clients) {
|
||||
if (getPlayerVehicle(clients[i]) == vehicle) {
|
||||
occupants.push(clients[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return occupants;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -806,10 +806,10 @@ function disconnectFromDatabase(dbConnection) {
|
||||
function queryDatabase(dbConnection, queryString, useThread = false) {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Database] Query string: ${queryString}`);
|
||||
if (useThread == true) {
|
||||
Promise.resolve().then(() => {
|
||||
let queryResult = dbConnection.query(queryString);
|
||||
return queryResult;
|
||||
});
|
||||
//Promise.resolve().then(() => {
|
||||
let queryResult = dbConnection.query(queryString);
|
||||
return queryResult;
|
||||
//});
|
||||
} else {
|
||||
return dbConnection.query(queryString);
|
||||
}
|
||||
@@ -857,7 +857,7 @@ function freeDatabaseQuery(dbQuery) {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
async function fetchQueryAssoc(dbConnection, queryString) {
|
||||
function fetchQueryAssoc(dbConnection, queryString) {
|
||||
return dbConnection.query(queryString, function (err, result, fields) {
|
||||
return result;
|
||||
});
|
||||
|
||||
@@ -1010,6 +1010,12 @@ function sendPlayerEnterPropertyKey(client, key) {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function sendPlayerScoreBoardKey(client, key) {
|
||||
sendNetworkEventToPlayer("v.rp.scoreBoardKey", client, key);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function makePedPlayAnimation(ped, animationSlot, positionOffset) {
|
||||
if (getAnimationData(animationSlot).loop == true) {
|
||||
setEntityData(ped, "v.rp.anim", animationSlot, true);
|
||||
@@ -1112,8 +1118,8 @@ function setPlayerInfiniteRun(client, state) {
|
||||
|
||||
// ==========================================================================
|
||||
|
||||
function sendBusinessToPlayer(client, businessId, isDeleted, name, entrancePosition, blipModel, pickupModel, buyPrice, rentPrice, hasInterior, locked, hasItems) {
|
||||
sendNetworkEventToPlayer("v.rp.business", client, businessId, isDeleted, name, entrancePosition, blipModel, pickupModel, buyPrice, rentPrice, hasInterior, locked, hasItems);
|
||||
function sendBusinessToPlayer(client, businessId, isDeleted, name, entrancePosition, blipModel, pickupModel, buyPrice, rentPrice, hasInterior, locked, hasItems, entranceFee) {
|
||||
sendNetworkEventToPlayer("v.rp.business", client, businessId, isDeleted, name, entrancePosition, blipModel, pickupModel, buyPrice, rentPrice, hasInterior, locked, hasItems, entranceFee);
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
@@ -1136,12 +1142,31 @@ function sendVehicleToPlayer(client, vehicleId, isDeleted, model, position, head
|
||||
|
||||
// ==========================================================================
|
||||
|
||||
function sendPayPhoneToPlayer(client, payPhoneId, isDeleted, state, position) {
|
||||
sendNetworkEventToPlayer("v.rp.payPhone", client, payPhoneId, isDeleted, state, position);
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
|
||||
function sendAllBusinessesToPlayer(client) {
|
||||
sendNetworkEventToPlayer("v.rp.removeBusinesses", client);
|
||||
|
||||
let businesses = getServerData().businesses;
|
||||
for (let i in businesses) {
|
||||
sendBusinessToPlayer(client, businesses[i].index, false, businesses[i].name, businesses[i].entrancePosition, businesses[i].entranceBlipModel, businesses[i].entrancePickupModel, businesses[i].buyPrice, businesses[i].rentPrice, businesses[i].hasInterior, doesBusinessHaveAnyItemsToBuy(i));
|
||||
sendBusinessToPlayer(client,
|
||||
businesses[i].index,
|
||||
false,
|
||||
businesses[i].name,
|
||||
businesses[i].entrancePosition,
|
||||
businesses[i].entranceBlipModel,
|
||||
businesses[i].entrancePickupModel,
|
||||
businesses[i].buyPrice,
|
||||
businesses[i].rentPrice,
|
||||
businesses[i].hasInterior,
|
||||
businesses[i].locked,
|
||||
doesBusinessHaveAnyItemsToBuy(i),
|
||||
businesses[i].entranceFee
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1182,6 +1207,17 @@ function sendAllVehiclesToPlayer(client) {
|
||||
|
||||
// ==========================================================================
|
||||
|
||||
function sendAllPayPhonesToPlayer(client) {
|
||||
sendNetworkEventToPlayer("v.rp.removePayPhones", client);
|
||||
|
||||
let payPhones = getServerData().payPhones;
|
||||
for (let i in payPhones) {
|
||||
sendPayPhoneToPlayer(client, payPhones[i].index, false, payPhones[i].state, payPhones[i].position);
|
||||
}
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
|
||||
function makePlayerHoldObjectModel(client, modelIndex) {
|
||||
sendNetworkEventToPlayer("v.rp.holdObject", client, getPlayerData(client).ped, modelIndex);
|
||||
}
|
||||
@@ -1302,7 +1338,7 @@ function showSingleParticleEffect(position, particleEffectId, strength = 1.0, du
|
||||
// ==========================================================================
|
||||
|
||||
function sendPlayerCurrencyString(client) {
|
||||
sendNetworkEventToPlayer("v.rp.currencyString", client, getGlobalConfig().economy.currencyString);
|
||||
sendNetworkEventToPlayer("v.rp.currencyString", client, getServerConfig().economy.currencyString);
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
@@ -1319,11 +1355,6 @@ function playerMapLoaded(client, mapName) {
|
||||
|
||||
setTimeout(function () {
|
||||
processPlayerEnteringExitingProperty(client);
|
||||
|
||||
setTimeout(function () {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.NetEvents] Enabling all rendering states for ${getPlayerDisplayForConsole(client)} since map switch finished`);
|
||||
setPlayer2DRendering(client, true, true, true, true, true, true);
|
||||
}, 500);
|
||||
}, 500);
|
||||
}
|
||||
|
||||
@@ -1351,4 +1382,34 @@ function requestPlayerToken(client) {
|
||||
sendNetworkEventToPlayer("v.rp.token", client);
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
|
||||
function sendPayPhoneStateToPlayer(client, payPhoneIndex, state) {
|
||||
sendNetworkEventToPlayer("v.rp.payPhoneState", client, payPhoneIndex, state);
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
|
||||
function sendPayPhoneDialingToPlayer(client) {
|
||||
sendNetworkEventToPlayer("v.rp.payPhoneDial", client);
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
|
||||
function sendPayPhoneHangupToPlayer(client) {
|
||||
sendNetworkEventToPlayer("v.rp.payPhoneHangup", client);
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
|
||||
function sendPayPhonePickupToPlayer(client) {
|
||||
sendNetworkEventToPlayer("v.rp.payPhonePickup", client);
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
|
||||
function sendIncomingDamageMultiplierToClient(client, multiplier) {
|
||||
sendNetworkEventToPlayer("v.rp.incomingDamageMultiplier", client, multiplier);
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
@@ -519,7 +519,7 @@ function deleteNPCCommand(command, params, client) {
|
||||
// ===========================================================================
|
||||
|
||||
function deleteNPC(npcId) {
|
||||
quickDatabaseQuery(`DELETE FROM npc_main WHERE npc_id=${getNPCData(npcId).databaseId}`);
|
||||
quickDatabaseQuery(`UPDATE npc_main SET npc_deleted = 1 WHERE npc_id=${getNPCData(npcId).databaseId}`);
|
||||
|
||||
if (getNPCData(npcId)) {
|
||||
if (getNPCData(npcId).ped != false) {
|
||||
|
||||
721
scripts/server/payphone.js
Normal file
721
scripts/server/payphone.js
Normal file
@@ -0,0 +1,721 @@
|
||||
// ===========================================================================
|
||||
// Vortrex's Roleplay Resource
|
||||
// https://github.com/VortrexFTW/v-roleplay
|
||||
// ===========================================================================
|
||||
// FILE: payphone.js
|
||||
// DESC: Provides payphone functions and commands
|
||||
// TYPE: Server (JavaScript)
|
||||
// ===========================================================================
|
||||
|
||||
class PayPhoneData {
|
||||
constructor(dbAssoc = false) {
|
||||
this.databaseId = 0;
|
||||
this.serverId = 0;
|
||||
this.index = -1;
|
||||
this.state = V_PAYPHONE_STATE_IDLE;
|
||||
this.number = 0;
|
||||
this.position = toVector3(0.0, 0.0, 0.0);
|
||||
this.usingPlayer = false;
|
||||
this.connectedPlayer = false;
|
||||
this.enabled = false;
|
||||
this.broken = false;
|
||||
this.price = 0;
|
||||
this.whoAdded = 0;
|
||||
this.whenAdded = 0;
|
||||
this.otherPayPhone = -1;
|
||||
|
||||
if (dbAssoc) {
|
||||
this.databaseId = toInteger(dbAssoc["payphone_id"]);
|
||||
this.serverId = toInteger(dbAssoc["payphone_server"]);
|
||||
this.number = toInteger(dbAssoc["payphone_number"]);
|
||||
this.enabled = intToBool(dbAssoc["payphone_enabled"]);
|
||||
this.broken = intToBool(dbAssoc["payphone_broken"]);
|
||||
this.position = toVector3(toFloat(dbAssoc["payphone_pos_x"]), toFloat(dbAssoc["payphone_pos_y"]), toFloat(dbAssoc["payphone_pos_z"]));
|
||||
this.price = toInteger(dbAssoc["payphone_price"]);
|
||||
this.whoAdded = toInteger(dbAssoc["payphone_who_added"]);
|
||||
this.whenAdded = toInteger(dbAssoc["payphone_when_added"]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function initPayPhoneScript() {
|
||||
logToConsole(LOG_INFO, "[V.RP.PayPhone]: Initializing payphone script ...");
|
||||
logToConsole(LOG_INFO, "[V.RP.PayPhone]: Payphone script initialized successfully!");
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function createPayPhoneCommand(command, params, client) {
|
||||
let payPhoneNumber = generateRandomPhoneNumber();
|
||||
|
||||
if (!areParamsEmpty(params)) {
|
||||
if (isNaN(params)) {
|
||||
messagePlayerError(client, getLocaleString(client, "MustBeNumber"));
|
||||
return false;
|
||||
}
|
||||
|
||||
payPhoneNumber = toInteger(params);
|
||||
}
|
||||
|
||||
let closestPayPhone = getClosestPayPhone(getPlayerPosition(client));
|
||||
if (closestPayPhone != -1) {
|
||||
if (getDistance(getPlayerPosition(client), getPayPhoneData(closestPayPhone).position) <= getGlobalConfig().payPhoneAnswerDistance) {
|
||||
messagePlayerError(client, "There is already a payphone at this location!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
createPayPhone(getPlayerPosition(client), payPhoneNumber, getPlayerData(client).accountData.databaseId);
|
||||
messageAdmins(`{adminOrange}${getPlayerName(client)}{MAINCOLOUR} created a payphone with number {ALTCOLOUR}${payPhoneNumber}`);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function createPayPhone(position, number, addedBy = defaultNoAccountId) {
|
||||
let tempPayPhoneData = new PayPhoneData(false);
|
||||
tempPayPhoneData.number = number;
|
||||
tempPayPhoneData.position = position;
|
||||
tempPayPhoneData.state = V_PAYPHONE_STATE_IDLE;
|
||||
tempPayPhoneData.needsSaved = true;
|
||||
tempPayPhoneData.whoAdded = addedBy;
|
||||
tempPayPhoneData.whenAdded = getCurrentUnixTimestamp();
|
||||
tempPayPhoneData.whoDeleted = defaultNoAccountId;
|
||||
tempPayPhoneData.whenDeleted = 0;
|
||||
tempPayPhoneData.enabled = true;
|
||||
|
||||
getServerData().payPhones.push(tempPayPhoneData);
|
||||
|
||||
setAllPayPhoneIndexes();
|
||||
saveAllPayPhonesToDatabase();
|
||||
|
||||
sendPayPhoneToPlayer(null, getServerData().payPhones.length - 1, false, tempPayPhoneData.state, tempPayPhoneData.position);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function getClosestPayPhone(position) {
|
||||
let closest = 0;
|
||||
for (let i in getServerData().payPhones) {
|
||||
if (getDistance(position, getServerData().payPhones[i].position) < getDistance(position, getServerData().payPhones[closest].position)) {
|
||||
closest = i;
|
||||
}
|
||||
}
|
||||
|
||||
return closest;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
/**
|
||||
* @param {Number} payPhoneIndex - The data index of the payphone
|
||||
* @return {PayPhoneData} The payphone's data (class instance)
|
||||
*/
|
||||
function getPayPhoneData(payPhoneIndex) {
|
||||
if (payPhoneIndex == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (typeof getServerData().payPhones[payPhoneIndex] != "undefined") {
|
||||
return getServerData().payPhones[payPhoneIndex];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function getPayPhoneNumberCommand(command, params, client) {
|
||||
let closestPayPhone = getClosestPayPhone(getPlayerPosition(client));
|
||||
|
||||
if (closestPayPhone == -1) {
|
||||
messagePlayerError(client, getLocaleString(client, "NoPayPhoneCloseEnough"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getDistance(getPlayerPosition(client), getPayPhoneData(closestPayPhone).position) > getGlobalConfig().payPhoneAnswerDistance) {
|
||||
messagePlayerError(client, getLocaleString(client, "NoPayPhoneCloseEnough"));
|
||||
return false;
|
||||
}
|
||||
|
||||
messagePlayerInfo(client, getLocaleString(client, "ThisPayPhoneNumber", getPayPhoneData(closestPayPhone).number));
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function deletePayPhoneCommand(command, params, client) {
|
||||
let payPhoneIndex = getClosestPayPhone(getPlayerPosition(client));
|
||||
|
||||
if (!areParamsEmpty(params)) {
|
||||
payPhoneIndex = getPayPhoneFromParams(params);
|
||||
}
|
||||
|
||||
if (payPhoneIndex == -1) {
|
||||
messagePlayerError(client, getLocaleString(client, "InvalidPayPhone"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getPayPhoneData(payPhoneIndex) == false) {
|
||||
messagePlayerError(client, getLocaleString(client, "InvalidPayPhone"));
|
||||
return false;
|
||||
}
|
||||
|
||||
messagePlayerInfo(client, getLocaleString(client, "PayPhoneDeleted", getPayPhoneData(payPhoneIndex).number));
|
||||
|
||||
// Alert player using the phone, if any
|
||||
if (getPayPhoneData(payPhoneIndex).usingPlayer != false) {
|
||||
messagePlayerAlert(client, getLocaleString(client, "UsingPayPhoneDeleted"));
|
||||
}
|
||||
|
||||
// Alert player on the other end of the call, if any
|
||||
if (getPayPhoneData(payPhoneIndex).connectedPlayer != false) {
|
||||
messagePlayerNormal(getPayPhoneData(payPhoneIndex).connectedPlayer, getLocaleString("PayPhoneRecipientHangup", "0"));
|
||||
}
|
||||
|
||||
stopUsingPayPhone(getPayPhoneData(payPhoneIndex).usingPlayer);
|
||||
stopUsingPayPhone(getPayPhoneData(payPhoneIndex).connectedPlayer);
|
||||
|
||||
quickDatabaseQuery(`UPDATE payphone_main SET payphone_deleted = 1, payphone_who_deleted = ${getPlayerData(client).accountData.databaseId}, payphone_when_deleted = UNIX_TIMESTAMP() WHERE payphone_id = ${getPayPhoneData(payPhoneIndex).databaseId}`);
|
||||
|
||||
getServerData().payPhones.splice(payPhoneIndex, 1);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function callPayPhoneCommand(command, params, client) {
|
||||
if (areParamsEmpty(params)) {
|
||||
messagePlayerSyntax(client, getCommandSyntaxText(command));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getPlayerData(client).usingPayPhone != -1) {
|
||||
messagePlayerError(client, getLocaleString(client, "AlreadyUsingPayPhone"));
|
||||
return false;
|
||||
}
|
||||
|
||||
let closestPayPhone = getClosestPayPhone(getPlayerPosition(client));
|
||||
|
||||
if (closestPayPhone == -1) {
|
||||
messagePlayerError(client, getLocaleString(client, "NoPayPhoneCloseEnough"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getDistance(getPlayerPosition(client), getPayPhoneData(closestPayPhone).position) > getGlobalConfig().payPhoneAnswerDistance) {
|
||||
messagePlayerError(client, getLocaleString(client, "NoPayPhoneCloseEnough"));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Will work on dual number/player calling param later
|
||||
//let targetRecipient = getPayPhoneRecipientFromParams(params);
|
||||
|
||||
let targetClient = getPlayerFromParams(params);
|
||||
|
||||
if (!targetClient) {
|
||||
messagePlayerError(client, getLocaleString(client, "InvalidPlayer"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getPlayerData(targetClient).usingPayPhone != -1 || isPlayerRestrained(targetClient) || isPlayerSurrendered(targetClient) || isPlayerMuted(targetClient) || !isPlayerSpawned(targetClient)) {
|
||||
messagePlayerError(client, getLocaleString(client, "UnableToCallPlayer"));
|
||||
return false;
|
||||
}
|
||||
|
||||
let closestPayPhoneTarget = getClosestPayPhone(getPlayerPosition(targetClient));
|
||||
|
||||
if (closestPayPhoneTarget == closestPayPhone) {
|
||||
messagePlayerError(client, getLocaleString(client, "UnableToCallPlayer"));
|
||||
return false;
|
||||
}
|
||||
|
||||
getPayPhoneData(closestPayPhone).state = V_PAYPHONE_STATE_CALLING;
|
||||
getPayPhoneData(closestPayPhone).usingPlayer = client;
|
||||
|
||||
sendPayPhonePickupToPlayer(client);
|
||||
|
||||
let nearbyPlayers = getPlayersInRange(getPlayerPosition(client), 3);
|
||||
for (let i in nearbyPlayers) {
|
||||
sendPayPhonePickupToPlayer(nearbyPlayers[i]);
|
||||
}
|
||||
|
||||
setTimeout(function () {
|
||||
for (let i in nearbyPlayers) {
|
||||
sendPayPhoneDialingToPlayer(nearbyPlayers[i]);
|
||||
}
|
||||
setTimeout(function () {
|
||||
getPayPhoneData(closestPayPhoneTarget).state = V_PAYPHONE_STATE_RINGING;
|
||||
getPayPhoneData(closestPayPhoneTarget).usingPlayer = client;
|
||||
getPayPhoneData(closestPayPhoneTarget).otherPayPhone = closestPayPhone;
|
||||
getPayPhoneData(closestPayPhone).otherPayPhone = closestPayPhoneTarget;
|
||||
|
||||
getPlayerData(client).usingPayPhone = closestPayPhone;
|
||||
|
||||
sendPayPhoneStateToPlayer(null, closestPayPhone, V_PAYPHONE_STATE_CALLING);
|
||||
sendPayPhoneStateToPlayer(null, closestPayPhoneTarget, V_PAYPHONE_STATE_RINGING);
|
||||
}, 6000);
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function givePayPhoneToPlayerCommand(command, params, client) {
|
||||
if (getPlayerData(client).usingPayPhone == -1) {
|
||||
messagePlayerError(client, "NotUsingPayPhone");
|
||||
return false;
|
||||
}
|
||||
|
||||
let targetClient = getPlayerFromParams(params);
|
||||
|
||||
if (!targetClient) {
|
||||
messagePlayerError(client, getLocaleString(client, "InvalidPlayer"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getDistance(getPlayerPosition(client), getPlayerPosition(targetClient)) >= getGlobalConfig().payPhoneGiveDistance) {
|
||||
messagePlayerError(client, getLocaleString(client, "NoPlayerCloseEnough"))
|
||||
return false;
|
||||
}
|
||||
|
||||
let otherClient = getPlayerData(client).payPhoneOtherPlayer;
|
||||
messagePlayerAlert(otherClient, getLocaleString(otherClient, "PayPhoneOccupantSwitched"));
|
||||
messagePlayerAlert(targetClient, getLocaleString(targetClient, "PayPhoneReceived", `{ALTCOLOUR}${getCharacterFullName(targetClient)}{MAINCOLOUR}`));
|
||||
messagePlayerSuccess(client, getLocaleString(client, "PayPhoneGiven", `{ALTCOLOUR}${getCharacterFullName(targetClient)}{MAINCOLOUR}`));
|
||||
|
||||
getPlayerData(targetClient).payPhoneCallStart = getPlayerData(client).payPhoneCallStart;
|
||||
getPlayerData(targetClient).payPhoneOtherPlayer = otherClient;
|
||||
getPlayerData(targetClient).usingPayPhone = getPlayerData(client).usingPayPhone;
|
||||
getPlayerData(targetClient).payPhoneInitiatedCall = getPlayerData(client).payPhoneInitiatedCall;
|
||||
|
||||
getPlayerData(client).payPhoneCallStart = 0;
|
||||
getPlayerData(client).payPhoneOtherPlayer = null;
|
||||
getPlayerData(client).usingPayPhone = -1;
|
||||
getPlayerData(client).payPhoneInitiatedCall = false;
|
||||
|
||||
getPlayerData(otherClient).payPhoneCallStart = getCurrentUnixTimestamp();
|
||||
getPlayerData(otherClient).payPhoneOtherPlayer = targetClient;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function answerPayPhoneCommand(command, params, client) {
|
||||
//if (areParamsEmpty(params)) {
|
||||
// messagePlayerSyntax(client, getCommandSyntaxText(command));
|
||||
// return false;
|
||||
//}
|
||||
|
||||
if (getPlayerData(client).usingPayPhone != -1) {
|
||||
messagePlayerError(client, getLocaleString(client, "AlreadyUsingPayPhone"));
|
||||
return false;
|
||||
}
|
||||
|
||||
let closestPayPhone = getClosestPayPhone(getPlayerPosition(client));
|
||||
|
||||
if (getDistance(getPlayerPosition(client), getPayPhoneData(closestPayPhone).position) > getGlobalConfig().payPhoneAnswerDistance) {
|
||||
messagePlayerError(client, getLocaleString(client, "NoPayPhoneCloseEnough"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getPayPhoneData(closestPayPhone).state != V_PAYPHONE_STATE_RINGING) {
|
||||
messagePlayerError(client, getLocaleString(client, "PayPhoneNotRinging"));
|
||||
return false;
|
||||
}
|
||||
|
||||
let otherClient = getPayPhoneData(closestPayPhone).usingPlayer;
|
||||
messagePlayerAlert(otherClient, getLocaleString(client, "PayPhoneRecipientAnswered"));
|
||||
messagePlayerNormal(client, getLocaleString(client, "PayPhoneAnswered"));
|
||||
|
||||
getPlayerData(client).payPhoneCallStart = getCurrentUnixTimestamp();
|
||||
getPlayerData(client).payPhoneOtherPlayer = otherClient;
|
||||
getPlayerData(client).usingPayPhone = closestPayPhone;
|
||||
getPlayerData(otherClient).payPhoneCallStart = getCurrentUnixTimestamp();
|
||||
getPlayerData(otherClient).payPhoneOtherPlayer = client;
|
||||
|
||||
getPayPhoneData(closestPayPhone).state = V_PAYPHONE_STATE_ACTIVE_CALL;
|
||||
getPayPhoneData(closestPayPhone).usingPlayer = client;
|
||||
getPayPhoneData(getPlayerData(otherClient).usingPayPhone).state = V_PAYPHONE_STATE_ACTIVE_CALL;
|
||||
|
||||
sendPayPhoneStateToPlayer(null, closestPayPhone, V_PAYPHONE_STATE_ACTIVE_CALL);
|
||||
sendPayPhoneStateToPlayer(null, getPlayerData(otherClient).usingPayPhone, V_PAYPHONE_STATE_ACTIVE_CALL);
|
||||
|
||||
let nearbyPlayers = getPlayersInRange(getPlayerPosition(client), 3);
|
||||
for (let i in nearbyPlayers) {
|
||||
sendPayPhonePickupToPlayer(nearbyPlayers[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function hangupPayPhoneCommand(command, params, client) {
|
||||
//if (areParamsEmpty(params)) {
|
||||
// messagePlayerSyntax(client, getCommandSyntaxText(command));
|
||||
// return false;
|
||||
//}
|
||||
|
||||
if (getPlayerData(client).usingPayPhone == -1) {
|
||||
messagePlayerError(client, getLocaleString(client, "NotUsingPayPhone"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getPayPhoneData(getPlayerData(client).usingPayPhone) == false) {
|
||||
getPlayerData(client).usingPayPhone = -1
|
||||
messagePlayerError(client, getLocaleString(client, "InvalidPayPhone"));
|
||||
return false;
|
||||
}
|
||||
|
||||
let clientPayPhoneIndex = getPlayerData(client).usingPayPhone;
|
||||
let clientPayPhone = getPayPhoneData(clientPayPhoneIndex);
|
||||
|
||||
if (clientPayPhone.state == V_PAYPHONE_STATE_CALLING) {
|
||||
clientPayPhone.state = V_PAYPHONE_STATE_IDLE;
|
||||
clientPayPhone.usingPlayer = null;
|
||||
clientPayPhone.otherPayPhone = -1;
|
||||
|
||||
sendPayPhoneStateToPlayer(null, clientPayPhoneIndex, V_PAYPHONE_STATE_IDLE);
|
||||
|
||||
let otherPayPhoneIndex = getPayPhoneUsedByPlayer(client);
|
||||
if (clientPayPhoneIndex != otherPayPhoneIndex) {
|
||||
getPayPhoneData(otherPayPhoneIndex).state = V_PAYPHONE_STATE_IDLE;
|
||||
getPayPhoneData(otherPayPhoneIndex).usingPlayer = null;
|
||||
getPayPhoneData(otherPayPhoneIndex).otherPayPhone = -1;
|
||||
|
||||
sendPayPhoneStateToPlayer(null, otherPayPhoneIndex, V_PAYPHONE_STATE_IDLE);
|
||||
|
||||
let nearbyPlayers = getPlayersInRange(getPlayerPosition(client), 3);
|
||||
for (let i in nearbyPlayers) {
|
||||
sendPayPhoneHangupToPlayer(nearbyPlayers[i]);
|
||||
}
|
||||
}
|
||||
} else if (clientPayPhone.state == V_PAYPHONE_STATE_ACTIVE_CALL) {
|
||||
let otherClient = getPlayerData(client).payPhoneOtherPlayer;
|
||||
let otherClientPayPhoneIndex = getPlayerData(otherClient).usingPayPhone;
|
||||
let otherClientPayPhone = getPayPhoneData(otherClientPayPhoneIndex);
|
||||
|
||||
if (getPlayerData(client).payPhoneInitiatedCall == true) {
|
||||
messagePlayerNormal(client, getLocaleString(client, "PayPhoneRecipientHangup", getPayPhoneCallPrice(clientPayPhoneIndex, getCurrentUnixTimestamp() - getPlayerData(client).payPhoneCallStart)));
|
||||
takePlayerCash(client, getPayPhoneCallPrice(getCurrentUnixTimestamp() - getPlayerData(client).payPhoneCallStart));
|
||||
messagePlayerAlert(otherClient, getLocaleString(client, "PayPhoneHangup"));
|
||||
|
||||
let nearbyPlayers = getPlayersInRange(getPlayerPosition(client), 3);
|
||||
for (let i in nearbyPlayers) {
|
||||
sendPayPhoneHangupToPlayer(nearbyPlayers[i]);
|
||||
}
|
||||
|
||||
nearbyPlayers = getPlayersInRange(getPlayerPosition(otherClient), 3);
|
||||
for (let i in nearbyPlayers) {
|
||||
sendPayPhoneHangupToPlayer(nearbyPlayers[i]);
|
||||
}
|
||||
} else {
|
||||
messagePlayerNormal(otherClient, getLocaleString(client, "PayPhoneRecipientHangup", getPayPhoneCallPrice(otherClientPayPhoneIndex, getCurrentUnixTimestamp() - getPlayerData(client).payPhoneCallStart)));
|
||||
takePlayerCash(otherClient, getPayPhoneCallPrice(getCurrentUnixTimestamp() - getPlayerData(client).payPhoneCallStart));
|
||||
messagePlayerAlert(client, getLocaleString(client, "PayPhoneHangup"));
|
||||
}
|
||||
|
||||
clientPayPhone.state = V_PAYPHONE_STATE_IDLE;
|
||||
clientPayPhone.otherPayPhone = -1;
|
||||
otherClientPayPhone.state = V_PAYPHONE_STATE_IDLE;
|
||||
otherClientPayPhone.otherPayPhone = -1;
|
||||
|
||||
sendPayPhoneStateToPlayer(null, clientPayPhone, V_PAYPHONE_STATE_IDLE);
|
||||
sendPayPhoneStateToPlayer(null, otherClientPayPhone, V_PAYPHONE_STATE_IDLE);
|
||||
|
||||
getPlayerData(otherClient).payPhoneCallStart = 0;
|
||||
getPlayerData(otherClient).payPhoneOtherPlayer = null;
|
||||
getPlayerData(otherClient).usingPayPhone = -1;
|
||||
}
|
||||
|
||||
getPlayerData(client).payPhoneCallStart = 0
|
||||
getPlayerData(client).payPhoneOtherPlayer = null;
|
||||
getPlayerData(client).usingPayPhone = -1;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function loadPayPhonesFromDatabase() {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.PayPhone]: Loading payphones from database ...`);
|
||||
let dbConnection = connectToDatabase();
|
||||
let tempPayPhones = [];
|
||||
let dbAssoc = [];
|
||||
if (dbConnection) {
|
||||
let dbQueryString = `SELECT * FROM payphone_main WHERE payphone_server = ${getServerId()} AND payphone_enabled = 1`;
|
||||
dbAssoc = fetchQueryAssoc(dbConnection, dbQueryString);
|
||||
if (dbAssoc.length > 0) {
|
||||
for (let i in dbAssoc) {
|
||||
let tempPayPhoneData = new PayPhoneData(dbAssoc[i]);
|
||||
tempPayPhones.push(tempPayPhoneData);
|
||||
}
|
||||
}
|
||||
disconnectFromDatabase(dbConnection);
|
||||
}
|
||||
|
||||
logToConsole(LOG_DEBUG, `[V.RP.PayPhone]: ${tempPayPhones.length} payphones loaded from database successfully!`);
|
||||
return tempPayPhones;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function saveAllPayPhonesToDatabase() {
|
||||
if (getServerConfig().devServer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i in getServerData().payPhones) {
|
||||
savePayPhoneToDatabase(i);
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function savePayPhoneToDatabase(payPhoneIndex) {
|
||||
if (getServerConfig().devServer) {
|
||||
logToConsole(LOG_VERBOSE, `[V.RP.PayPhone]: Payphone ${payPhoneIndex} can't be saved because server is running as developer only. Aborting save ...`);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getPayPhoneData(payPhoneIndex) == false) {
|
||||
logToConsole(LOG_VERBOSE, `[V.RP.PayPhone]: Payphone ${payPhoneIndex} data is invalid. Aborting save ...`);
|
||||
return false;
|
||||
}
|
||||
|
||||
let tempPayPhoneData = getPayPhoneData(payPhoneIndex);
|
||||
|
||||
if (tempPayPhoneData.databaseId == -1) {
|
||||
logToConsole(LOG_VERBOSE, `[V.RP.PayPhone]: Payphone ${payPhoneIndex} is a temp payphone. Aborting save ...`);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!tempPayPhoneData.needsSaved) {
|
||||
logToConsole(LOG_VERBOSE, `[V.RP.PayPhone]: Payphone ${payPhoneIndex} hasn't changed data. Aborting save ...`);
|
||||
return false;
|
||||
}
|
||||
|
||||
logToConsole(LOG_VERBOSE, `[V.RP.PayPhone]: Saving payphone ${tempPayPhoneData.databaseId} to database ...`);
|
||||
let dbConnection = connectToDatabase();
|
||||
if (dbConnection) {
|
||||
let data = [
|
||||
["payphone_server", getServerId()],
|
||||
["payphone_number", toInteger(tempPayPhoneData.number)],
|
||||
["payphone_enabled", boolToInt(tempPayPhoneData.enabled)],
|
||||
["payphone_price", toInteger(tempPayPhoneData.price)],
|
||||
["payphone_who_added", toInteger(tempPayPhoneData.whoAdded)],
|
||||
["payphone_when_added", toInteger(tempPayPhoneData.whenAdded)],
|
||||
["payphone_pos_x", toFloat(tempPayPhoneData.position.x)],
|
||||
["payphone_pos_y", toFloat(tempPayPhoneData.position.y)],
|
||||
["payphone_pos_z", toFloat(tempPayPhoneData.position.z)],
|
||||
];
|
||||
|
||||
let dbQuery = null;
|
||||
if (tempPayPhoneData.databaseId == 0) {
|
||||
let queryString = createDatabaseInsertQuery("payphone_main", data);
|
||||
dbQuery = queryDatabase(dbConnection, queryString);
|
||||
tempPayPhoneData.databaseId = getDatabaseInsertId(dbConnection);
|
||||
tempPayPhoneData.needsSaved = false;
|
||||
} else {
|
||||
let queryString = createDatabaseUpdateQuery("payphone_main", data, `payphone_id=${tempPayPhoneData.databaseId}`);
|
||||
dbQuery = queryDatabase(dbConnection, queryString);
|
||||
getPayPhoneData(payPhoneIndex).needsSaved = false;
|
||||
}
|
||||
|
||||
logToConsole(LOG_VERBOSE, `[V.RP.PayPhone]: Saved payphone ${payPhoneIndex} to database!`);
|
||||
|
||||
freeDatabaseQuery(dbQuery);
|
||||
disconnectFromDatabase(dbConnection);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function setAllPayPhoneIndexes() {
|
||||
for (let i in getServerData().payPhones) {
|
||||
getServerData().payPhones[i].index = i;
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function getPayPhoneCallPrice(payPhoneIndex, durationSeconds) {
|
||||
// Charge price for every 10 seconds
|
||||
return getPayPhoneData(payPhoneIndex).price * Math.ceil(durationSeconds / 10);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function getPayPhoneUsedByPlayer(client) {
|
||||
for (let i in getServerData().payPhones) {
|
||||
if (getServerData().payPhones[i].usingPlayer) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function getNearbyPayPhonesCommand(command, params, client) {
|
||||
let distance = 10.0;
|
||||
|
||||
if (!areParamsEmpty(params)) {
|
||||
distance = getParam(params, " ", 1);
|
||||
}
|
||||
|
||||
if (isNaN(distance)) {
|
||||
messagePlayerError(client, "The distance must be a number!");
|
||||
return false;
|
||||
}
|
||||
|
||||
distance = toFloat(distance);
|
||||
|
||||
if (distance <= 0) {
|
||||
messagePlayerError(client, "The distance must be more than 0!");
|
||||
return false;
|
||||
}
|
||||
|
||||
let nearbyPayPhones = getPayPhonesInRange(getPlayerPosition(client), distance);
|
||||
|
||||
if (nearbyPayPhones.length == 0) {
|
||||
messagePlayerAlert(client, getLocaleString(client, "NoPayPhonesWithinRange", distance));
|
||||
return false;
|
||||
}
|
||||
|
||||
let payPhonesList = nearbyPayPhones.map(function (x) {
|
||||
return `{chatBoxListIndex}${x.index}: {MAINCOLOUR}${x.number} {mediumGrey}(${toFloat(getDistance(getPlayerPosition(client), x.position)).toFixed(2)} ${toLowerCase(getLocaleString(client, "Meters"))} ${toLowerCase(getGroupedLocaleString(client, "CardinalDirections", getCardinalDirectionName(getCardinalDirection(getPlayerPosition(client), x.position))))})`;
|
||||
});
|
||||
let chunkedList = splitArrayIntoChunks(payPhonesList, 4);
|
||||
|
||||
messagePlayerNormal(client, makeChatBoxSectionHeader(getLocaleString(client, "HeaderPayPhonesInRangeList", `${distance} ${toLowerCase(getLocaleString(client, "Meters"))}`)));
|
||||
for (let i in chunkedList) {
|
||||
messagePlayerInfo(client, chunkedList[i].join(", "));
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function getPayPhonesInRange(position, distance) {
|
||||
return getServerData().payPhones.filter((payPhone) => getDistance(position, payPhone.position) <= distance);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function stopUsingPayPhone(client) {
|
||||
if (client == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getPlayerData(client) == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getPlayerData(client).usingPayPhone == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
getPayPhoneData(getPlayerData(client).usingPayPhone).state = V_PAYPHONE_STATE_IDLE;
|
||||
sendPayPhoneStateToPlayer(client, getPlayerData(client).usingPayPhone, V_PAYPHONE_STATE_IDLE);
|
||||
|
||||
getPlayerData(client).payPhoneCallStart = 0
|
||||
getPlayerData(client).payPhoneOtherPlayer = null;
|
||||
getPlayerData(client).usingPayPhone = -1;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
/**
|
||||
* This is a command handler function.
|
||||
*
|
||||
* @param {string} command - The command name used by the player
|
||||
* @param {string} params - The parameters/args string used with the command by the player
|
||||
* @param {Client} client - The client/player that used the command
|
||||
* @return {bool} Whether or not the command was successful
|
||||
*
|
||||
*/
|
||||
function getPayPhoneInfoCommand(command, params, client) {
|
||||
let payPhoneIndex = getClosestPayPhone(getPlayerPosition(client));
|
||||
|
||||
if (!areParamsEmpty(params)) {
|
||||
payPhoneIndex = getPayPhoneFromParams(params);
|
||||
}
|
||||
|
||||
if (!getPayPhoneData(payPhoneIndex)) {
|
||||
messagePlayerError(client, getLocaleString(client, "InvalidPayPhone"));
|
||||
return false;
|
||||
}
|
||||
|
||||
let payPhoneData = getPayPhoneData(payPhoneIndex);
|
||||
|
||||
let tempStats = [
|
||||
[`ID`, `${payPhoneData.index}/${payPhoneData.databaseId}`],
|
||||
[`Number`, `${payPhoneData.number}`],
|
||||
[`State`, `${getPayPhoneStateName(payPhoneData.state)}`],
|
||||
[`Added By`, `${loadAccountFromId(payPhoneData.whoAdded).name} on ${new Date(payPhoneData.whenAdded * 1000).toLocaleString()}`],
|
||||
];
|
||||
|
||||
let stats = tempStats.map(stat => `{MAINCOLOUR}${stat[0]}: {ALTCOLOUR}${stat[1]}{MAINCOLOUR}`);
|
||||
|
||||
messagePlayerNormal(client, makeChatBoxSectionHeader(getLocaleString(client, "HeaderPayPhoneInfo", payPhoneData.number)));
|
||||
let chunkedList = splitArrayIntoChunks(stats, 6);
|
||||
for (let i in chunkedList) {
|
||||
messagePlayerInfo(client, chunkedList[i].join(", "));
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function resetAllPayPhonesCommand(command, params, client) {
|
||||
resetAllPayPhones();
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function resetAllPayPhones() {
|
||||
for (let i in getServerData().payPhones) {
|
||||
if (getServerData().payPhones[i].usingPlayer != null) {
|
||||
getPlayerData(getServerData().payPhones[i].usingPlayer).usingPayPhone = -1;
|
||||
getPlayerData(getServerData().payPhones[i].usingPlayer).payPhoneCallStart = 0;
|
||||
getPlayerData(getServerData().payPhones[i].usingPlayer).payPhoneInitiatedCall = false;
|
||||
getPlayerData(getServerData().payPhones[i].usingPlayer).payPhoneOtherPlayer = null;
|
||||
}
|
||||
getServerData().payPhones[i].state = V_PAYPHONE_STATE_IDLE;
|
||||
}
|
||||
|
||||
sendPayPhoneStateToPlayer(null, -1, V_PAYPHONE_STATE_IDLE);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function fixDesyncedPayPhones() {
|
||||
for (let i in getServerData().payPhones) {
|
||||
switch (getServerData().payPhones[i].state) {
|
||||
case V_PAYPHONE_STATE_RINGING:
|
||||
if (getPayPhoneData(i).otherPayPhone != -1) {
|
||||
if (getPayPhoneData(getPayPhoneData(i).otherPayPhone).state != V_PAYPHONE_STATE_CALLING) {
|
||||
if (getServerData().payPhones[i].usingPlayer != null) {
|
||||
getPlayerData(getServerData().payPhones[i].usingPlayer).usingPayPhone = -1;
|
||||
getPlayerData(getServerData().payPhones[i].usingPlayer).payPhoneCallStart = 0;
|
||||
getPlayerData(getServerData().payPhones[i].usingPlayer).payPhoneInitiatedCall = false;
|
||||
getPlayerData(getServerData().payPhones[i].usingPlayer).payPhoneOtherPlayer = null;
|
||||
}
|
||||
getPayPhoneData(i).otherPayPhone = -1;
|
||||
setPayPhoneState(i, V_PAYPHONE_STATE_IDLE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function setPayPhoneState(payPhoneIndex, state) {
|
||||
getPayPhoneData(payPhoneIndex).state = state;
|
||||
sendPayPhoneStateToPlayer(null, payPhoneIndex, state);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -17,6 +17,9 @@ const V_PROMPT_GIVEHOUSETOCLAN = 5;
|
||||
const V_PROMPT_BUYBIZ = 6;
|
||||
const V_PROMPT_BUYHOUSE = 7;
|
||||
const V_PROMPT_RESETKEYBINDS = 8;
|
||||
const V_PROMPT_RESETACTIONTIPS = 9;
|
||||
const V_PROMPT_JOBINVITE = 10;
|
||||
const V_PROMPT_CLANINVITE = 11;
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
@@ -43,16 +46,7 @@ function playerPromptAnswerNo(client) {
|
||||
break;
|
||||
|
||||
case V_PROMPT_BIZORDER:
|
||||
if (getPlayerData(client).businessOrderAmount > 0) {
|
||||
if (doesPlayerUseGUI(client)) {
|
||||
showPlayerErrorGUI(client, getLocaleString(client, "BusinessOrderCanceled"), getLocaleString(client, "GUIWarning"));
|
||||
} else {
|
||||
logToConsole(LOG_DEBUG, `${getPlayerDisplayForConsole(client)} canceled the order of ${getPlayerData(client).businessOrderAmount} ${getPlayerData(client).businessOrderItem} at ${getPlayerData(client).businessOrderCost / getPlayerData(client).businessOrderAmount} each for business ${getBusinessData(getPlayerData(client).businessOrderBusiness)}`);
|
||||
messagePlayerError(client, getLocaleString(client, "BusinessOrderCanceled"));
|
||||
}
|
||||
} else {
|
||||
showPlayerErrorGUI(client, getLocaleString(client, "NotOrderingAnyBusinessItems"), getLocaleString(client, getLocaleString(client, "GUIWarningTitle")));
|
||||
}
|
||||
showPlayerError(client, getLocaleString(client, "BusinessOrderCanceled"), getLocaleString(client, "GUIWarningTitle"));
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -83,19 +77,14 @@ function playerPromptAnswerYes(client) {
|
||||
if (getPlayerData(client).businessOrderAmount > 0) {
|
||||
if (getBusinessData(getPlayerData(client).businessOrderBusiness).till < getPlayerData(client).businessOrderCost) {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Prompt] ${getPlayerDisplayForConsole(client)} failed to order ${getPlayerData(client).businessOrderAmount} ${getItemTypeData(getPlayerData(client).businessOrderItem).name} at ${getPlayerData(client).businessOrderCost / getPlayerData(client).businessOrderAmount} each for business ${getBusinessData(getPlayerData(client).businessOrderBusiness).name} (Reason: Not enough money in business till)`);
|
||||
if (doesPlayerHaveGUIEnabled(client)) {
|
||||
showPlayerErrorGUI(client, getLocaleString(client, "BusinessOrderNotEnoughMoney", `{ALTCOLOUR}/bizdeposit{MAINCOLOUR}`), getLocaleString(client, "BusinessOrderCanceled"));
|
||||
} else {
|
||||
messagePlayerError(client, getLocaleString(client, "BusinessOrderNotEnoughMoney", `{ALTCOLOUR}/bizdeposit{MAINCOLOUR}`));
|
||||
}
|
||||
showPlayerError(client, getLocaleString(client, "BusinessOrderNotEnoughMoney", `{ALTCOLOUR}/bizdeposit{MAINCOLOUR}`), getLocaleString(client, "BusinessOrderCanceled"));
|
||||
getPlayerData(client).businessOrderAmount = 0;
|
||||
getPlayerData(client).businessOrderBusiness = false;
|
||||
getPlayerData(client).businessOrderItem = -1;
|
||||
getPlayerData(client).businessOrderValue = -1;
|
||||
} else {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Prompt] ${getPlayerDisplayForConsole(client)} successfully ordered ${getPlayerData(client).businessOrderAmount} ${getItemTypeData(getPlayerData(client).businessOrderItem).name} at ${getPlayerData(client).businessOrderCost / getPlayerData(client).businessOrderAmount} each for business ${getBusinessData(getPlayerData(client).businessOrderBusiness).name}`);
|
||||
|
||||
showPlayerInfoGUI(client, getLocaleString(client, "BusinessOrderSuccessInfo", getPlayerData(client).businessOrderAmount, getItemTypeData(getPlayerData(client).businessOrderItem).name, getItemValueDisplay(getPlayerData(client).businessOrderItem, getPlayerData(client).businessOrderValue), getPlayerData(client).businessOrderCost), getLocaleString(client, "GUIInfoTitle"));
|
||||
showPlayerInfo(client, getLocaleString(client, "BusinessOrderSuccessInfo", getPlayerData(client).businessOrderAmount, getItemTypeData(getPlayerData(client).businessOrderItem).name, getItemValueDisplay(getPlayerData(client).businessOrderItem, getPlayerData(client).businessOrderValue), getPlayerData(client).businessOrderCost), getLocaleString(client, "GUIInfoTitle"));
|
||||
createItem(getPlayerData(client).businessOrderItem, getPlayerData(client).businessOrderValue, V_ITEM_OWNER_BIZFLOOR, getBusinessData(getPlayerData(client).businessOrderBusiness).databaseId, getPlayerData(client).businessOrderAmount);
|
||||
cacheBusinessItems(getPlayerData(client).businessOrderBusiness);
|
||||
getBusinessData(getPlayerData(client).businessOrderBusiness).till -= getPlayerData(client).businessOrderCost;
|
||||
@@ -106,7 +95,7 @@ function playerPromptAnswerYes(client) {
|
||||
getPlayerData(client).businessOrderValue = -1;
|
||||
}
|
||||
} else {
|
||||
showPlayerErrorGUI(client, ``, `Business Order Canceled`);
|
||||
showPlayerError(client, getLocaleString(client, "BusinessOrderCanceled"), getLocaleString(client, "GUIWarningTitle"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -232,12 +221,13 @@ function playerPromptAnswerYes(client) {
|
||||
return false;
|
||||
}
|
||||
|
||||
takePlayerCash(client, getBusinessData(businessId).buyPrice);
|
||||
getBusinessData(businessId).ownerType = V_BIZ_OWNER_PLAYER;
|
||||
getBusinessData(businessId).ownerId = getPlayerCurrentSubAccount(client).databaseId;
|
||||
getBusinessData(businessId).buyPrice = 0;
|
||||
getBusinessData(businessId).needsSaved = true;
|
||||
|
||||
updateBusinessPickupLabelData(businessId);
|
||||
takePlayerCash(client, getBusinessData(businessId).buyPrice);
|
||||
|
||||
messageDiscordEventChannel(`🏢 ${getCharacterFullName(client)} is now the owner of *${getBusinessData(businessId).name}*!`);
|
||||
messagePlayerSuccess(client, getLocaleString(client, "BusinessPurchased", `{businessBlue}${getBusinessData(businessId).name}{MAINCOLOUR}`));
|
||||
@@ -269,6 +259,20 @@ function playerPromptAnswerYes(client) {
|
||||
break;
|
||||
}
|
||||
|
||||
case V_PROMPT_RESETACTIONTIPS: {
|
||||
getPlayerData(client).accountData.seenActionTips = 0;
|
||||
messagePlayerSuccess(client, getLocaleString(client, "ActionTipsReset"));
|
||||
break;
|
||||
}
|
||||
|
||||
case V_PROMPT_CLANINVITE: {
|
||||
break;
|
||||
}
|
||||
|
||||
case V_PROMPT_JOBINVITE: {
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
messagePlayerError(client, getLocaleString(client, "NoPromptAccept"));
|
||||
submitBugReport(client, `[AUTOMATED REPORT] Tried to accept invalid prompt type: ${getPlayerData(client).promptType}`);
|
||||
|
||||
@@ -7,4 +7,4 @@
|
||||
// TYPE: Server (JavaScript)
|
||||
// ===========================================================================
|
||||
|
||||
let accountSaltHash = "FGjD49yWqMrW";
|
||||
// This stuff is in other places, depending on type. I'll probably remove this file soon.
|
||||
@@ -393,24 +393,37 @@ function getVehicleCommand(command, params, client) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (typeof getServerData().vehicles[toInteger(params) - 1] == "undefined") {
|
||||
let vehicleIndex = toInteger(params);
|
||||
|
||||
if (typeof getServerData().vehicles[vehicleIndex] == "undefined") {
|
||||
messagePlayerError(client, "That vehicle ID doesn't exist!");
|
||||
}
|
||||
|
||||
let vehicle = getServerData().vehicles[toInteger(params) - 1].vehicle;
|
||||
destroyGameElement(getServerData().vehicles[vehicleIndex]);
|
||||
getServerData().vehicles[vehicleIndex].vehicle = null;
|
||||
|
||||
let oldStreamInDistance = getElementStreamInDistance(vehicle);
|
||||
let oldStreamOutDistance = getElementStreamOutDistance(vehicle);
|
||||
getServerData().vehicles[vehicleIndex].spawnPosition = getPlayerPosition(client);
|
||||
getServerData().vehicles[vehicleIndex].spawnRotation = getPlayerHeading(client);
|
||||
|
||||
setElementStreamInDistance(vehicle, 9999999);
|
||||
setElementStreamOutDistance(vehicle, 9999999 + 1);
|
||||
//let oldStreamInDistance = getElementStreamInDistance(vehicle);
|
||||
//let oldStreamOutDistance = getElementStreamOutDistance(vehicle);
|
||||
|
||||
setElementPosition(vehicle, getPosInFrontOfPos(getPlayerPosition(client), fixAngle(getPlayerHeading(client)), 5.0));
|
||||
setElementInterior(vehicle, getPlayerInterior(client));
|
||||
setElementDimension(vehicle, getPlayerDimension(client));
|
||||
//setElementStreamInDistance(vehicle, 9999999);
|
||||
//setElementStreamOutDistance(vehicle, 9999999 + 1);
|
||||
|
||||
setElementStreamInDistance(vehicle, oldStreamInDistance);
|
||||
setElementStreamOutDistance(vehicle, oldStreamOutDistance);
|
||||
//setElementPosition(vehicle, getPosInFrontOfPos(getPlayerPosition(client), fixAngle(getPlayerHeading(client)), 5.0));
|
||||
//setElementInterior(vehicle, getPlayerInterior(client));
|
||||
//setElementDimension(vehicle, getPlayerDimension(client));
|
||||
|
||||
//setElementStreamInDistance(vehicle, oldStreamInDistance);
|
||||
//setElementStreamOutDistance(vehicle, oldStreamOutDistance);
|
||||
|
||||
let vehicle = spawnVehicle(getServerData().vehicles[vehicleIndex]);
|
||||
|
||||
if (getServerData().vehicles[vehicleIndex].vehicle == null) {
|
||||
messagePlayerError(client, "Vehicle could not be retrieved!");
|
||||
return false;
|
||||
}
|
||||
|
||||
messageAdmins(`{adminOrange}${getPlayerName(client)}{MAINCOLOUR} teleported a {vehiclePurple}${getVehicleName(vehicle)}{ALTCOLOUR} (ID ${vehicle.id}){MAINCOLOUR} to their position`, true);
|
||||
}
|
||||
@@ -1152,18 +1165,6 @@ function getPlayerStaffFlagsCommand(command, params, client) {
|
||||
*
|
||||
*/
|
||||
function getStaffFlagsCommand(command, params, client) {
|
||||
if (areParamsEmpty(params)) {
|
||||
messagePlayerSyntax(client, getCommandSyntaxText(command));
|
||||
return false;
|
||||
}
|
||||
|
||||
let targetClient = getParam(params, " ", 1);
|
||||
|
||||
if (!targetClient) {
|
||||
messagePlayerError(client, getLocaleString(client, "InvalidPlayer"));
|
||||
return false;
|
||||
}
|
||||
|
||||
let chunkedList = splitArrayIntoChunks(getServerBitFlagKeys().staffFlagKeys, 8);
|
||||
|
||||
messagePlayerInfo(client, makeChatBoxSectionHeader(getLocaleString(client, "HeaderStaffFlagsList")));
|
||||
@@ -1386,7 +1387,7 @@ function setPlayerStaffTitleCommand(command, params, client) {
|
||||
return false;
|
||||
}
|
||||
|
||||
getPlayerData(client).accountData.staffTitle = newTitle;
|
||||
getPlayerData(targetClient).accountData.staffTitle = newTitle;
|
||||
|
||||
messageAdmins(`{adminOrange}${getPlayerName(client)}{MAINCOLOUR} set ${getPlayerName(targetClient)}'s{MAINCOLOUR} staff title to {ALTCOLOUR}${newTitle}`);
|
||||
}
|
||||
@@ -1647,6 +1648,10 @@ function forceAccountPasswordResetCommand(command, params, client) {
|
||||
messagePlayerError(client, getLocaleString(client, "InvalidPlayer"));
|
||||
return false;
|
||||
}
|
||||
|
||||
getPlayerData(targetClient).passwordResetState = V_RESETPASS_STATE_SETPASS;
|
||||
hideAllPlayerGUI(targetClient);
|
||||
showPlayerChangePasswordGUI(targetClient);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -1910,4 +1915,77 @@ function showAccountStaffNotesCommand(command, params, client) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
/**
|
||||
* This is a command handler function.
|
||||
*
|
||||
* @param {string} command - The command name used by the player
|
||||
* @param {string} params - The parameters/args string used with the command by the player
|
||||
* @param {Client} client - The client/player that used the command
|
||||
* @return {bool} Whether or not the command was successful
|
||||
*
|
||||
*/
|
||||
function setServerDefaultChatTypeCommand(command, params, client) {
|
||||
if (areParamsEmpty(params)) {
|
||||
messagePlayerSyntax(client, getCommandSyntaxText(command));
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (toLowerCase(params)) {
|
||||
case "global":
|
||||
getServerConfig().normalChatType = V_CHAT_TYPE_GLOBAL;
|
||||
break;
|
||||
|
||||
case "local":
|
||||
getServerConfig().normalChatType = V_CHAT_TYPE_LOCAL;
|
||||
break;
|
||||
|
||||
case "talk":
|
||||
getServerConfig().normalChatType = V_CHAT_TYPE_TALK;
|
||||
break;
|
||||
|
||||
case "shout":
|
||||
getServerConfig().normalChatType = V_CHAT_TYPE_SHOUT;
|
||||
break;
|
||||
|
||||
case "whisper":
|
||||
getServerConfig().normalChatType = V_CHAT_TYPE_WHISPER;
|
||||
break;
|
||||
|
||||
case "none":
|
||||
getServerConfig().normalChatType = V_CHAT_TYPE_NONE;
|
||||
break;
|
||||
|
||||
default:
|
||||
messagePlayerError(client, "That chat type is invalid!")
|
||||
messagePlayerInfo(client, "Available chat types: global, local, talk, shout, whisper, none");
|
||||
messagePlayerInfo(client, "Global and local are out-of-character, the rest is in-character");
|
||||
break;
|
||||
}
|
||||
|
||||
messagePlayerSuccess(client, `You set the server's normal chat type to ${toLowerCase(params)}`);
|
||||
return true;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
/**
|
||||
* This is a command handler function.
|
||||
*
|
||||
* @param {string} command - The command name used by the player
|
||||
* @param {string} params - The parameters/args string used with the command by the player
|
||||
* @param {Client} client - The client/player that used the command
|
||||
* @return {bool} Whether or not the command was successful
|
||||
*
|
||||
*/
|
||||
function clearChatCommand(command, params, client) {
|
||||
if (areParamsEmpty(params)) {
|
||||
messagePlayerSyntax(client, getCommandSyntaxText(command));
|
||||
return false;
|
||||
}
|
||||
|
||||
clearChatBox(null);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -7,7 +7,8 @@
|
||||
// TYPE: Server (JavaScript)
|
||||
// ===========================================================================
|
||||
|
||||
async function initServerScripts() {
|
||||
function initServerScripts() {
|
||||
serverStarting = true;
|
||||
checkForAllRequiredModules();
|
||||
|
||||
initDatabaseScript();
|
||||
@@ -38,10 +39,11 @@ async function initServerScripts() {
|
||||
initRadioScript();
|
||||
initLocaleScript();
|
||||
initCommandScript();
|
||||
initPayPhoneScript();
|
||||
|
||||
// Load config and stuff
|
||||
loadGlobalConfig();
|
||||
await loadServerConfig();
|
||||
loadServerConfig();
|
||||
applyConfigToServer(getServerConfig());
|
||||
|
||||
// Load all the server data
|
||||
@@ -49,13 +51,14 @@ async function initServerScripts() {
|
||||
setAllServerDataIndexes();
|
||||
|
||||
checkServerGameTime();
|
||||
spawnAllServerElements();
|
||||
|
||||
addAllNetworkEventHandlers();
|
||||
addAllCommandHandlers();
|
||||
initAllClients();
|
||||
initTimers();
|
||||
|
||||
serverStartTime = getCurrentUnixTimestamp();
|
||||
serverStarting = false;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -150,6 +153,7 @@ function loadServerDataFromDatabase() {
|
||||
getServerData().radioStations = loadRadioStationsFromDatabase();
|
||||
getServerData().gates = loadGatesFromDatabase();
|
||||
getServerData().jobs = loadJobsFromDatabase();
|
||||
getServerData().payPhones = loadPayPhonesFromDatabase();
|
||||
}
|
||||
|
||||
getServerData().commands = loadCommands();
|
||||
@@ -167,6 +171,7 @@ function setAllServerDataIndexes() {
|
||||
setNPCDataIndexes();
|
||||
setAllRaceDataIndexes();
|
||||
setAllRadioStationIndexes();
|
||||
setAllPayPhoneIndexes();
|
||||
cacheAllGroundItems();
|
||||
cacheAllBusinessItems();
|
||||
cacheAllItemItems();
|
||||
@@ -193,6 +198,23 @@ function spawnAllServerElements() {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function despawnAllServerElements() {
|
||||
//despawnAllBusinessPickups();
|
||||
//despawnAllBusinessBlips();
|
||||
//despawnAllHousePickups();
|
||||
//despawnAllHouseBlips();
|
||||
//despawnAllJobPickups();
|
||||
//despawnAllJobBlips();
|
||||
//despawnAllGroundItemObjects();
|
||||
despawnAllVehicles();
|
||||
despawnAllNPCs();
|
||||
|
||||
// Using client-side spheres since server-side ones don't show on GTAC atm (bug)
|
||||
//createAllJobRouteLocationMarkers();
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
initServerScripts();
|
||||
|
||||
// ===========================================================================
|
||||
@@ -46,6 +46,8 @@ class SubAccountData {
|
||||
this.inHouse = 0;
|
||||
this.inBusiness = 0;
|
||||
this.accent = "";
|
||||
this.payDayAmount = 0;
|
||||
this.scene = "";
|
||||
|
||||
this.bodyParts = {
|
||||
hair: [0, 0],
|
||||
@@ -95,6 +97,8 @@ class SubAccountData {
|
||||
this.inHouse = toInteger(dbAssoc["sacct_inhouse"]);
|
||||
this.inBusiness = toInteger(dbAssoc["sacct_inbusiness"]);
|
||||
this.accent = toString(dbAssoc["sacct_accent"]);
|
||||
this.payDayAmount = toInteger(dbAssoc["sacct_svr_payday"]);
|
||||
this.scene = toString(dbAssoc["sacct_svr_scene"]);
|
||||
|
||||
this.bodyParts = {
|
||||
hair: [toInteger(dbAssoc["sacct_svr_hd_part_hair_model"]) || 0, toInteger(dbAssoc["sacct_svr_hd_part_hair_texture"]) || 0],
|
||||
@@ -166,6 +170,13 @@ function loadSubAccountFromId(subAccountId) {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
/**
|
||||
* Loads sub accounts (characters) by account ID
|
||||
*
|
||||
* @param {Number} accountId - The database ID of the account
|
||||
* @return {Array.<SubAccountData>} Array of subaccounts that belong to the account ID
|
||||
*
|
||||
*/
|
||||
function loadSubAccountsFromAccount(accountId) {
|
||||
let tempSubAccounts = [];
|
||||
let dbAssoc = false;
|
||||
@@ -246,6 +257,13 @@ function loadSubAccountsFromAccount(accountId) {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
/**
|
||||
* Saves the subaccount data to the database (character)
|
||||
*
|
||||
* @param {SubAccountData} subAccountData - The data of the subaccount
|
||||
* @return {void}
|
||||
*
|
||||
*/
|
||||
function saveSubAccountToDatabase(subAccountData) {
|
||||
let dbConnection = connectToDatabase();
|
||||
|
||||
@@ -284,7 +302,7 @@ function saveSubAccountToDatabase(subAccountData) {
|
||||
//["sacct_svr_svr", getServerId()],
|
||||
["sacct_svr_sacct", subAccountData.databaseId],
|
||||
["sacct_svr_job", subAccountData.job],
|
||||
//["sacct_svr_job_rank", getServerId()],
|
||||
["sacct_svr_job_rank", subAccountData.jobRank],
|
||||
["sacct_svr_clan", subAccountData.clan],
|
||||
["sacct_svr_clan_rank", subAccountData.clanRank],
|
||||
["sacct_svr_clan_tag", safeClanTag],
|
||||
@@ -324,6 +342,7 @@ function saveSubAccountToDatabase(subAccountData) {
|
||||
["sacct_svr_hd_prop_leftfoot_texture", subAccountData.bodyProps.leftFoot[1]],
|
||||
["sacct_svr_hd_prop_rightfoot_model", subAccountData.bodyProps.rightFoot[0]],
|
||||
["sacct_svr_hd_prop_rightfoot_texture", subAccountData.bodyProps.rightFoot[1]],
|
||||
["sacct_svr_payday", subAccountData.payDayAmount],
|
||||
];
|
||||
|
||||
dbQuery = null;
|
||||
@@ -338,6 +357,13 @@ function saveSubAccountToDatabase(subAccountData) {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
/**
|
||||
* Creates a new subaccount (character)
|
||||
*
|
||||
* @param {SubAccountData} subAccountData - The data of the subaccount
|
||||
* @return {SubAccountData} The new sub account data
|
||||
*
|
||||
*/
|
||||
function createSubAccount(accountId, firstName, lastName) {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Account] Attempting to create subaccount ${firstName} ${lastName} in database`);
|
||||
|
||||
@@ -515,6 +541,8 @@ function selectCharacter(client, characterId = -1) {
|
||||
//setPlayerCameraLookAt(client, getPosBehindPos(spawnPosition, spawnHeading, 5), spawnPosition);
|
||||
getPlayerData(client).pedState = V_PEDSTATE_SPAWNING;
|
||||
|
||||
getPlayerData(client).scene = getPlayerCurrentSubAccount(client).scene;
|
||||
|
||||
if (getGame() <= V_GAME_GTA_IV_EFLC) {
|
||||
spawnPlayer(client, spawnPosition, spawnHeading, getGameConfig().skins[getGame()][skin][0], spawnInterior, spawnDimension);
|
||||
onPlayerSpawn(client);
|
||||
@@ -725,7 +753,11 @@ function forcePlayerIntoSwitchCharacterScreen(client) {
|
||||
|
||||
getPlayerData(client).switchingCharacter = true;
|
||||
|
||||
showConnectCameraToPlayer(client);
|
||||
despawnPlayer(client);
|
||||
|
||||
if (getGame() != V_GAME_MAFIA_ONE) {
|
||||
showConnectCameraToPlayer(client);
|
||||
}
|
||||
|
||||
showCharacterSelectToClient(client);
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ function saveServerDataToDatabase() {
|
||||
}
|
||||
|
||||
try {
|
||||
updateVehicleSavedPositions();
|
||||
saveAllVehiclesToDatabase();
|
||||
} catch (error) {
|
||||
logToConsole(LOG_ERROR, `Could not save vehicles to database: ${error}`);
|
||||
@@ -78,6 +79,12 @@ function saveServerDataToDatabase() {
|
||||
logToConsole(LOG_ERROR, `Could not save gates to database: ${error}`);
|
||||
}
|
||||
|
||||
try {
|
||||
saveAllPayPhonesToDatabase();
|
||||
} catch (error) {
|
||||
logToConsole(LOG_ERROR, `Could not save payphones to database: ${error}`);
|
||||
}
|
||||
|
||||
try {
|
||||
saveServerConfigToDatabase();
|
||||
} catch (error) {
|
||||
@@ -113,6 +120,9 @@ function oneMinuteTimerFunction() {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Event] Updating all player name tags`);
|
||||
updateAllPlayerNameTags();
|
||||
}
|
||||
|
||||
updateVehicleSavedPositions();
|
||||
fixDesyncedPayPhones();
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -121,7 +131,6 @@ function tenMinuteTimerFunction() {
|
||||
//showRandomTipToAllPlayers();
|
||||
//saveServerDataToDatabase();
|
||||
//checkInactiveVehicleRespawns();
|
||||
updateVehicleSavedPositions();
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -236,44 +245,50 @@ function checkServerGameTime() {
|
||||
|
||||
if (getGame() == V_GAME_MAFIA_ONE) {
|
||||
if (getGameConfig().mainWorldScene[getGame()] == "FREERIDE") {
|
||||
if (isServerGoingToChangeMapsSoon(getServerConfig().hour, getServerConfig().minute)) {
|
||||
sendMapChangeWarningToPlayer(null, true);
|
||||
}
|
||||
//if (isServerGoingToChangeMapsSoon(getServerConfig().hour, getServerConfig().minute)) {
|
||||
// sendMapChangeWarningToPlayer(null, true);
|
||||
//}
|
||||
|
||||
if (isNightTime(getServerConfig().hour)) {
|
||||
getGameConfig().mainWorldScene[getGame()] = "FREERIDENOC";
|
||||
removeAllPlayersFromProperties();
|
||||
removeAllPlayersFromVehicles();
|
||||
saveServerDataToDatabase();
|
||||
logToConsole(LOG_INFO | LOG_WARN, `[V.RP.Timers] Changing server map to night`);
|
||||
messageDiscordEventChannel("🌙 Changing server map to night");
|
||||
despawnAllVehicles();
|
||||
despawnAllNPCs();
|
||||
despawnAllGroundItemObjects();
|
||||
getGameConfig().mainWorldScene[getGame()] = "FREERIDENOC";
|
||||
setServerPassword(generateRandomString(10, getGlobalConfig().alphaNumericCharacters));
|
||||
if (!serverStarting) {
|
||||
kickAllClients();
|
||||
saveServerDataToDatabase();
|
||||
despawnAllServerElements();
|
||||
}
|
||||
game.changeMap(getGameConfig().mainWorldScene[getGame()]);
|
||||
spawnAllVehicles();
|
||||
spawnAllNPCs();
|
||||
spawnAllGroundItemObjects();
|
||||
spawnAllServerElements();
|
||||
setServerPassword("");
|
||||
} else {
|
||||
if (serverStarting) {
|
||||
spawnAllServerElements();
|
||||
}
|
||||
}
|
||||
} else if (getGameConfig().mainWorldScene[getGame()] == "FREERIDENOC") {
|
||||
if (isServerGoingToChangeMapsSoon(getServerConfig().hour, getServerConfig().minute)) {
|
||||
sendMapChangeWarningToPlayer(null, true);
|
||||
}
|
||||
//if (isServerGoingToChangeMapsSoon(getServerConfig().hour, getServerConfig().minute)) {
|
||||
// sendMapChangeWarningToPlayer(null, true);
|
||||
//}
|
||||
|
||||
if (!isNightTime(getServerConfig().hour)) {
|
||||
getGameConfig().mainWorldScene[getGame()] = "FREERIDE";
|
||||
removeAllPlayersFromProperties();
|
||||
removeAllPlayersFromVehicles();
|
||||
saveServerDataToDatabase();
|
||||
logToConsole(LOG_INFO | LOG_WARN, `[V.RP.Timers] Changing server map to day`);
|
||||
messageDiscordEventChannel("🌞 Changing server map to day");
|
||||
despawnAllVehicles();
|
||||
despawnAllNPCs();
|
||||
despawnAllGroundItemObjects();
|
||||
getGameConfig().mainWorldScene[getGame()] = "FREERIDE";
|
||||
setServerPassword(generateRandomString(10, getGlobalConfig().alphaNumericCharacters));
|
||||
if (!serverStarting) {
|
||||
kickAllClients();
|
||||
saveServerDataToDatabase();
|
||||
despawnAllServerElements();
|
||||
}
|
||||
game.changeMap(getGameConfig().mainWorldScene[getGame()]);
|
||||
spawnAllVehicles();
|
||||
spawnAllNPCs();
|
||||
spawnAllGroundItemObjects();
|
||||
spawnAllServerElements();
|
||||
setServerPassword("");
|
||||
} else {
|
||||
if (serverStarting) {
|
||||
spawnAllServerElements();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -310,7 +325,12 @@ function checkPayDays() {
|
||||
|
||||
for (let i in getServerData().businesses) {
|
||||
if (getBusinessData(i).ownerType != V_BIZ_OWNER_NONE && getBusinessData(i).ownerType != V_BIZ_OWNER_PUBLIC && getBusinessData(i).ownerType != V_BIZ_OWNER_FACTION) {
|
||||
getBusinessData(i).till += 1000;
|
||||
let addToTill = getServerConfig().economy.passiveIncomePerPayDay;
|
||||
if (isDoubleBonusActive()) {
|
||||
addToTill = addToTill * 2;
|
||||
}
|
||||
getBusinessData(i).till = getBusinessData(i).till + addToTill;
|
||||
getBusinessData(i).needsSaved = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -542,109 +542,143 @@ function processPlayerEnteringExitingProperty(client) {
|
||||
}
|
||||
|
||||
if (pedState == V_PEDSTATE_ENTERINGPROPERTY) {
|
||||
logToConsole(LOG_VERBOSE, `[V.RP.Utilities]: Processing property ENTER for player ${getPlayerDisplayForConsole(client)} ...`);
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Utilities]: Processing property ENTER for player ${getPlayerDisplayForConsole(client)} ...`);
|
||||
if (isGameFeatureSupported("interiorScene") && propertyData.exitScene != "") {
|
||||
logToConsole(LOG_VERBOSE, `[V.RP.Utilities]: Player ${getPlayerDisplayForConsole(client)} is entering a property with interior scene (${propertyData.exitScene})`);
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Utilities]: Player ${getPlayerDisplayForConsole(client)} is entering a property with interior scene (${propertyData.exitScene}). Spawning ...`);
|
||||
spawnPlayer(client, propertyData.exitPosition, propertyData.exitRotation, getGameConfig().skins[getGame()][getPlayerCurrentSubAccount(client).skin][0]);
|
||||
onPlayerSpawn(client);
|
||||
getPlayerData(client).scene = propertyData.exitScene;
|
||||
//onPlayerSpawn(client);
|
||||
setPlayerControlState(client, false);
|
||||
} else {
|
||||
setPlayerPosition(client, propertyData.exitPosition);
|
||||
setPlayerHeading(client, propertyData.exitRotation);
|
||||
}
|
||||
|
||||
if (isGameFeatureSupported("dimension")) {
|
||||
setPlayerDimension(client, propertyData.exitDimension);
|
||||
}
|
||||
|
||||
if (isGameFeatureSupported("interior")) {
|
||||
setPlayerInterior(client, propertyData.exitInterior);
|
||||
}
|
||||
|
||||
setTimeout(function () {
|
||||
if (isFadeCameraSupported()) {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Utilities]: Fading camera OUT for player ${getPlayerDisplayForConsole(client)}`);
|
||||
fadePlayerCamera(client, true, 1000);
|
||||
}
|
||||
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Utilities]: Setting interior lights ${getOnOffFromBool(propertyData.interiorLights)} for player ${getPlayerDisplayForConsole(client)}`);
|
||||
updateInteriorLightsForPlayer(client, propertyData.interiorLights);
|
||||
|
||||
let radioStationIndex = propertyData.streamingRadioStationIndex;
|
||||
if (radioStationIndex != -1) {
|
||||
if (getRadioStationData(radioStationIndex)) {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Utilities]: Player ${getPlayerDisplayForConsole(client)} entered a property with a radio station set, changing their stream`);
|
||||
playRadioStreamForPlayer(client, getRadioStationData(radioStationIndex).url);
|
||||
getPlayerData(client).streamingRadioStation = radioStationIndex;
|
||||
}
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
if (getPlayerData(client).enteringExitingProperty[0] == V_PROPERTY_TYPE_BUSINESS) {
|
||||
if (propertyData.type == V_BIZ_TYPE_PAINTBALL) {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Utilities]: Starting paintball for player ${getOnOffFromBool(inProperty.interiorLights)}`);
|
||||
startPaintBall(client);
|
||||
}
|
||||
}
|
||||
|
||||
let radioStationIndex = propertyData.streamingRadioStationIndex;
|
||||
if (radioStationIndex != -1) {
|
||||
if (getRadioStationData(radioStationIndex)) {
|
||||
playRadioStreamForPlayer(client, getRadioStationData(radioStationIndex).url);
|
||||
getPlayerData(client).streamingRadioStation = radioStationIndex;
|
||||
}
|
||||
if (isGameFeatureSupported("dimension")) {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Utilities]: Setting dimension for player ${getPlayerDisplayForConsole(client)} to ${propertyData.exitDimension}`);
|
||||
setPlayerDimension(client, propertyData.exitDimension);
|
||||
}
|
||||
|
||||
if (isGameFeatureSupported("interior")) {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Utilities]: Setting interior for player ${getPlayerDisplayForConsole(client)} to ${propertyData.exitInterior}`);
|
||||
setPlayerInterior(client, propertyData.exitInterior);
|
||||
}
|
||||
|
||||
getPlayerData(client).inProperty = [getPlayerData(client).enteringExitingProperty[0], getPlayerData(client).enteringExitingProperty[1]];
|
||||
getPlayerData(client).enteringExitingProperty = null;
|
||||
getPlayerData(client).pedState = V_PEDSTATE_READY;
|
||||
|
||||
setTimeout(function () {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.NetEvents] Enabling all rendering states for player ${getPlayerDisplayForConsole(client)} since map switch finished`);
|
||||
setPlayer2DRendering(client, true, true, true, true, true, true);
|
||||
|
||||
setPlayerControlState(client, true);
|
||||
}, 2500);
|
||||
} else if (pedState == V_PEDSTATE_EXITINGPROPERTY) {
|
||||
logToConsole(LOG_VERBOSE, `[V.RP.Utilities]: Processing property EXIT for player ${getPlayerDisplayForConsole(client)} from property ID ${propertyData.index}/${propertyData.databaseId} ...`);
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Utilities]: Processing property EXIT for player ${getPlayerDisplayForConsole(client)} from property ID ${propertyData.index}/${propertyData.databaseId} ...`);
|
||||
if (isGameFeatureSupported("interiorScene") && propertyData.entranceScene != "") {
|
||||
logToConsole(LOG_VERBOSE, `[V.RP.Utilities]: Player ${getPlayerDisplayForConsole(client)} is exiting a property with external interior scene (${propertyData.entranceScene})`);
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Utilities]: Player ${getPlayerDisplayForConsole(client)} is exiting a property with external interior scene (${propertyData.entranceScene})`);
|
||||
spawnPlayer(client, propertyData.entrancePosition, propertyData.entranceRotation, getGameConfig().skins[getGame()][getPlayerCurrentSubAccount(client).skin][0]);
|
||||
onPlayerSpawn(client);
|
||||
getPlayerData(client).scene = propertyData.entranceScene;
|
||||
//onPlayerSpawn(client);
|
||||
setPlayerControlState(client, false);
|
||||
} else {
|
||||
setPlayerPosition(client, propertyData.entrancePosition);
|
||||
setPlayerHeading(client, propertyData.entranceRotation);
|
||||
}
|
||||
|
||||
if (isGameFeatureSupported("dimension")) {
|
||||
setPlayerDimension(client, propertyData.entranceDimension);
|
||||
}
|
||||
|
||||
if (isGameFeatureSupported("interior")) {
|
||||
setPlayerInterior(client, propertyData.entranceInterior);
|
||||
}
|
||||
|
||||
// Check if exiting property was into another house/business
|
||||
let inProperty = false;
|
||||
let inPropertyType = V_PROPERTY_TYPE_NONE;
|
||||
|
||||
let inBusiness = getPlayerBusiness(client);
|
||||
if (inBusiness != -1) {
|
||||
inProperty = getBusinessData(inBusiness);
|
||||
inPropertyType = V_PROPERTY_TYPE_BUSINESS;
|
||||
} else {
|
||||
let inHouse = getPlayerHouse(client);
|
||||
if (inHouse != -1) {
|
||||
inProperty = getHouseData(inHouse);
|
||||
inPropertyType = V_PROPERTY_TYPE_HOUSE;
|
||||
if (getPlayerDimension(client) != getGameConfig().mainWorldDimension[getGame()]) {
|
||||
let inBusiness = getPlayerBusiness(client);
|
||||
if (inBusiness != -1) {
|
||||
inProperty = getBusinessData(inBusiness);
|
||||
inPropertyType = V_PROPERTY_TYPE_BUSINESS;
|
||||
} else {
|
||||
let inHouse = getPlayerHouse(client);
|
||||
if (inHouse != -1) {
|
||||
inProperty = getHouseData(inHouse);
|
||||
inPropertyType = V_PROPERTY_TYPE_HOUSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setTimeout(function () {
|
||||
if (getGame() != V_GAME_MAFIA_ONE && getGame() != V_GAME_GTA_IV) {
|
||||
if (isFadeCameraSupported()) {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Utilities]: Fading camera IN for player ${getPlayerDisplayForConsole(client)}`);
|
||||
fadePlayerCamera(client, true, 1000);
|
||||
}
|
||||
}
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Utilities]: Setting interior lights ${getOnOffFromBool(inProperty.interiorLights)} for player ${getPlayerDisplayForConsole(client)}`);
|
||||
updateInteriorLightsForPlayer(client, (inProperty != false) ? inProperty.interiorLights : true);
|
||||
}, 1000);
|
||||
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Utilities]: Attempting to stop paintball for player ${getOnOffFromBool(inProperty.interiorLights)}`);
|
||||
stopPaintBall(client);
|
||||
|
||||
if (inProperty != false) {
|
||||
if (getBusinessData(inBusiness).streamingRadioStationIndex != -1) {
|
||||
if (getRadioStationData(getBusinessData(inBusiness).streamingRadioStationIndex)) {
|
||||
playRadioStreamForPlayer(client, getRadioStationData(getBusinessData(inBusiness).streamingRadioStationIndex).url);
|
||||
getPlayerData(client).streamingRadioStation = getBusinessData(inBusiness).streamingRadioStationIndex;
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Utilities]: Player ${getPlayerDisplayForConsole(client)} exited property into another property, changing radio station`);
|
||||
if (inProperty.streamingRadioStationIndex != -1) {
|
||||
if (getRadioStationData(inProperty.streamingRadioStationIndex)) {
|
||||
playRadioStreamForPlayer(client, getRadioStationData(inProperty.streamingRadioStationIndex).url);
|
||||
getPlayerData(client).streamingRadioStation = inProperty.streamingRadioStationIndex;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Utilities]: Player ${getPlayerDisplayForConsole(client)} exited property into main world, stopping radio station`);
|
||||
stopRadioStreamForPlayer(client);
|
||||
getPlayerData(client).streamingRadioStation = -1;
|
||||
}
|
||||
|
||||
if (isGameFeatureSupported("dimension")) {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Utilities]: Setting dimension for player ${getPlayerDisplayForConsole(client)} to ${propertyData.entranceDimension}`);
|
||||
setPlayerDimension(client, propertyData.entranceDimension);
|
||||
}
|
||||
|
||||
if (isGameFeatureSupported("interior")) {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Utilities]: Setting interior for player ${getPlayerDisplayForConsole(client)} to ${propertyData.entranceInterior}`);
|
||||
setPlayerInterior(client, propertyData.entranceInterior);
|
||||
}
|
||||
|
||||
getPlayerData(client).inProperty = [inPropertyType, inProperty.index];
|
||||
getPlayerData(client).enteringExitingProperty = null;
|
||||
getPlayerData(client).pedState = V_PEDSTATE_READY;
|
||||
|
||||
setTimeout(function () {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.NetEvents] Enabling all rendering states for player ${getPlayerDisplayForConsole(client)} since map switch finished`);
|
||||
setPlayer2DRendering(client, true, true, true, true, true, true);
|
||||
|
||||
setPlayerControlState(client, true);
|
||||
}, 2500);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -90,6 +90,11 @@ class VehicleData {
|
||||
|
||||
this.lastActiveTime = false;
|
||||
|
||||
this.rank = 0;
|
||||
|
||||
this.whoAdded = 0;
|
||||
this.whenAdded = 0;
|
||||
|
||||
if (dbAssoc) {
|
||||
// General Info
|
||||
this.databaseId = toInteger(dbAssoc["veh_id"]);
|
||||
@@ -154,16 +159,9 @@ class VehicleData {
|
||||
this.whoAdded = toInteger(dbAssoc["veh_who_added"]);
|
||||
this.whenAdded = toInteger(dbAssoc["veh_when_added"]);
|
||||
this.licensePlate = toInteger(dbAssoc["veh_license_plate"]);
|
||||
this.rank = toInteger(dbAssoc["veh_rank"]);
|
||||
}
|
||||
}
|
||||
|
||||
saveToDatabase() {
|
||||
saveVehicleToDatabase(this);
|
||||
}
|
||||
|
||||
respawn() {
|
||||
respawnVehicle(this.vehicle);
|
||||
}
|
||||
};
|
||||
|
||||
// ===========================================================================
|
||||
@@ -186,7 +184,7 @@ function loadVehiclesFromDatabase() {
|
||||
dbAssoc = fetchQueryAssoc(dbConnection, dbQueryString);
|
||||
if (dbAssoc.length > 0) {
|
||||
for (let i in dbAssoc) {
|
||||
let tempVehicleData = new VehicleData(dbAssoc[i]);
|
||||
let tempVehicleData = new VehicleData(dbAssoc[i], false);
|
||||
tempVehicles.push(tempVehicleData);
|
||||
}
|
||||
}
|
||||
@@ -294,6 +292,7 @@ function saveVehicleToDatabase(vehicleDataId) {
|
||||
["veh_int", toInteger(tempVehicleData.interior)],
|
||||
["veh_vw", toInteger(tempVehicleData.dimension)],
|
||||
["veh_livery", toInteger(tempVehicleData.livery)],
|
||||
["veh_rank", toInteger(tempVehicleData.rank)],
|
||||
["veh_radio_station", (getRadioStationData(tempVehicleData.streamingRadioStationIndex) != false) ? toInteger(getRadioStationData(tempVehicleData.streamingRadioStationIndex).databaseId) : -1],
|
||||
];
|
||||
|
||||
@@ -322,9 +321,10 @@ function saveVehicleToDatabase(vehicleDataId) {
|
||||
|
||||
function spawnAllVehicles() {
|
||||
for (let i in getServerData().vehicles) {
|
||||
let vehicle = spawnVehicle(getServerData().vehicles[i]);
|
||||
getServerData().vehicles[i].vehicle = vehicle;
|
||||
setEntityData(vehicle, "v.rp.dataSlot", i, false);
|
||||
if (getServerData().vehicles[i].vehicle == false) {
|
||||
let vehicle = spawnVehicle(getServerData().vehicles[i]);
|
||||
getServerData().vehicles[i].vehicle = vehicle;
|
||||
}
|
||||
}
|
||||
setAllVehicleIndexes();
|
||||
}
|
||||
@@ -337,9 +337,10 @@ function spawnAllVehicles() {
|
||||
*/
|
||||
function getVehicleData(vehicle) {
|
||||
if (isVehicleObject(vehicle)) {
|
||||
let dataIndex = getEntityData(vehicle, "v.rp.dataSlot");
|
||||
if (typeof getServerData().vehicles[dataIndex] != "undefined") {
|
||||
return getServerData().vehicles[dataIndex];
|
||||
for (let i in getServerData().vehicles) {
|
||||
if (getServerData().vehicles[i].vehicle == vehicle) {
|
||||
return getServerData().vehicles[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -367,7 +368,7 @@ function createVehicleCommand(command, params, client) {
|
||||
}
|
||||
|
||||
let frontPos = getPosInFrontOfPos(getPlayerPosition(client), getPlayerHeading(client), getGlobalConfig().spawnCarDistance);
|
||||
let vehicle = createPermanentVehicle(modelIndex, frontPos, heading, getPlayerInterior(client), getPlayerDimension(client));
|
||||
let vehicle = createPermanentVehicle(modelIndex, frontPos, heading, getPlayerInterior(client), getPlayerDimension(client), getPlayerData(client).accountData.databaseId);
|
||||
|
||||
messageAdmins(`{adminOrange}${getPlayerName(client)}{MAINCOLOUR} created a {vehiclePurple}${getVehicleName(vehicle)}`, true);
|
||||
}
|
||||
@@ -388,7 +389,7 @@ function createTemporaryVehicleCommand(command, params, client) {
|
||||
}
|
||||
|
||||
let frontPos = getPosInFrontOfPos(getPlayerPosition(client), getPlayerHeading(client), getGlobalConfig().spawnCarDistance);
|
||||
let vehicle = createTemporaryVehicle(modelIndex, frontPos, getPlayerHeading(client), getPlayerInterior(client), getPlayerDimension(client));
|
||||
let vehicle = createTemporaryVehicle(modelIndex, frontPos, getPlayerHeading(client), getPlayerInterior(client), getPlayerDimension(client), getPlayerData(client).accountData.databaseId);
|
||||
|
||||
messageAdmins(`{adminOrange}${getPlayerName(client)}{MAINCOLOUR} created a temporary {vehiclePurple}${getVehicleName(vehicle)}`, true);
|
||||
}
|
||||
@@ -496,13 +497,18 @@ function deleteVehicleCommand(command, params, client) {
|
||||
vehicle = getPlayerVehicle(client);
|
||||
}
|
||||
|
||||
let dataIndex = getEntityData(vehicle, "v.rp.dataSlot");
|
||||
let vehicleIndex = getVehicleData(vehicle).index;
|
||||
let vehicleName = getVehicleName(vehicle);
|
||||
|
||||
quickDatabaseQuery(`UPDATE veh_main SET veh_deleted = 1 WHERE veh_id = ${getVehicleData(vehicle).databaseId}`);
|
||||
if (getVehicleData(vehicle).databaseId > 0) {
|
||||
quickDatabaseQuery(`UPDATE veh_main SET veh_deleted = 1 WHERE veh_id = ${getVehicleData(vehicle).databaseId}`);
|
||||
}
|
||||
|
||||
getServerData().vehicles.splice(dataIndex, 1);
|
||||
destroyElement(vehicle);
|
||||
getServerData().vehicles.splice(vehicleIndex, 1);
|
||||
|
||||
destroyGameElement(vehicle);
|
||||
|
||||
setAllVehicleIndexes();
|
||||
|
||||
messagePlayerSuccess(client, `The ${vehicleName} has been deleted!`);
|
||||
}
|
||||
@@ -818,23 +824,25 @@ function doesPlayerHaveVehicleKeys(client, vehicle) {
|
||||
|
||||
if (vehicleData.ownerType == V_VEHOWNER_CLAN) {
|
||||
if (vehicleData.ownerId == getPlayerCurrentSubAccount(client).clan) {
|
||||
if (vehicleData.clanRank <= getPlayerCurrentSubAccount(client).clanRank) {
|
||||
if (getClanRankData(getPlayerClan(client), getPlayerClanRank(client)).level >= vehicleData.rank) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (vehicleData.ownerType == V_VEHOWNER_FACTION) {
|
||||
if (vehicleData.ownerId == getPlayerCurrentSubAccount(client).faction) {
|
||||
if (vehicleData.factionRank <= getPlayerCurrentSubAccount(client).factionRank) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
//if (vehicleData.ownerType == V_VEHOWNER_FACTION) {
|
||||
// if (vehicleData.ownerId == getPlayerCurrentSubAccount(client).faction) {
|
||||
// if (vehicleData.factionRank <= getPlayerCurrentSubAccount(client).factionRank) {
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
if (vehicleData.ownerType == V_VEHOWNER_JOB) {
|
||||
if (vehicleData.ownerId == getPlayerCurrentSubAccount(client).job) {
|
||||
return true;
|
||||
if (getJobRankData(getPlayerJob(client), getPlayerJobRank(client)).level >= vehicleData.rank) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -928,8 +936,13 @@ function setVehicleRankCommand(command, params, client) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isNaN(params)) {
|
||||
messagePlayerError(client, getLocaleString(client, "MustBeNumber"));
|
||||
return false;
|
||||
}
|
||||
|
||||
let vehicle = getPlayerVehicle(client);
|
||||
let rankId = params;
|
||||
let level = toInteger(params);
|
||||
|
||||
if (!getVehicleData(vehicle)) {
|
||||
messagePlayerError(client, getLocaleString(client, "RandomVehicleCommandsDisabled"));
|
||||
@@ -937,16 +950,11 @@ function setVehicleRankCommand(command, params, client) {
|
||||
}
|
||||
|
||||
if (getVehicleData(vehicle).ownerType == V_VEHOWNER_CLAN) {
|
||||
rankId = getClanRankFromParams(getVehicleData(vehicle).ownerId, params);
|
||||
if (!getClanRankData(getVehicleData(vehicle).ownerId, rankId)) {
|
||||
messagePlayerError(client, getLocaleString(client, "InvalidClanRank"));
|
||||
return false;
|
||||
}
|
||||
getVehicleData(vehicle).rank = getClanRankData(getVehicleData(vehicle).ownerId, rankId).databaseId;
|
||||
messageAdmins(`{adminOrange}${getPlayerName(client)}{MAINCOLOUR} set their {vehiclePurple}${getVehicleName(vehicle)}{MAINCOLOUR} minimum rank to {ALTCOLOUR}${getClanRankData(getVehicleData(vehicle).ownerId, rankId).name}{MAINCOLOUR} of the {clanOrange}${getClanData(getVehicleData(vehicle).ownerId).name}{MAINCOLOUR} clan!`, true);
|
||||
getVehicleData(vehicle).rank = level
|
||||
messageAdmins(`{adminOrange}${getPlayerName(client)}{MAINCOLOUR} set their {vehiclePurple}${getVehicleName(vehicle)}{MAINCOLOUR} minimum rank to {ALTCOLOUR}${level}{MAINCOLOUR} of the {clanOrange}${getClanData(getVehicleData(vehicle).ownerId).name}{MAINCOLOUR} clan!`, true);
|
||||
} else if (getVehicleData(vehicle).ownerType == V_VEHOWNER_JOB) {
|
||||
getVehicleData(vehicle).rank = rankId;
|
||||
messageAdmins(`{adminOrange}${getPlayerName(client)}{MAINCOLOUR} set their {vehiclePurple}${getVehicleName(vehicle)}{MAINCOLOUR} minimum rank to {ALTCOLOUR}${rankId}{MAINCOLOUR} of the {jobYellow}${getJobData(getJobIdFromDatabaseId(getVehicleData(vehicle).ownerId)).name}{MAINCOLOUR} job!`, true);
|
||||
getVehicleData(vehicle).rank = level;
|
||||
messageAdmins(`{adminOrange}${getPlayerName(client)}{MAINCOLOUR} set their {vehiclePurple}${getVehicleName(vehicle)}{MAINCOLOUR} minimum rank to {ALTCOLOUR}${level}{MAINCOLOUR} of the {jobYellow}${getJobData(getJobIdFromDatabaseId(getVehicleData(vehicle).ownerId)).name}{MAINCOLOUR} job!`, true);
|
||||
}
|
||||
|
||||
getVehicleData(vehicle).needsSaved = true;
|
||||
@@ -1227,6 +1235,9 @@ function getVehicleInfoCommand(command, params, client) {
|
||||
[`License Plate`, `${vehicleData.licensePlate}`],
|
||||
[`Colour`, `${getVehicleColourInfoString(vehicleData.colour1, vehicleData.colour1IsRGBA)}, ${getVehicleColourInfoString(vehicleData.colour1, vehicleData.colour1IsRGBA)}`],
|
||||
[`Last Driver`, `${vehicleData.lastDriverName}`],
|
||||
[`Added By`, `${loadAccountFromId(vehicleData.whoAdded).name}`],
|
||||
[`Added On`, `${new Date(vehicleData.whenAdded).toLocaleDateString("en-GB")}`],
|
||||
[`Rank Level`, `${vehicleData.rank}`],
|
||||
];
|
||||
|
||||
let stats = tempStats.map(stat => `{chatBoxListIndex}${stat[0]}: {ALTCOLOUR}${stat[1]}{MAINCOLOUR}`);
|
||||
@@ -1319,14 +1330,10 @@ function toggleVehicleSpawnLockCommand(command, params, client) {
|
||||
// ===========================================================================
|
||||
|
||||
function reloadAllVehiclesCommand(command, params, client) {
|
||||
for (let i in getServerData().vehicles) {
|
||||
if (getServerData().vehicles[i].vehicle) {
|
||||
deleteGameElement(getServerData().vehicles[i].vehicle);
|
||||
}
|
||||
}
|
||||
|
||||
despawnAllVehicles();
|
||||
clearArray(getServerData().vehicles);
|
||||
getServerData().vehicles = loadVehiclesFromDatabase();
|
||||
setAllVehicleIndexes();
|
||||
spawnAllVehicles();
|
||||
|
||||
announceAdminAction(`AllVehiclesReloaded`);
|
||||
@@ -1359,10 +1366,10 @@ function respawnAllVehiclesCommand(command, params, client) {
|
||||
respawnVehicle(getServerData().vehicles[i].vehicle);
|
||||
}
|
||||
|
||||
let randomVehicles = getElementsByType(ELEMENT_VEHICLE).filter(v => getVehicleData(v) == false);
|
||||
for (let i in randomVehicles) {
|
||||
destroyElement(randomVehicles[i]);
|
||||
}
|
||||
//let randomVehicles = getElementsByType(ELEMENT_VEHICLE).filter(v => getVehicleData(v) == false);
|
||||
//for (let i in randomVehicles) {
|
||||
// destroyElement(randomVehicles[i]);
|
||||
//}
|
||||
|
||||
setAllVehicleIndexes();
|
||||
|
||||
@@ -1373,17 +1380,19 @@ function respawnAllVehiclesCommand(command, params, client) {
|
||||
|
||||
function respawnEmptyVehiclesCommand(command, params, client) {
|
||||
for (let i in getServerData().vehicles) {
|
||||
if (!isVehicleUnoccupied(getServerData().vehicles[i].vehicle)) {
|
||||
if (isVehicleUnoccupied(getServerData().vehicles[i].vehicle)) {
|
||||
respawnVehicle(getServerData().vehicles[i].vehicle);
|
||||
}
|
||||
}
|
||||
|
||||
let clientVehicles = getElementsByType(ELEMENT_VEHICLE).filter(v => getVehicleData(v) == false);
|
||||
for (let i in clientVehicles) {
|
||||
if (!isVehicleUnoccupied(clientVehicles[i])) {
|
||||
destroyElement(clientVehicles[i]);
|
||||
}
|
||||
}
|
||||
//let clientVehicles = getElementsByType(ELEMENT_VEHICLE).filter(v => getVehicleData(v) == false);
|
||||
//for (let i in clientVehicles) {
|
||||
// if (!isVehicleUnoccupied(clientVehicles[i])) {
|
||||
// destroyElement(clientVehicles[i]);
|
||||
// }
|
||||
//}
|
||||
|
||||
setAllVehicleIndexes();
|
||||
|
||||
announceAdminAction(`EmptyVehiclesRespawned`);
|
||||
}
|
||||
@@ -1397,6 +1406,8 @@ function respawnJobVehiclesCommand(command, params, client) {
|
||||
}
|
||||
}
|
||||
|
||||
setAllVehicleIndexes();
|
||||
|
||||
announceAdminAction(`JobVehiclesRespawned`);
|
||||
}
|
||||
|
||||
@@ -1409,6 +1420,8 @@ function respawnClanVehiclesCommand(command, params, client) {
|
||||
}
|
||||
}
|
||||
|
||||
setAllVehicleIndexes();
|
||||
|
||||
announceAdminAction(`ClanVehiclesRespawned`);
|
||||
}
|
||||
|
||||
@@ -1421,6 +1434,8 @@ function respawnPlayerVehiclesCommand(command, params, client) {
|
||||
}
|
||||
}
|
||||
|
||||
setAllVehicleIndexes();
|
||||
|
||||
announceAdminAction(`PlayerVehiclesRespawned`);
|
||||
}
|
||||
|
||||
@@ -1433,6 +1448,8 @@ function respawnPublicVehiclesCommand(command, params, client) {
|
||||
}
|
||||
}
|
||||
|
||||
setAllVehicleIndexes();
|
||||
|
||||
announceAdminAction(`PublicVehiclesRespawned`);
|
||||
}
|
||||
|
||||
@@ -1445,6 +1462,8 @@ function respawnBusinessVehiclesCommand(command, params, client) {
|
||||
}
|
||||
}
|
||||
|
||||
setAllVehicleIndexes();
|
||||
|
||||
announceAdminAction(`BusinessVehiclesRespawned`);
|
||||
}
|
||||
|
||||
@@ -1464,23 +1483,21 @@ function stopRentingVehicle(client) {
|
||||
// ===========================================================================
|
||||
|
||||
function respawnVehicle(vehicle) {
|
||||
let vehicles = getServerData().vehicles;
|
||||
for (let i in vehicles) {
|
||||
if (vehicle == vehicles[i].vehicle) {
|
||||
if (vehicles[i].spawnLocked == true) {
|
||||
vehicles[i].engine = false;
|
||||
for (let i in getServerData().vehicles) {
|
||||
if (vehicle == getServerData().vehicles[i].vehicle) {
|
||||
if (getServerData().vehicles[i].spawnLocked == true) {
|
||||
getServerData().vehicles[i].engine = false;
|
||||
}
|
||||
|
||||
if (vehicles[i].ownerType == V_VEHOWNER_JOB) {
|
||||
vehicles[i].locked = true;
|
||||
if (getServerData().vehicles[i].ownerType == V_VEHOWNER_JOB) {
|
||||
getServerData().vehicles[i].locked = true;
|
||||
}
|
||||
|
||||
destroyElement(vehicle);
|
||||
vehicles[i].vehicle = false;
|
||||
getServerData().vehicles[i].vehicle = false;
|
||||
|
||||
let newVehicle = spawnVehicle(vehicles[i]);
|
||||
vehicles[i].vehicle = newVehicle;
|
||||
setEntityData(newVehicle, "v.rp.dataSlot", i, false);
|
||||
let newVehicle = spawnVehicle(getServerData().vehicles[i]);
|
||||
getServerData().vehicles[i].vehicle = newVehicle;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1490,7 +1507,7 @@ function respawnVehicle(vehicle) {
|
||||
// ===========================================================================
|
||||
|
||||
function spawnVehicle(vehicleData) {
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Vehicle]: Spawning ${getVehicleNameFromModel(vehicleData.model)} at ${vehicleData.spawnPosition.x}, ${vehicleData.spawnPosition.y}, ${vehicleData.spawnPosition.z} with heading ${vehicleData.spawnRotation}`);
|
||||
logToConsole(LOG_DEBUG, `[V.RP.Vehicle]: Spawning ${getGameConfig().vehicles[getGame()][vehicleData.model][1]} at ${vehicleData.spawnPosition.x}, ${vehicleData.spawnPosition.y}, ${vehicleData.spawnPosition.z} with heading ${vehicleData.spawnRotation}`);
|
||||
let vehicle = createGameVehicle(vehicleData.model, vehicleData.spawnPosition, vehicleData.spawnRotation);
|
||||
|
||||
if (!vehicle) {
|
||||
@@ -1590,7 +1607,7 @@ function isVehicleOwnedByJob(vehicle, jobId) {
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function createNewDealershipVehicle(modelIndex, spawnPosition, spawnRotation, price, dealershipId, interior = 0, dimension = 0) {
|
||||
function createNewDealershipVehicle(modelIndex, spawnPosition, spawnRotation, price, ownerType, dealershipId, interior = 0, dimension = 0) {
|
||||
let vehicle = createGameVehicle(modelIndex, spawnPosition, spawnRotation);
|
||||
if (!vehicle) {
|
||||
return false;
|
||||
@@ -1605,19 +1622,29 @@ function createNewDealershipVehicle(modelIndex, spawnPosition, spawnRotation, pr
|
||||
tempVehicleData.spawnLocked = true;
|
||||
tempVehicleData.spawnPosition = spawnPosition;
|
||||
tempVehicleData.spawnRotation = spawnRotation;
|
||||
tempVehicleData.ownerType = V_VEHOWNER_BIZ;
|
||||
tempVehicleData.ownerType = ownerType;
|
||||
tempVehicleData.ownerId = dealershipId;
|
||||
tempVehicleData.needsSaved = true;
|
||||
tempVehicleData.interior = interior;
|
||||
tempVehicleData.dimension = dimension;
|
||||
tempVehicleData.whoAdded = defaultNoAccountId;
|
||||
tempVehicleData.whenAdded = getCurrentUnixTimestamp();
|
||||
|
||||
let slot = getServerData().vehicles.push(tempVehicleData);
|
||||
setEntityData(vehicle, "v.rp.dataSlot", slot - 1, false);
|
||||
if (!isGameFeatureSupported("vehicleColour")) {
|
||||
tempVehicleData.colour1 = 0;
|
||||
tempVehicleData.colour2 = 0;
|
||||
tempVehicleData.colour3 = 0;
|
||||
tempVehicleData.colour4 = 0;
|
||||
}
|
||||
|
||||
getServerData().vehicles.push(tempVehicleData);
|
||||
|
||||
setAllVehicleIndexes();
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function createTemporaryVehicle(modelIndex, position, heading, interior = 0, dimension = 0) {
|
||||
function createTemporaryVehicle(modelIndex, position, heading, interior = 0, dimension = 0, whoAdded = defaultNoAccountId) {
|
||||
let vehicle = createGameVehicle(modelIndex, position, heading);
|
||||
setVehicleHeading(vehicle, heading);
|
||||
setElementInterior(vehicle, interior);
|
||||
@@ -1629,6 +1656,10 @@ function createTemporaryVehicle(modelIndex, position, heading, interior = 0, dim
|
||||
tempVehicleData.databaseId = -1;
|
||||
tempVehicleData.interior = interior;
|
||||
tempVehicleData.dimension = dimension;
|
||||
tempVehicleData.needsSaved = true;
|
||||
tempVehicleData.whoAdded = whoAdded;
|
||||
tempVehicleData.whenAdded = getCurrentUnixTimestamp();
|
||||
|
||||
if (!isGameFeatureSupported("vehicleColour")) {
|
||||
tempVehicleData.colour1 = 0;
|
||||
tempVehicleData.colour2 = 0;
|
||||
@@ -1636,19 +1667,16 @@ function createTemporaryVehicle(modelIndex, position, heading, interior = 0, dim
|
||||
tempVehicleData.colour4 = 0;
|
||||
}
|
||||
|
||||
let slot = getServerData().vehicles.push(tempVehicleData);
|
||||
setAllVehicleIndexes();
|
||||
getServerData().vehicles.push(tempVehicleData);
|
||||
|
||||
if (areServerElementsSupported()) {
|
||||
setEntityData(vehicle, "v.rp.dataSlot", slot - 1, false);
|
||||
}
|
||||
setAllVehicleIndexes();
|
||||
|
||||
return vehicle;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function createPermanentVehicle(modelIndex, position, heading, interior = 0, dimension = 0) {
|
||||
function createPermanentVehicle(modelIndex, position, heading, interior = 0, dimension = 0, whoAdded = defaultNoAccountId) {
|
||||
let vehicle = createGameVehicle(modelIndex, position, heading);
|
||||
setVehicleHeading(vehicle, heading);
|
||||
setElementInterior(vehicle, interior);
|
||||
@@ -1659,6 +1687,10 @@ function createPermanentVehicle(modelIndex, position, heading, interior = 0, dim
|
||||
tempVehicleData.model = modelIndex;
|
||||
tempVehicleData.interior = interior;
|
||||
tempVehicleData.dimension = dimension;
|
||||
tempVehicleData.needsSaved = true;
|
||||
tempVehicleData.whoAdded = whoAdded;
|
||||
tempVehicleData.whenAdded = getCurrentUnixTimestamp();
|
||||
|
||||
if (!isGameFeatureSupported("vehicleColour")) {
|
||||
tempVehicleData.colour1 = 0;
|
||||
tempVehicleData.colour2 = 0;
|
||||
@@ -1666,12 +1698,9 @@ function createPermanentVehicle(modelIndex, position, heading, interior = 0, dim
|
||||
tempVehicleData.colour4 = 0;
|
||||
}
|
||||
|
||||
let slot = getServerData().vehicles.push(tempVehicleData);
|
||||
setAllVehicleIndexes();
|
||||
getServerData().vehicles.push(tempVehicleData);
|
||||
|
||||
if (areServerElementsSupported()) {
|
||||
setEntityData(vehicle, "v.rp.dataSlot", slot - 1, false);
|
||||
}
|
||||
setAllVehicleIndexes();
|
||||
|
||||
return vehicle;
|
||||
}
|
||||
@@ -1737,7 +1766,7 @@ function checkVehiclePurchasing(client) {
|
||||
|
||||
getServerData().purchasingVehicleCache.splice(getServerData().purchasingVehicleCache.indexOf(client), 1);
|
||||
if (getVehicleData(getPlayerData(client).buyingVehicle).ownerType == V_VEHOWNER_BIZ || getVehicleData(getPlayerData(client).buyingVehicle).ownerType == V_VEHOWNER_NONE) {
|
||||
createNewDealershipVehicle(getVehicleData(getPlayerData(client).buyingVehicle).model, getVehicleData(getPlayerData(client).buyingVehicle).spawnPosition, getVehicleData(getPlayerData(client).buyingVehicle).spawnRotation, getVehicleData(getPlayerData(client).buyingVehicle).buyPrice, getVehicleData(getPlayerData(client).buyingVehicle).ownerId);
|
||||
createNewDealershipVehicle(getVehicleData(getPlayerData(client).buyingVehicle).model, getVehicleData(getPlayerData(client).buyingVehicle).spawnPosition, getVehicleData(getPlayerData(client).buyingVehicle).spawnRotation, getVehicleData(getPlayerData(client).buyingVehicle).buyPrice, getVehicleData(getPlayerData(client).buyingVehicle).ownerType, getVehicleData(getPlayerData(client).buyingVehicle).ownerId);
|
||||
}
|
||||
takePlayerCash(client, getVehicleData(getPlayerData(client).buyingVehicle).buyPrice);
|
||||
updatePlayerCash(client);
|
||||
@@ -1839,13 +1868,18 @@ function getVehicleFromDatabaseId(databaseId) {
|
||||
// ===========================================================================
|
||||
|
||||
function isVehicleUnoccupied(vehicle) {
|
||||
for (let i = 0; i <= 8; i++) {
|
||||
if (vehicle.getOccupant(i) != null) {
|
||||
return true;
|
||||
let clients = getClients();
|
||||
for (let i in clients) {
|
||||
if (clients[i].player != null) {
|
||||
if (clients[i].player.vehicle != false) {
|
||||
if (clients[i].player.vehicle == vehicle) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -1868,7 +1902,7 @@ function removeAllOccupantsFromVehicle(vehicle) {
|
||||
let clients = getClients();
|
||||
for (let i in clients) {
|
||||
if (clients[i].player != null) {
|
||||
if (clients[i].player.vehicle != null) {
|
||||
if (clients[i].player.vehicle != false) {
|
||||
if (clients[i].player.vehicle == vehicle) {
|
||||
removePlayerFromVehicle(clients[i]);
|
||||
}
|
||||
@@ -1920,9 +1954,13 @@ function isPlayerInVehicleDriverSeat(client) {
|
||||
|
||||
function despawnAllVehicles() {
|
||||
for (let i in getServerData().vehicles) {
|
||||
destroyGameElement(getServerData().vehicles[i].vehicle);
|
||||
getServerData().vehicles[i].vehicle = null;
|
||||
if (getServerData().vehicles[i].vehicle != false) {
|
||||
destroyGameElement(getServerData().vehicles[i].vehicle);
|
||||
getServerData().vehicles[i].vehicle = false;
|
||||
}
|
||||
}
|
||||
|
||||
setAllVehicleIndexes();
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -1936,4 +1974,18 @@ function updateVehicleSavedPositions() {
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function getVehicleDataIndexFromVehicle(vehicle) {
|
||||
if (isVehicleObject(vehicle)) {
|
||||
for (let i in getServerData().vehicles) {
|
||||
if (getServerData().vehicles[i].vehicle == vehicle) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -142,4 +142,12 @@ const V_NPC_ACTION_GUARD_AREA = 7;
|
||||
const V_VEHSEAT_DRIVER = 0;
|
||||
const V_VEHSEAT_FRONTPASSENGER = 1;
|
||||
const V_VEHSEAT_REARLEFTPASSENGER = 2;
|
||||
const V_VEHSEAT_REARRIGHTPASSENGER = 3;
|
||||
const V_VEHSEAT_REARRIGHTPASSENGER = 3;
|
||||
|
||||
// PayPhone States
|
||||
const V_PAYPHONE_STATE_NONE = 0;
|
||||
const V_PAYPHONE_STATE_IDLE = 1;
|
||||
const V_PAYPHONE_STATE_RINGING = 2;
|
||||
const V_PAYPHONE_STATE_ACTIVE_CALL = 3;
|
||||
const V_PAYPHONE_STATE_BROKEN = 4;
|
||||
const V_PAYPHONE_STATE_CALLING = 5;
|
||||
File diff suppressed because it is too large
Load Diff
44
scripts/shared/queue.js
Normal file
44
scripts/shared/queue.js
Normal file
@@ -0,0 +1,44 @@
|
||||
// ===========================================================================
|
||||
// Vortrex's Roleplay Resource
|
||||
// https://github.com/VortrexFTW/v-roleplay
|
||||
// ===========================================================================
|
||||
// FILE: queue.js
|
||||
// DESC: Provides simple queue functions
|
||||
// TYPE: Shared (JavaScript)
|
||||
// ===========================================================================
|
||||
|
||||
class QueueData {
|
||||
constructor(func, duration) {
|
||||
this.duration = duration;
|
||||
this.func = func;
|
||||
this.nextUp = null;
|
||||
|
||||
if (this.nextUp != null) {
|
||||
if (duration <= 0) {
|
||||
this.nextUp.func();
|
||||
} else {
|
||||
delayedFunction(this.nextUp.func, this.duration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
next(func, duration) {
|
||||
this.nextUp = createQueue(func, duration);
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function createQueue(func, duration) {
|
||||
return new QueueData(func, duration);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function delayedFunction(func, duration) {
|
||||
setTimeout(function () {
|
||||
func();
|
||||
}, duration);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -7,6 +7,14 @@
|
||||
// TYPE: Shared (JavaScript)
|
||||
// ===========================================================================
|
||||
|
||||
let dayHourStart = 6;
|
||||
let dayMinuteStart = 0;
|
||||
let dayMinuteWarningStart = 5;
|
||||
|
||||
let nightHourStart = 18;
|
||||
let nightMinuteStart = 0;
|
||||
let nightMinuteWarningStart = 5;
|
||||
|
||||
let emojiNumbers = ["➊", "➋", "➌", "➍", "➎", "➏", "➐", "➑", "➒"];
|
||||
//let emojiNumbers = ["①", "②", "③", "④", "⑤", "⑥", "⑦", "⑧", "⑨"];
|
||||
//let emojiNumbers = ["1️⃣", "2️⃣", "3️⃣", "4️⃣", "5️⃣", "6️⃣", "7️⃣", "8️⃣", "9️⃣"];
|
||||
@@ -1370,11 +1378,24 @@ let placesOfOrigin = [
|
||||
"Blaine County",
|
||||
"Red County",
|
||||
"Bone County",
|
||||
"Lost Heaven",
|
||||
"Empire Bay",
|
||||
"Other",
|
||||
];
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
let payPhoneStateNames = [
|
||||
"None/Unknown",
|
||||
"Idle",
|
||||
"Ringing",
|
||||
"Active Call",
|
||||
"Broken",
|
||||
"Calling"
|
||||
];
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function getGameConfig() {
|
||||
return gameData;
|
||||
}
|
||||
@@ -2303,25 +2324,31 @@ function removeHexColoursFromString(str) {
|
||||
// ===========================================================================
|
||||
|
||||
function removeSlashesFromString(str) {
|
||||
let matchRegex = /\//gi;
|
||||
str.replace(matchRegex, ``);
|
||||
if (str == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (str == "") {
|
||||
let matchRegex = /\//gi;
|
||||
str.replace(matchRegex, ``);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
async function waitUntil(condition) {
|
||||
return new Promise((resolve) => {
|
||||
let interval = setInterval(() => {
|
||||
if (!condition()) {
|
||||
return;
|
||||
}
|
||||
|
||||
clearInterval(interval);
|
||||
resolve();
|
||||
}, 1);
|
||||
});
|
||||
function waitUntil(condition) {
|
||||
//return new Promise((resolve) => {
|
||||
// let interval = setInterval(() => {
|
||||
// if (!condition()) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// clearInterval(interval);
|
||||
// resolve();
|
||||
// }, 1);
|
||||
//});
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -3208,7 +3235,7 @@ function fillLeadingZeros(number, length) {
|
||||
// ===========================================================================
|
||||
|
||||
function isMainWorldScene(sceneName) {
|
||||
return (sceneName == "v.rp.mainWorldScene");
|
||||
return (sceneName == "V.RP.MAINWORLD" || sceneName == "");
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
@@ -3225,11 +3252,11 @@ function isNightTime(hour) {
|
||||
|
||||
function isServerGoingToChangeMapsSoon(hour, minute) {
|
||||
if (server.mapName == "FREERIDENOC") {
|
||||
if (hour == 6 && minute >= 30) {
|
||||
return true
|
||||
if (hour == dayHourStart && minute < (dayMinuteStart - dayMinuteWarningStart)) {
|
||||
return true;
|
||||
}
|
||||
} else if (server.mapName == "FREERIDE") {
|
||||
if (hour == 18 && minute >= 30) {
|
||||
if (hour == dayHourStart && minute < (nightMinuteStart - nightMinuteWarningStart)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -3253,4 +3280,10 @@ function getWeatherData(weatherIndex, gameId = getGame()) {
|
||||
return getGameConfig().weather[gameId][weatherIndex];
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
function getPayPhoneStateName(state) {
|
||||
return payPhoneStateNames[state];
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
2
third-party/mexui/mexui.js
vendored
2
third-party/mexui/mexui.js
vendored
@@ -248,7 +248,7 @@ mexui.isAnyWindowShown = function () {
|
||||
mexui.setInput = function (showInput) {
|
||||
gui.showCursor(showInput, !showInput);
|
||||
|
||||
if (localClient.player && game.game >= GAME_GTA_IV) {
|
||||
if (localClient.player && game.game <= GAME_GTA_IV) {
|
||||
if (showInput)
|
||||
game.setCameraLookAtEntity(new Vec3(game.cameraMatrix.m41, game.cameraMatrix.m42, game.cameraMatrix.m43), localPlayer, false);
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user