new seatbelt script
This commit is contained in:
@@ -15,7 +15,7 @@
|
|||||||
<animConvRoofName>null</animConvRoofName>
|
<animConvRoofName>null</animConvRoofName>
|
||||||
<animConvRoofWindowsAffected />
|
<animConvRoofWindowsAffected />
|
||||||
<ptfxAssetName>null</ptfxAssetName>
|
<ptfxAssetName>null</ptfxAssetName>
|
||||||
<audioNameHash>GUARDIAN</audioNameHash>
|
<audioNameHash>kc80cumminsn14jake</audioNameHash>
|
||||||
<layout>LAYOUT_TRUCK</layout>
|
<layout>LAYOUT_TRUCK</layout>
|
||||||
<coverBoundOffsets>PHANTOM_COVER_OFFSET_INFO</coverBoundOffsets>
|
<coverBoundOffsets>PHANTOM_COVER_OFFSET_INFO</coverBoundOffsets>
|
||||||
<explosionInfo>EXPLOSION_INFO_TRUCK</explosionInfo>
|
<explosionInfo>EXPLOSION_INFO_TRUCK</explosionInfo>
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
static/*
|
||||||
|
!static/**/*.js
|
||||||
@@ -0,0 +1,172 @@
|
|||||||
|
{
|
||||||
|
"root": true,
|
||||||
|
"extends": ["eslint:recommended", "plugin:prettier/recommended"],
|
||||||
|
"parserOptions": {
|
||||||
|
"ecmaVersion": 2021
|
||||||
|
},
|
||||||
|
"env": {
|
||||||
|
"es2021": true,
|
||||||
|
"browser": true,
|
||||||
|
"jquery": true
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"prettier/prettier": [
|
||||||
|
2,
|
||||||
|
{
|
||||||
|
"printWidth": 120,
|
||||||
|
"singleQuote": true,
|
||||||
|
"quoteProps": "as-needed",
|
||||||
|
"trailingComma": "all",
|
||||||
|
"endOfLine": "lf",
|
||||||
|
"arrowParens": "avoid"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"strict": ["error", "global"],
|
||||||
|
"no-await-in-loop": "warn",
|
||||||
|
"no-compare-neg-zero": "error",
|
||||||
|
"no-template-curly-in-string": "error",
|
||||||
|
"no-unsafe-negation": "error",
|
||||||
|
"valid-jsdoc": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"requireReturn": false,
|
||||||
|
"requireReturnDescription": false,
|
||||||
|
"prefer": {
|
||||||
|
"return": "returns",
|
||||||
|
"arg": "param"
|
||||||
|
},
|
||||||
|
"preferType": {
|
||||||
|
"String": "string",
|
||||||
|
"Number": "number",
|
||||||
|
"Boolean": "boolean",
|
||||||
|
"Symbol": "symbol",
|
||||||
|
"object": "Object",
|
||||||
|
"function": "Function",
|
||||||
|
"array": "Array",
|
||||||
|
"date": "Date",
|
||||||
|
"error": "Error",
|
||||||
|
"null": "void"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
"accessor-pairs": "warn",
|
||||||
|
"array-callback-return": "error",
|
||||||
|
"consistent-return": "error",
|
||||||
|
"curly": ["error", "multi-line", "consistent"],
|
||||||
|
"dot-location": ["error", "property"],
|
||||||
|
"dot-notation": "error",
|
||||||
|
"eqeqeq": "error",
|
||||||
|
"no-empty-function": "error",
|
||||||
|
"no-floating-decimal": "error",
|
||||||
|
"no-implied-eval": "error",
|
||||||
|
"no-invalid-this": "error",
|
||||||
|
"no-lone-blocks": "error",
|
||||||
|
"no-multi-spaces": "error",
|
||||||
|
"no-new-func": "error",
|
||||||
|
"no-new-wrappers": "error",
|
||||||
|
"no-new": "error",
|
||||||
|
"no-octal-escape": "error",
|
||||||
|
"no-return-assign": "error",
|
||||||
|
"no-return-await": "error",
|
||||||
|
"no-self-compare": "error",
|
||||||
|
"no-sequences": "error",
|
||||||
|
"no-throw-literal": "error",
|
||||||
|
"no-unmodified-loop-condition": "error",
|
||||||
|
"no-unused-expressions": "error",
|
||||||
|
"no-useless-call": "error",
|
||||||
|
"no-useless-concat": "error",
|
||||||
|
"no-useless-escape": "error",
|
||||||
|
"no-useless-return": "error",
|
||||||
|
"no-void": "error",
|
||||||
|
"no-warning-comments": "warn",
|
||||||
|
"prefer-promise-reject-errors": "error",
|
||||||
|
"require-await": "warn",
|
||||||
|
"wrap-iife": "error",
|
||||||
|
"yoda": "error",
|
||||||
|
|
||||||
|
"no-label-var": "error",
|
||||||
|
"no-shadow": "error",
|
||||||
|
"no-undef-init": "error",
|
||||||
|
|
||||||
|
"callback-return": "error",
|
||||||
|
"getter-return": "off",
|
||||||
|
"handle-callback-err": "error",
|
||||||
|
"no-mixed-requires": "error",
|
||||||
|
"no-new-require": "error",
|
||||||
|
"no-path-concat": "error",
|
||||||
|
|
||||||
|
"array-bracket-spacing": "error",
|
||||||
|
"block-spacing": "error",
|
||||||
|
"brace-style": ["error", "1tbs", { "allowSingleLine": true }],
|
||||||
|
"capitalized-comments": ["error", "always", { "ignoreConsecutiveComments": true }],
|
||||||
|
"comma-dangle": ["error", "always-multiline"],
|
||||||
|
"comma-spacing": "error",
|
||||||
|
"comma-style": "error",
|
||||||
|
"computed-property-spacing": "error",
|
||||||
|
"consistent-this": ["error", "$this"],
|
||||||
|
"eol-last": "error",
|
||||||
|
"func-names": "error",
|
||||||
|
"func-name-matching": "error",
|
||||||
|
"func-style": ["error", "declaration", { "allowArrowFunctions": true }],
|
||||||
|
"key-spacing": "error",
|
||||||
|
"keyword-spacing": "error",
|
||||||
|
"max-depth": "error",
|
||||||
|
"max-len": ["error", 120, 2],
|
||||||
|
"max-nested-callbacks": ["error", { "max": 4 }],
|
||||||
|
"max-statements-per-line": ["error", { "max": 2 }],
|
||||||
|
"new-cap": "off",
|
||||||
|
"newline-per-chained-call": ["error", { "ignoreChainWithDepth": 3 }],
|
||||||
|
"no-array-constructor": "error",
|
||||||
|
"no-inline-comments": "error",
|
||||||
|
"no-lonely-if": "error",
|
||||||
|
"no-multiple-empty-lines": ["error", { "max": 2, "maxEOF": 1, "maxBOF": 0 }],
|
||||||
|
"no-new-object": "error",
|
||||||
|
"no-spaced-func": "error",
|
||||||
|
"no-trailing-spaces": "error",
|
||||||
|
"no-unneeded-ternary": "error",
|
||||||
|
"no-whitespace-before-property": "error",
|
||||||
|
"nonblock-statement-body-position": "error",
|
||||||
|
"object-curly-spacing": ["error", "always"],
|
||||||
|
"operator-assignment": "error",
|
||||||
|
"padded-blocks": ["error", "never"],
|
||||||
|
"quote-props": ["error", "as-needed"],
|
||||||
|
"quotes": ["error", "single", { "avoidEscape": true, "allowTemplateLiterals": true }],
|
||||||
|
"semi-spacing": "error",
|
||||||
|
"semi": "error",
|
||||||
|
"space-before-blocks": "error",
|
||||||
|
"space-before-function-paren": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"anonymous": "never",
|
||||||
|
"named": "never",
|
||||||
|
"asyncArrow": "always"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"space-in-parens": "error",
|
||||||
|
"space-infix-ops": "error",
|
||||||
|
"space-unary-ops": "error",
|
||||||
|
"spaced-comment": ["error", "always", { "markers": ["/"] }],
|
||||||
|
"template-tag-spacing": "error",
|
||||||
|
"unicode-bom": "error",
|
||||||
|
|
||||||
|
"arrow-body-style": "error",
|
||||||
|
"arrow-parens": ["error", "as-needed"],
|
||||||
|
"arrow-spacing": "error",
|
||||||
|
"no-duplicate-imports": "error",
|
||||||
|
"no-useless-computed-key": "error",
|
||||||
|
"no-useless-constructor": "error",
|
||||||
|
"prefer-arrow-callback": "error",
|
||||||
|
"prefer-numeric-literals": "error",
|
||||||
|
"prefer-rest-params": "error",
|
||||||
|
"prefer-spread": "error",
|
||||||
|
"prefer-template": "error",
|
||||||
|
"prefer-object-has-own": "error",
|
||||||
|
"rest-spread-spacing": "error",
|
||||||
|
"template-curly-spacing": "error",
|
||||||
|
"yield-star-spacing": "error"
|
||||||
|
},
|
||||||
|
"globals": {
|
||||||
|
"Howl": "readonly"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,132 @@
|
|||||||
|
config.lua
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
.pnpm-debug.log*
|
||||||
|
|
||||||
|
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||||
|
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
*.lcov
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# Bower dependency directory (https://bower.io/)
|
||||||
|
bower_components
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||||
|
build/Release
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules/
|
||||||
|
jspm_packages/
|
||||||
|
|
||||||
|
# Snowpack dependency directory (https://snowpack.dev/)
|
||||||
|
web_modules/
|
||||||
|
|
||||||
|
# TypeScript cache
|
||||||
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Optional stylelint cache
|
||||||
|
.stylelintcache
|
||||||
|
|
||||||
|
# Microbundle cache
|
||||||
|
.rpt2_cache/
|
||||||
|
.rts2_cache_cjs/
|
||||||
|
.rts2_cache_es/
|
||||||
|
.rts2_cache_umd/
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
|
.yarn-integrity
|
||||||
|
|
||||||
|
# dotenv environment variable files
|
||||||
|
.env
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
.env.local
|
||||||
|
|
||||||
|
# parcel-bundler cache (https://parceljs.org/)
|
||||||
|
.cache
|
||||||
|
.parcel-cache
|
||||||
|
|
||||||
|
# Next.js build output
|
||||||
|
.next
|
||||||
|
out
|
||||||
|
|
||||||
|
# Nuxt.js build / generate output
|
||||||
|
.nuxt
|
||||||
|
dist
|
||||||
|
|
||||||
|
# Gatsby files
|
||||||
|
.cache/
|
||||||
|
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||||
|
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||||
|
# public
|
||||||
|
|
||||||
|
# vuepress build output
|
||||||
|
.vuepress/dist
|
||||||
|
|
||||||
|
# vuepress v2.x temp and cache directory
|
||||||
|
.temp
|
||||||
|
.cache
|
||||||
|
|
||||||
|
# Docusaurus cache and generated files
|
||||||
|
.docusaurus
|
||||||
|
|
||||||
|
# Serverless directories
|
||||||
|
.serverless/
|
||||||
|
|
||||||
|
# FuseBox cache
|
||||||
|
.fusebox/
|
||||||
|
|
||||||
|
# DynamoDB Local files
|
||||||
|
.dynamodb/
|
||||||
|
|
||||||
|
# TernJS port file
|
||||||
|
.tern-port
|
||||||
|
|
||||||
|
# Stores VSCode versions used for testing VSCode extensions
|
||||||
|
.vscode-test
|
||||||
|
|
||||||
|
# yarn v2
|
||||||
|
.yarn/cache
|
||||||
|
.yarn/unplugged
|
||||||
|
.yarn/build-state.yml
|
||||||
|
.yarn/install-state.gz
|
||||||
|
.pnp.*
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
static/*
|
||||||
|
!static/**/*.css
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"extends": "stylelint-config-standard"
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
nodeLinker: node-modules
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2021 Reece Stokes
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
# Seatbelt
|
||||||
|
|
||||||
|
## About
|
||||||
|
|
||||||
|
A modern realisation on seatbelt scripts, for additional roleplay and realism to your server.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
- Install to your `resource` folder (or [download manually](https://github.com/TFNRP/seatbelt/archive/refs/heads/main.zip)):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/TFNRP/seatbelt.git
|
||||||
|
```
|
||||||
|
|
||||||
|
- (Optional) Copy `config.default.lua`, rename the copy to `config.lua` and edit it to your liking.
|
||||||
|
- Add the following to your `server.cfg`:
|
||||||
|
- `ensure seatbelt`
|
||||||
|
- (Optional) `add_ace group.police seatbelt.notify allow`
|
||||||
|
Replace `police` with your LEO group.
|
||||||
|
This is optional if you don't use ACL - read [Configuration](#configuration).
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
Modern Seatbelt does the following:
|
||||||
|
|
||||||
|
- Buckle up with `/seatbelt` or <kbd>K</kbd>.
|
||||||
|
- Keybinds can be changed in FiveM keybind settings.
|
||||||
|
- Quick unbuckle by pressing <kbd>Shift</kbd> + <kbd>F</kbd>.
|
||||||
|
- Heftier consequences for MVAs.
|
||||||
|
- Law enforcement notified of traffic violation
|
||||||
|
when driving behind (or crossing infront).
|
||||||
|
- Out-of-the-way notifications whilst driving
|
||||||
|
without seatbelt.
|
||||||
|
- Lightweight, out of the box.
|
||||||
|
- Supports the TFNRP framework.
|
||||||
|
- Realistic sound effects for buckling & driving w/o SB.
|
||||||
|
|
||||||
|
## Coming Soon
|
||||||
|
|
||||||
|
Features that are planned for Modern Seatbelt:
|
||||||
|
|
||||||
|
- Complimentary scripts for compatible UI support.
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
> Note: Do not edit `config.default.lua`
|
||||||
|
|
||||||
|
Copy `config.default.lua` and rename the copy to `config.lua`.
|
||||||
|
Check [config.lua](https://github.com/TFNRP/seatbelt/blob/main/config.default.lua) for better details.
|
||||||
|
|
||||||
|
property | description
|
||||||
|
-- | --
|
||||||
|
`LeoCheck` = `2` | The method this script should use to check whether a player is an (on-duty) LEO.</br>`1` = be inside a police vehicle; or</br>`2` = have the `seatbelt.notify` ACL.
|
||||||
|
`PlayerIdentifierType` = `1` | What type of LEO notifications should be shown?</br>`1` = Player ID (i.e. "Player 7")</br>`2` = Seat position (i.e. "Driver", "Passenger", "Rear left passenger", "Far rear left passenger")</br>`3` = Username (i.e. "Hagen Hyena", "1D-32 Backer P.")
|
||||||
|
`Distance` = `20` | The amount of distance LEOs have to be to detect people not weaing a seatbelt.
|
||||||
|
`DefaultKeybind` = `K` | The default seatbelt keybind.
|
||||||
|
`Excluded` | A list of excluded vehicles and vehicle seats.
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
[Reports issues and create suggestions](https://github.com/TFNRP/seatbelt/issues).
|
||||||
|
[Improve code, fix issues and add suggestions](https://github.com/TFNRP/seatbelt/pulls).
|
||||||
|
|
||||||
|
## Credits & Copyright
|
||||||
|
|
||||||
|
- [@TehRamsus](https://forum.cfx.re/u/TehRamsus) for their [Seatbelt](https://github.com/TehRamsus/Seatbelt) script, which inspired me to create Modern Seatbelt.
|
||||||
|
- [@Mercy3](https://forum.cfx.re/u/Mercy3) for providing and giving permission of use of `static/assets/{buckle,chime,unbuckle}.ogg` files.
|
||||||
|
|
||||||
|
Licensed under [MIT License](https://github.com/TFNRP/seatbelt/blob/main/LICENSE). No code or assets of the inspiring work has been used.
|
||||||
|
The author of [Seatbelt](https://github.com/TehRamsus/Seatbelt) stated they would rework their original work but has not done so since Oct 25th, '21, hence my release.
|
||||||
@@ -0,0 +1,177 @@
|
|||||||
|
local showingWarning = false
|
||||||
|
local lastSpeed = 0
|
||||||
|
local lastVelocity = vector3(0, 0, 0)
|
||||||
|
local newbieBeep = true
|
||||||
|
local showHelp = false
|
||||||
|
local activated
|
||||||
|
local hasSeatbelt
|
||||||
|
|
||||||
|
RegisterKeyMapping('seatbelt', 'Seatbelt', 'keyboard', Constants.DefaultKeybind)
|
||||||
|
RegisterFrameworkCommand('seatbelt', function()
|
||||||
|
local ped = PlayerPedId()
|
||||||
|
if IsPedInAnyVehicle(ped) then
|
||||||
|
local vehcileHasSeatbelt, strong = DoesPedVehicleHaveSeatbelt(ped)
|
||||||
|
if vehcileHasSeatbelt and not strong then
|
||||||
|
if activated then
|
||||||
|
DeactivateSeatbelt()
|
||||||
|
else
|
||||||
|
ActivateSeatbelt()
|
||||||
|
end
|
||||||
|
SendNuiMessage('{"t":0,"d":' .. (activated == true and '1' or '0') .. '}')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
function ActivateSeatbelt()
|
||||||
|
if activated == true then
|
||||||
|
return error('seatbelt attempted to activate when already active.')
|
||||||
|
end
|
||||||
|
-- compat for other resources like carhud
|
||||||
|
TriggerEvent('seatbelt:stateChange', true)
|
||||||
|
|
||||||
|
-- disable exit keys
|
||||||
|
Citizen.CreateThread(function()
|
||||||
|
while activated do
|
||||||
|
Citizen.Wait(1)
|
||||||
|
DisableControlAction(0, 75, true)
|
||||||
|
DisableControlAction(27, 75, true)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- quick unbuckled
|
||||||
|
Citizen.CreateThread(function()
|
||||||
|
while activated do
|
||||||
|
Citizen.Wait(1)
|
||||||
|
if IsDisabledControlJustPressed(0, 75) and IsControlPressed(0, 21) then
|
||||||
|
DeactivateSeatbelt()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- validation
|
||||||
|
Citizen.CreateThread(function()
|
||||||
|
while activated do
|
||||||
|
if not IsPedInAnyVehicle(PlayerPedId()) then
|
||||||
|
DeactivateSeatbelt()
|
||||||
|
end
|
||||||
|
Citizen.Wait(50)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
activated = true
|
||||||
|
end
|
||||||
|
|
||||||
|
function DeactivateSeatbelt()
|
||||||
|
if activated == false then
|
||||||
|
return error('seatbelt attempted to deactivate when already deactivated.')
|
||||||
|
end
|
||||||
|
TriggerEvent('seatbelt:stateChange', false)
|
||||||
|
|
||||||
|
-- help text separate from hud
|
||||||
|
Citizen.CreateThread(function()
|
||||||
|
while not activated do
|
||||||
|
if showHelp then
|
||||||
|
local message = '~BLIP_GANG_VEHICLE~ Press ~INPUT_REPLAY_SHOWHOTKEY~ to ~y~buckle~s~ your seatbelt.'
|
||||||
|
ShowHelpText(message, newbieBeep)
|
||||||
|
newbieBeep = false
|
||||||
|
for _ = 0, 8 do
|
||||||
|
Citizen.Wait(5)
|
||||||
|
ShowHelpText(message, false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
Citizen.Wait(65)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- handling and HUD
|
||||||
|
Citizen.CreateThread(function()
|
||||||
|
while not activated do
|
||||||
|
local ped = PlayerPedId()
|
||||||
|
if IsPedInAnyVehicle(ped) then
|
||||||
|
local _hasSeatbelt, strong = DoesPedVehicleHaveSeatbelt(ped)
|
||||||
|
hasSeatbelt = _hasSeatbelt
|
||||||
|
if hasSeatbelt and not strong then
|
||||||
|
local vehicle = GetVehiclePedIsIn(ped)
|
||||||
|
local speed = GetEntitySpeed(vehicle)
|
||||||
|
|
||||||
|
if speed > (50 / 3.6) and (lastSpeed - speed) > (speed * .2) then
|
||||||
|
local coords = GetEntityCoords(ped)
|
||||||
|
local fw = Fwv(ped)
|
||||||
|
ForceStopWarning()
|
||||||
|
showHelp = false
|
||||||
|
SetEntityCoords(ped, coords.x + fw.x, coords.y + fw.y, coords.z - .47, true, true, true)
|
||||||
|
SetEntityVelocity(ped, lastVelocity.x, lastVelocity.y, lastVelocity.z)
|
||||||
|
SetPedToRagdoll(ped, 1e3, 1e3, 0, false, false, false)
|
||||||
|
elseif speed > (20 / 3.6) then
|
||||||
|
SetWarning(true)
|
||||||
|
showHelp = not (IsPauseMenuActive() or IsHudHidden() or IsPlayerDead(PlayerId()))
|
||||||
|
else
|
||||||
|
SetWarning(false)
|
||||||
|
showHelp = false
|
||||||
|
end
|
||||||
|
|
||||||
|
lastSpeed = speed
|
||||||
|
lastVelocity = GetEntityVelocity(vehicle)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
ForceStopWarning()
|
||||||
|
showHelp = false
|
||||||
|
end
|
||||||
|
Citizen.Wait(50)
|
||||||
|
end
|
||||||
|
|
||||||
|
SetWarning(false)
|
||||||
|
showHelp = false
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- notification
|
||||||
|
Citizen.CreateThread(function()
|
||||||
|
while not activated do
|
||||||
|
local ped = PlayerPedId()
|
||||||
|
local vehicle = GetVehiclePedIsIn(ped)
|
||||||
|
if IsPedInAnyVehicle(ped) and hasSeatbelt and GetEntitySpeed(vehicle) * 3.6 > 10 then
|
||||||
|
TriggerServerEvent('seatbelt:ServerNotify')
|
||||||
|
end
|
||||||
|
Citizen.Wait(3e3)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
activated = false
|
||||||
|
end
|
||||||
|
|
||||||
|
function SetWarning(bool)
|
||||||
|
if bool ~= showingWarning then
|
||||||
|
SendNuiMessage('{"t":1,"d":' .. (bool == true and '1' or '0') .. '}')
|
||||||
|
showingWarning = bool
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function ForceStopWarning()
|
||||||
|
if showingWarning then
|
||||||
|
SendNuiMessage('{"t":1,"d":3}')
|
||||||
|
showingWarning = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
RegisterNetEvent('seatbelt:ClientNotify', function(serverId)
|
||||||
|
local ped = PlayerPedId()
|
||||||
|
local player = GetPlayerFromServerId(serverId) -- onesync notice: returns -1 if not loaded
|
||||||
|
local playerPed = GetPlayerPed(player)
|
||||||
|
if player ~= PlayerId() and player > 0 and IsLEO() and not IsHudHidden() and IsPedInAnyVehicle(playerPed) then
|
||||||
|
local vehicle = GetVehiclePedIsIn(playerPed)
|
||||||
|
local identifier = GetPlayerIdentifier_(serverId, playerPed, vehicle)
|
||||||
|
if #(GetEntityCoords(ped) - GetEntityCoords(GetPlayerPed(player))) < Constants.Distance and identifier then
|
||||||
|
ShowNotification(
|
||||||
|
identifier ..
|
||||||
|
' is not weaing a seatbelt in <C>~y~' ..
|
||||||
|
GetVehicleNumberPlateText(vehicle) ..
|
||||||
|
'~s~</C>.'
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
Citizen.CreateThread(function()
|
||||||
|
DeactivateSeatbelt()
|
||||||
|
end)
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
-- Do not edit config.default.lua
|
||||||
|
-- Copy config.default.lua and rename the copy to config.lua
|
||||||
|
|
||||||
|
--- Configuration variables
|
||||||
|
--- @type {}
|
||||||
|
Config = {}
|
||||||
|
|
||||||
|
--- The method that should be used to check whether a player is an on-duty LEO.
|
||||||
|
--- For a player to receive an LEO notification, they must
|
||||||
|
--- - `1` = be inside a police vehicle; or
|
||||||
|
--- - `2` = have the `seatbelt.notify` ACL.
|
||||||
|
--- @type 1 | 2
|
||||||
|
Config.LeoCheck = 2
|
||||||
|
|
||||||
|
--- Changes how players are identified to LEOs. Cannot be nilish
|
||||||
|
--- - `1` = Player ID (i.e. "Player 7")
|
||||||
|
--- - `2` = Seat position (i.e. "Driver", "Passenger", "Rear left passenger", "Far rear left passenger")
|
||||||
|
--- - `3` = Username (i.e. "Hagen Hyena", "1D-32 Backer P.")
|
||||||
|
--- @type 1 | 2 | 3
|
||||||
|
Config.PlayerIdentifierType = 1
|
||||||
|
|
||||||
|
--- Distance which LEOs can detect seatbelt-less occupants within.
|
||||||
|
--- @type number -- A postive number
|
||||||
|
Config.Distance = 20
|
||||||
|
|
||||||
|
--- The default seatbelt keybind.
|
||||||
|
--- After a player joins, their keybind will not change if
|
||||||
|
--- the default keybind changes.
|
||||||
|
--- Players can manually change this keybind in their settings.
|
||||||
|
--- @type string
|
||||||
|
--- @see {@link https://docs.fivem.net/docs/game-references/input-mapper-parameter-ids/keyboard}
|
||||||
|
Config.DefaultKeybind = 'K'
|
||||||
|
|
||||||
|
--- Custom vehicles/seats that don't have seatbelts.
|
||||||
|
--- Bicycles, motorbikes and submersibles are excluded automatically
|
||||||
|
--- - `1` = Seatbelt always off, windscreen ejection still occurs
|
||||||
|
--- - `2` = Seatbelt always on, ejection is never calculated
|
||||||
|
--- @type table<hash, (1 | 2) | table<number, 1 | 2>>
|
||||||
|
Config.Excluded = {
|
||||||
|
[GetHashKey('MINITANK')] = 2, -- Seatbelt always on.
|
||||||
|
[GetHashKey('HALFTRACK')] = { [3] = 1 }, -- Seat #3 has no seatbelt.
|
||||||
|
[GetHashKey('KHANJALI')] = 2,
|
||||||
|
[GetHashKey('APC')] = 2,
|
||||||
|
[GetHashKey('THRUSTER')] = 2,
|
||||||
|
[GetHashKey('RHINO')] = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
--- A model hash key
|
||||||
|
--- @alias hash number
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
fx_version 'cerulean'
|
||||||
|
game 'gta5'
|
||||||
|
|
||||||
|
repository 'https://github.com/TFNRP/seatbelt'
|
||||||
|
fork_repository 'https://github.com/TehRamsus/Seatbelt'
|
||||||
|
version '1.2.1'
|
||||||
|
author 'Reece Stokes <hagen@hyena.gay>'
|
||||||
|
|
||||||
|
client_script {
|
||||||
|
'@framework/util.lua',
|
||||||
|
'config.default.lua',
|
||||||
|
'config.lua',
|
||||||
|
'util.lua',
|
||||||
|
'client.lua',
|
||||||
|
}
|
||||||
|
server_script 'server.lua'
|
||||||
|
ui_page 'static/index.html'
|
||||||
|
file 'static/**'
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"name": "seatbelt",
|
||||||
|
"version": "1.2.1",
|
||||||
|
"license": "MIT",
|
||||||
|
"author": "Reece Stokes <hagen@hyena.gay>",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"test": "eslint static && stylelint static",
|
||||||
|
"lint": "eslint static && stylelint static",
|
||||||
|
"lint:fix": "eslint static --fix && stylelint static --fix"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/TFNRP/seatbelt.git"
|
||||||
|
},
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/TFNRP/seatbelt/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/TFNRP/seatbelt#readme",
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/howler": "^2.2.7",
|
||||||
|
"@types/jquery": "^3.5.16",
|
||||||
|
"eslint": "^8.46.0",
|
||||||
|
"eslint-config-prettier": "^8.9.0",
|
||||||
|
"eslint-plugin-prettier": "^5.0.0",
|
||||||
|
"prettier": "^3.0.0",
|
||||||
|
"stylelint": "^14.16.1",
|
||||||
|
"stylelint-config-standard": "^24.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
RegisterNetEvent('seatbelt:ServerNotify', function()
|
||||||
|
TriggerClientEvent('seatbelt:ClientNotify', -1, source)
|
||||||
|
end)
|
||||||
|
|
||||||
|
RegisterNetEvent('seatbelt:ServerHasAce', function()
|
||||||
|
TriggerClientEvent('seatbelt:ClientHasAce', source, IsPlayerAceAllowed(source, 'seatbelt.notify'))
|
||||||
|
end)
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,22 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<script src="https://nui-game-internal/ui/jquery.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/howler/2.2.3/howler.min.js"
|
||||||
|
integrity="sha512-6+YN/9o9BWrk6wSfGxQGpt3EUK6XeHi6yeHV+TYD2GR0Sj/cggRpXr1BrAQf0as6XslxomMUxXp2vIl+fv0QRA=="
|
||||||
|
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
<script src="./index.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="ui">
|
||||||
|
<svg id="seatbelt" xmlns="http://www.w3.org/2000/svg" role="img" viewBox="0 0 24 24">
|
||||||
|
<path d="M12,2C13.11,2 14,2.9 14,4C14,5.11 13.11,6 12,6A2,2 0 0,1 10,4A2,2 0 0,1 12,2M12.39,14.79C14.03,14.79 15.46,14.89 16.64,15.04C16.7,12.32 16.46,9.92 16,9C15.87,8.73 15.69,8.5 15.5,8.3L7.43,15.22C8.79,15 10.5,14.79 12.39,14.79M7.46,17C7.59,18.74 7.85,20.5 8.27,22H10.34C10.05,21.12 9.84,20.09 9.68,19C9.68,19 12,18.56 14.32,19C14.16,20.09 13.95,21.12 13.66,22H15.73C16.17,20.45 16.43,18.61 16.56,16.79C15.41,16.65 14,16.54 12.39,16.54C10.46,16.54 8.78,16.75 7.46,17M12,7C12,7 9,7 8,9C7.66,9.68 7.44,11.15 7.37,12.96L13.92,7.34C12.93,7 12,7 12,7M18.57,5.67L17.43,4.34L13.92,7.35C14.47,7.54 15.05,7.84 15.5,8.3L18.57,5.67M20.67,15.83C20.58,15.8 19.14,15.33 16.64,15.04C16.63,15.61 16.6,16.2 16.56,16.79C18.81,17.07 20.1,17.5 20.12,17.5L20.67,15.83M7.37,12.96L3.43,16.34L4.32,17.82C4.34,17.81 5.5,17.36 7.46,17C7.35,15.59 7.32,14.2 7.37,12.96Z"/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
/// <reference types="howler"/>
|
||||||
|
/// <reference types="jquery"/>
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const sounds = {
|
||||||
|
buckle: new Howl({ src: ['./assets/buckle.ogg'] }),
|
||||||
|
chime: new Howl({ src: ['./assets/chime.ogg'] }),
|
||||||
|
unbluckle: new Howl({ src: ['./assets/unbuckle.ogg'] }),
|
||||||
|
};
|
||||||
|
const buckle = [sounds.unbluckle, sounds.buckle];
|
||||||
|
|
||||||
|
$(() => {
|
||||||
|
const top = $('#seatbelt').css('top');
|
||||||
|
|
||||||
|
const enableIcon = () => {
|
||||||
|
const ui = $('#ui');
|
||||||
|
ui.stop(true, true);
|
||||||
|
ui.css('display', 'flex');
|
||||||
|
$('#seatbelt').animate(
|
||||||
|
{
|
||||||
|
top,
|
||||||
|
opacity: '1.0',
|
||||||
|
},
|
||||||
|
700,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const disableIcon = () => {
|
||||||
|
const ui = $('#ui');
|
||||||
|
ui.stop(true, true);
|
||||||
|
$('#seatbelt').animate(
|
||||||
|
{
|
||||||
|
top: '100vw',
|
||||||
|
opacity: '0.0',
|
||||||
|
},
|
||||||
|
700,
|
||||||
|
() => ui.css('display', 'none'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
sounds.chime.on('play', enableIcon);
|
||||||
|
sounds.chime.on('stop', disableIcon);
|
||||||
|
sounds.chime.on('end', () => {
|
||||||
|
if (!sounds.chime.loop()) disableIcon();
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener('message', event => {
|
||||||
|
const payload = event.data;
|
||||||
|
|
||||||
|
switch (payload.t) {
|
||||||
|
case 0: {
|
||||||
|
const data = payload.d;
|
||||||
|
let playing;
|
||||||
|
// If another sound is already playing, play the new sound from the reverse of the elapsed time
|
||||||
|
if ((playing = buckle.find(sound => sound.playing()))) {
|
||||||
|
const seek = buckle[data].duration() - playing.seek() - 0.423764;
|
||||||
|
playing.stop();
|
||||||
|
buckle[data].play();
|
||||||
|
if (seek > 0) buckle[data].seek(seek);
|
||||||
|
} else {
|
||||||
|
buckle[data].play();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 1: {
|
||||||
|
switch (payload.d) {
|
||||||
|
case 1:
|
||||||
|
sounds.chime.loop(true);
|
||||||
|
if (!sounds.chime.playing())
|
||||||
|
sounds.chime.play();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
sounds.chime.stop();
|
||||||
|
sounds.unbluckle.stop();
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
sounds.chime.loop(false);
|
||||||
|
break;
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
<svg id="seatbelt" xmlns="http://www.w3.org/2000/svg" role="img" viewBox="0 0 24 24">
|
||||||
|
<path d="M12,2C13.11,2 14,2.9 14,4C14,5.11 13.11,6 12,6A2,2 0 0,1 10,4A2,2 0 0,1 12,2M12.39,14.79C14.03,14.79 15.46,14.89 16.64,15.04C16.7,12.32 16.46,9.92 16,9C15.87,8.73 15.69,8.5 15.5,8.3L7.43,15.22C8.79,15 10.5,14.79 12.39,14.79M7.46,17C7.59,18.74 7.85,20.5 8.27,22H10.34C10.05,21.12 9.84,20.09 9.68,19C9.68,19 12,18.56 14.32,19C14.16,20.09 13.95,21.12 13.66,22H15.73C16.17,20.45 16.43,18.61 16.56,16.79C15.41,16.65 14,16.54 12.39,16.54C10.46,16.54 8.78,16.75 7.46,17M12,7C12,7 9,7 8,9C7.66,9.68 7.44,11.15 7.37,12.96L13.92,7.34C12.93,7 12,7 12,7M18.57,5.67L17.43,4.34L13.92,7.35C14.47,7.54 15.05,7.84 15.5,8.3L18.57,5.67M20.67,15.83C20.58,15.8 19.14,15.33 16.64,15.04C16.63,15.61 16.6,16.2 16.56,16.79C18.81,17.07 20.1,17.5 20.12,17.5L20.67,15.83M7.37,12.96L3.43,16.34L4.32,17.82C4.34,17.81 5.5,17.36 7.46,17C7.35,15.59 7.32,14.2 7.37,12.96Z"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 944 B |
@@ -0,0 +1,23 @@
|
|||||||
|
body {
|
||||||
|
user-select: none;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ui {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes blink {
|
||||||
|
0% { opacity: 1; }
|
||||||
|
50% { opacity: 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
svg {
|
||||||
|
position: absolute;
|
||||||
|
animation: blink normal 1s infinite ease-in-out;
|
||||||
|
fill: red;
|
||||||
|
top: 42.1vw;
|
||||||
|
left: 15.4vw;
|
||||||
|
width: 3vw;
|
||||||
|
height: 3vw;
|
||||||
|
}
|
||||||
@@ -0,0 +1,141 @@
|
|||||||
|
if RegisterFrameworkCommand == nil then
|
||||||
|
-- polyfill
|
||||||
|
RegisterFrameworkCommand = function (name, handler, restricted)
|
||||||
|
if type(name) == 'table' then
|
||||||
|
for _, c in ipairs(name) do
|
||||||
|
RegisterFrameworkCommand(c, handler, restricted)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
RegisterCommand(name, handler, restricted)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if GetConvar('tfnrp_framework_init', 'false') == 'true' then
|
||||||
|
IsHudHidden = exports.framework.IsHudHidden
|
||||||
|
function IsLEO()
|
||||||
|
return exports.framework:GetLocalClientDuty() > 0
|
||||||
|
end
|
||||||
|
else
|
||||||
|
function IsHudHidden()
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
if (Config.LeoCheck == 2) then
|
||||||
|
local has_ace = false
|
||||||
|
local update = true
|
||||||
|
|
||||||
|
function IsLEO()
|
||||||
|
if (update) then
|
||||||
|
TriggerServerEvent('seatbelt:ServerHasAce')
|
||||||
|
update = false
|
||||||
|
Citizen.SetTimeout(12e3, function ()
|
||||||
|
update = true
|
||||||
|
end)
|
||||||
|
|
||||||
|
while update == false do
|
||||||
|
Citizen.Wait(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
update = false
|
||||||
|
end
|
||||||
|
|
||||||
|
return has_ace
|
||||||
|
end
|
||||||
|
|
||||||
|
RegisterNetEvent('seatbelt:ClientHasAce', function(bool)
|
||||||
|
has_ace = bool
|
||||||
|
update = true
|
||||||
|
end)
|
||||||
|
else
|
||||||
|
if (Config.LeoCheck ~= 1) then
|
||||||
|
Citizen.Trace('Config.LeoCheck was not set correctly, using police vehicle check instead')
|
||||||
|
end
|
||||||
|
function IsLEO()
|
||||||
|
return IsPedInAnyPoliceVehicle(PlayerPedId())
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Config.LeoCheck = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- config setup
|
||||||
|
Constants = {
|
||||||
|
Distance = Config.Distance + 0.0,
|
||||||
|
Excluded = Config.Excluded,
|
||||||
|
DefaultKeybind = Config.DefaultKeybind,
|
||||||
|
}
|
||||||
|
|
||||||
|
local GetPlayerIdentifierMethods = {
|
||||||
|
function(serverId)
|
||||||
|
return '<C>Player ' .. serverId .. '</C>'
|
||||||
|
end,
|
||||||
|
function(_, playerPed, vehicle)
|
||||||
|
local hash = GetEntityModel(vehicle)
|
||||||
|
local seats = GetVehicleModelNumberOfSeats(hash)
|
||||||
|
local names = {
|
||||||
|
'Driver',
|
||||||
|
'Passenger',
|
||||||
|
'Rear left passenger',
|
||||||
|
'Rear right passenger',
|
||||||
|
'Far rear left passenger',
|
||||||
|
'Far rear right passenger',
|
||||||
|
}
|
||||||
|
for seat = 1, math.min(#names, seats) do
|
||||||
|
if GetPedInVehicleSeat(vehicle, seat - 2) == playerPed then
|
||||||
|
return names[seat]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
function(serverId)
|
||||||
|
return '<C>' .. GetPlayerName(serverId) .. '</C>'
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
--- GetPlayerIdentifier is a reserved namespace
|
||||||
|
GetPlayerIdentifier_ = GetPlayerIdentifierMethods[Config.PlayerIdentifierType]
|
||||||
|
|
||||||
|
GetPlayerIdentifierMethods = nil
|
||||||
|
Config = nil
|
||||||
|
|
||||||
|
function DoesPedVehicleHaveSeatbelt(ped)
|
||||||
|
if not IsPedInAnyVehicle(ped)
|
||||||
|
or IsPedOnAnyBike(ped)
|
||||||
|
or IsPedInAnyBoat(ped)
|
||||||
|
or IsPedInAnyPlane(ped)
|
||||||
|
or IsPedInAnyHeli(ped)
|
||||||
|
then return false, false end
|
||||||
|
|
||||||
|
local vehicle = GetVehiclePedIsIn(ped)
|
||||||
|
local model = GetEntityModel(vehicle)
|
||||||
|
if Constants.Excluded[model] then
|
||||||
|
if Constants.Excluded[model] == 2 then
|
||||||
|
return true, true
|
||||||
|
elseif type(Constants.Excluded[model]) == 'table' then
|
||||||
|
for seat, type in pairs(Constants.Excluded[model]) do
|
||||||
|
if GetPedInVehicleSeat(vehicle, seat - 2) == ped then
|
||||||
|
return false, type == 2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true, false
|
||||||
|
end
|
||||||
|
|
||||||
|
function Fwv(entity)
|
||||||
|
local hr = GetEntityHeading(entity) + 90.0
|
||||||
|
if hr < 0.0 then hr = 360.0 + hr end
|
||||||
|
hr = hr * 0.0174533
|
||||||
|
return { x = math.cos(hr) * 2.0, y = math.sin(hr) * 2.0 }
|
||||||
|
end
|
||||||
|
|
||||||
|
function ShowNotification(string)
|
||||||
|
BeginTextCommandThefeedPost('STRING')
|
||||||
|
AddTextComponentSubstringPlayerName(string)
|
||||||
|
EndTextCommandThefeedPostTicker(true, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
function ShowHelpText(text, beep)
|
||||||
|
SetTextComponentFormat('STRING')
|
||||||
|
AddTextComponentSubstringPlayerName(text)
|
||||||
|
EndTextCommandDisplayHelp(0, 0, beep, -1)
|
||||||
|
end
|
||||||
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -229,7 +229,7 @@ ensure scully_lawenforcement
|
|||||||
ensure VehicleTrustSystem-master
|
ensure VehicleTrustSystem-master
|
||||||
ensure LSRPC-K9
|
ensure LSRPC-K9
|
||||||
ensure 5500wrecker
|
ensure 5500wrecker
|
||||||
ensure seatbelt-1.2.1
|
ensure seatbelt
|
||||||
|
|
||||||
***EUPCLOTHING***
|
***EUPCLOTHING***
|
||||||
ensure eup-stream
|
ensure eup-stream
|
||||||
|
|||||||
Reference in New Issue
Block a user