diff --git a/_resources/esx_policejob/.editorconfig b/_resources/esx_policejob/.editorconfig
new file mode 100644
index 00000000..9b425256
--- /dev/null
+++ b/_resources/esx_policejob/.editorconfig
@@ -0,0 +1,9 @@
+root = true
+
+[*]
+indent_size = 4
+indent_style = tab
+end_of_line = crlf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
\ No newline at end of file
diff --git a/_resources/esx_policejob/LICENSE b/_resources/esx_policejob/LICENSE
new file mode 100644
index 00000000..49c66f5e
--- /dev/null
+++ b/_resources/esx_policejob/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ fxserver-esx_policejob
+ Copyright (C) 2015 Jérémie N'gadi
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ fxserver-esx_policejob Copyright (C) 2015 Jérémie N'gadi
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
\ No newline at end of file
diff --git a/_resources/esx_policejob/README.md b/_resources/esx_policejob/README.md
new file mode 100644
index 00000000..16504542
--- /dev/null
+++ b/_resources/esx_policejob/README.md
@@ -0,0 +1,68 @@
+# esx_policejob
+
+This resource for ESX adds police armories, vehicle garages and ability for cops to search, handcuff people and much more.
+
+### Requirements
+* Auto mode
+ * [esx_billing](https://github.com/ESX-Org/esx_billing)
+ * [esx_vehicleshop](https://github.com/ESX-Org/esx_vehicleshop)
+
+* Player management (boss actions and armory with buyable weapons)
+ * [esx_addoninventory](https://github.com/ESX-Org/esx_addoninventory)
+ * [esx_datastore](https://github.com/ESX-Org/esx_datastore)
+ * [esx_society](https://github.com/ESX-Org/esx_society)
+
+* ESX Identity Support
+ * [esx_identity](https://github.com/ESX-Org/esx_identity)
+
+* ESX License Support
+ * [esx_license](https://github.com/ESX-Org/esx_license)
+
+* ESX Service Support
+ * [esx_service](https://github.com/ESX-Org/esx_service)
+
+* ESX Status Support
+ * [esx_status](https://github.com/ESX-Org/esx_status)
+
+## Download & Installation
+
+### Using [fvm](https://github.com/qlaffont/fvm-installer)
+```
+fvm install --save --folder=esx esx-org/esx_policejob
+```
+
+### Using Git
+```
+cd resources
+git clone https://github.com/ESX-Org/esx_policejob [esx]/esx_policejob
+```
+
+### Manually
+- Download https://github.com/ESX-Org/esx_policejob/archive/master.zip
+- Put it in the `[esx]` directory
+
+
+## Installation
+- Import `esx_policejob.sql` in your database
+- Add this to your server.cfg:
+
+```
+start esx_policejob
+```
+
+- * If you want player management you have to set `Config.EnablePlayerManagement` to `true` in `config.lua`
+ * If you want armory management you have to set `Config.EnableArmoryManagement` to `true` in `config.lua`
+ * If you want license management you have to set `Config.EnableLicenses` to `true` in `config.lua`
+ * If you want service management you have to set `Config.MaxInService` to a higher value than `-1` in `config.lua`
+
+# Legal
+### License
+esx_policejob - police script for ESX
+
+Copyright (C) 2015-2020 Jérémie N'gadi
+
+This program Is free software: you can redistribute it And/Or modify it under the terms Of the GNU General Public License As published by the Free Software Foundation, either version 3 Of the License, Or (at your option) any later version.
+
+This program Is distributed In the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty Of MERCHANTABILITY Or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License For more details.
+
+You should have received a copy Of the GNU General Public License along with this program. If Not, see http://www.gnu.org/licenses/.
diff --git a/_resources/esx_policejob/client/main.lua b/_resources/esx_policejob/client/main.lua
new file mode 100644
index 00000000..4ae3bf3a
--- /dev/null
+++ b/_resources/esx_policejob/client/main.lua
@@ -0,0 +1,1576 @@
+local CurrentActionData, handcuffTimer, dragStatus, blipsCops, currentTask = {}, {}, {}, {}, {}
+local HasAlreadyEnteredMarker, isDead, isHandcuffed, hasAlreadyJoined, playerInService = false, false, false, false, false
+local LastStation, LastPart, LastPartNum, LastEntity, CurrentAction, CurrentActionMsg
+dragStatus.isDragged, isInShopMenu = false, false
+ESX = nil
+
+Citizen.CreateThread(function()
+ while ESX == nil do
+ TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)
+ Citizen.Wait(0)
+ end
+
+ while ESX.GetPlayerData().job == nil do
+ Citizen.Wait(10)
+ end
+
+ ESX.PlayerData = ESX.GetPlayerData()
+end)
+
+function cleanPlayer(playerPed)
+ SetPedArmour(playerPed, 0)
+ ClearPedBloodDamage(playerPed)
+ ResetPedVisibleDamage(playerPed)
+ ClearPedLastWeaponDamage(playerPed)
+ ResetPedMovementClipset(playerPed, 0)
+end
+
+function setUniform(uniform, playerPed)
+ TriggerEvent('skinchanger:getSkin', function(skin)
+ local uniformObject
+
+ if skin.sex == 0 then
+ uniformObject = Config.Uniforms[uniform].male
+ else
+ uniformObject = Config.Uniforms[uniform].female
+ end
+
+ if uniformObject then
+ TriggerEvent('skinchanger:loadClothes', skin, uniformObject)
+
+ if uniform == 'bullet_wear' then
+ SetPedArmour(playerPed, 100)
+ end
+ else
+ ESX.ShowNotification(_U('no_outfit'))
+ end
+ end)
+end
+
+function OpenCloakroomMenu()
+ local playerPed = PlayerPedId()
+ local grade = ESX.PlayerData.job.grade_name
+
+ local elements = {
+ {label = _U('citizen_wear'), value = 'citizen_wear'},
+ {label = _U('bullet_wear'), uniform = 'bullet_wear'},
+ {label = _U('gilet_wear'), uniform = 'gilet_wear'},
+ {label = _U('police_wear'), uniform = grade}
+ }
+
+ if Config.EnableCustomPeds then
+ for k,v in ipairs(Config.CustomPeds.shared) do
+ table.insert(elements, {label = v.label, value = 'freemode_ped', maleModel = v.maleModel, femaleModel = v.femaleModel})
+ end
+
+ for k,v in ipairs(Config.CustomPeds[grade]) do
+ table.insert(elements, {label = v.label, value = 'freemode_ped', maleModel = v.maleModel, femaleModel = v.femaleModel})
+ end
+ end
+
+ ESX.UI.Menu.CloseAll()
+
+ ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'cloakroom', {
+ title = _U('cloakroom'),
+ align = 'top-left',
+ elements = elements
+ }, function(data, menu)
+ cleanPlayer(playerPed)
+
+ if data.current.value == 'citizen_wear' then
+ if Config.EnableCustomPeds then
+ ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin)
+ local isMale = skin.sex == 0
+
+ TriggerEvent('skinchanger:loadDefaultModel', isMale, function()
+ ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin)
+ TriggerEvent('skinchanger:loadSkin', skin)
+ TriggerEvent('esx:restoreLoadout')
+ end)
+ end)
+
+ end)
+ else
+ ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin)
+ TriggerEvent('skinchanger:loadSkin', skin)
+ end)
+ end
+
+ if Config.EnableESXService then
+ ESX.TriggerServerCallback('esx_service:isInService', function(isInService)
+ if isInService then
+ playerInService = false
+
+ local notification = {
+ title = _U('service_anonunce'),
+ subject = '',
+ msg = _U('service_out_announce', GetPlayerName(PlayerId())),
+ iconType = 1
+ }
+
+ TriggerServerEvent('esx_service:notifyAllInService', notification, 'police')
+
+ TriggerServerEvent('esx_service:disableService', 'police')
+ TriggerEvent('esx_policejob:updateBlip')
+ ESX.ShowNotification(_U('service_out'))
+ end
+ end, 'police')
+ end
+ end
+
+ if Config.EnableESXService and data.current.value ~= 'citizen_wear' then
+ local awaitService
+
+ ESX.TriggerServerCallback('esx_service:isInService', function(isInService)
+ if not isInService then
+
+ if Config.MaxInService == -1 then
+ ESX.TriggerServerCallback('esx_service:enableService', function(canTakeService, maxInService, inServiceCount)
+ if not canTakeService then
+ ESX.ShowNotification(_U('service_max', inServiceCount, maxInService))
+ else
+ awaitService = true
+ playerInService = true
+
+ local notification = {
+ title = _U('service_anonunce'),
+ subject = '',
+ msg = _U('service_in_announce', GetPlayerName(PlayerId())),
+ iconType = 1
+ }
+
+ TriggerServerEvent('esx_service:notifyAllInService', notification, 'police')
+ TriggerEvent('esx_policejob:updateBlip')
+ ESX.ShowNotification(_U('service_in'))
+ end
+ end, 'police')
+ else
+ awaitService = true
+ playerInService = true
+
+ local notification = {
+ title = _U('service_anonunce'),
+ subject = '',
+ msg = _U('service_in_announce', GetPlayerName(PlayerId())),
+ iconType = 1
+ }
+
+ TriggerServerEvent('esx_service:notifyAllInService', notification, 'police')
+ TriggerEvent('esx_policejob:updateBlip')
+ ESX.ShowNotification(_U('service_in'))
+ end
+
+ else
+ awaitService = true
+ end
+ end, 'police')
+
+ while awaitService == nil do
+ Citizen.Wait(5)
+ end
+
+ -- if we couldn't enter service don't let the player get changed
+ if not awaitService then
+ return
+ end
+ end
+
+ if data.current.uniform then
+ setUniform(data.current.uniform, playerPed)
+ elseif data.current.value == 'freemode_ped' then
+ local modelHash
+
+ ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin)
+ if skin.sex == 0 then
+ modelHash = GetHashKey(data.current.maleModel)
+ else
+ modelHash = GetHashKey(data.current.femaleModel)
+ end
+
+ ESX.Streaming.RequestModel(modelHash, function()
+ SetPlayerModel(PlayerId(), modelHash)
+ SetModelAsNoLongerNeeded(modelHash)
+ SetPedDefaultComponentVariation(PlayerPedId())
+
+ TriggerEvent('esx:restoreLoadout')
+ end)
+ end)
+ end
+ end, function(data, menu)
+ menu.close()
+
+ CurrentAction = 'menu_cloakroom'
+ CurrentActionMsg = _U('open_cloackroom')
+ CurrentActionData = {}
+ end)
+end
+
+function OpenArmoryMenu(station)
+ local elements = {
+ {label = _U('buy_weapons'), value = 'buy_weapons'}
+ }
+
+ if Config.EnableArmoryManagement then
+ table.insert(elements, {label = _U('get_weapon'), value = 'get_weapon'})
+ table.insert(elements, {label = _U('put_weapon'), value = 'put_weapon'})
+ table.insert(elements, {label = _U('remove_object'), value = 'get_stock'})
+ table.insert(elements, {label = _U('deposit_object'), value = 'put_stock'})
+ end
+
+ ESX.UI.Menu.CloseAll()
+
+ ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'armory', {
+ title = _U('armory'),
+ align = 'top-left',
+ elements = elements
+ }, function(data, menu)
+
+ if data.current.value == 'get_weapon' then
+ OpenGetWeaponMenu()
+ elseif data.current.value == 'put_weapon' then
+ OpenPutWeaponMenu()
+ elseif data.current.value == 'buy_weapons' then
+ OpenBuyWeaponsMenu()
+ elseif data.current.value == 'put_stock' then
+ OpenPutStocksMenu()
+ elseif data.current.value == 'get_stock' then
+ OpenGetStocksMenu()
+ end
+
+ end, function(data, menu)
+ menu.close()
+
+ CurrentAction = 'menu_armory'
+ CurrentActionMsg = _U('open_armory')
+ CurrentActionData = {station = station}
+ end)
+end
+
+function OpenPoliceActionsMenu()
+ ESX.UI.Menu.CloseAll()
+
+ ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'police_actions', {
+ title = 'Police',
+ align = 'top-left',
+ elements = {
+ {label = _U('citizen_interaction'), value = 'citizen_interaction'},
+ {label = _U('vehicle_interaction'), value = 'vehicle_interaction'},
+ {label = _U('object_spawner'), value = 'object_spawner'}
+ }}, function(data, menu)
+ if data.current.value == 'citizen_interaction' then
+ local elements = {
+ {label = _U('id_card'), value = 'identity_card'},
+ {label = _U('search'), value = 'search'},
+ {label = _U('handcuff'), value = 'handcuff'},
+ {label = _U('drag'), value = 'drag'},
+ {label = _U('put_in_vehicle'), value = 'put_in_vehicle'},
+ {label = _U('out_the_vehicle'), value = 'out_the_vehicle'},
+ {label = _U('fine'), value = 'fine'},
+ {label = _U('unpaid_bills'), value = 'unpaid_bills'}
+ }
+
+ if Config.EnableLicenses then
+ table.insert(elements, {label = _U('license_check'), value = 'license'})
+ end
+
+ ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'citizen_interaction', {
+ title = _U('citizen_interaction'),
+ align = 'top-left',
+ elements = elements
+ }, function(data2, menu2)
+ local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer()
+ if closestPlayer ~= -1 and closestDistance <= 3.0 then
+ local action = data2.current.value
+
+ if action == 'identity_card' then
+ OpenIdentityCardMenu(closestPlayer)
+ elseif action == 'search' then
+ OpenBodySearchMenu(closestPlayer)
+ elseif action == 'handcuff' then
+ TriggerServerEvent('esx_policejob:handcuff', GetPlayerServerId(closestPlayer))
+ elseif action == 'drag' then
+ TriggerServerEvent('esx_policejob:drag', GetPlayerServerId(closestPlayer))
+ elseif action == 'put_in_vehicle' then
+ TriggerServerEvent('esx_policejob:putInVehicle', GetPlayerServerId(closestPlayer))
+ elseif action == 'out_the_vehicle' then
+ TriggerServerEvent('esx_policejob:OutVehicle', GetPlayerServerId(closestPlayer))
+ elseif action == 'fine' then
+ OpenFineMenu(closestPlayer)
+ elseif action == 'license' then
+ ShowPlayerLicense(closestPlayer)
+ elseif action == 'unpaid_bills' then
+ OpenUnpaidBillsMenu(closestPlayer)
+ end
+ else
+ ESX.ShowNotification(_U('no_players_nearby'))
+ end
+ end, function(data2, menu2)
+ menu2.close()
+ end)
+ elseif data.current.value == 'vehicle_interaction' then
+ local elements = {}
+ local playerPed = PlayerPedId()
+ local vehicle = ESX.Game.GetVehicleInDirection()
+
+ if DoesEntityExist(vehicle) then
+ table.insert(elements, {label = _U('vehicle_info'), value = 'vehicle_infos'})
+ table.insert(elements, {label = _U('pick_lock'), value = 'hijack_vehicle'})
+ table.insert(elements, {label = _U('impound'), value = 'impound'})
+ end
+
+ table.insert(elements, {label = _U('search_database'), value = 'search_database'})
+
+ ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_interaction', {
+ title = _U('vehicle_interaction'),
+ align = 'top-left',
+ elements = elements
+ }, function(data2, menu2)
+ local coords = GetEntityCoords(playerPed)
+ vehicle = ESX.Game.GetVehicleInDirection()
+ action = data2.current.value
+
+ if action == 'search_database' then
+ LookupVehicle()
+ elseif DoesEntityExist(vehicle) then
+ if action == 'vehicle_infos' then
+ local vehicleData = ESX.Game.GetVehicleProperties(vehicle)
+ OpenVehicleInfosMenu(vehicleData)
+ elseif action == 'hijack_vehicle' then
+ if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 3.0) then
+ TaskStartScenarioInPlace(playerPed, 'WORLD_HUMAN_WELDING', 0, true)
+ Citizen.Wait(20000)
+ ClearPedTasksImmediately(playerPed)
+
+ SetVehicleDoorsLocked(vehicle, 1)
+ SetVehicleDoorsLockedForAllPlayers(vehicle, false)
+ ESX.ShowNotification(_U('vehicle_unlocked'))
+ end
+ elseif action == 'impound' then
+ -- is the script busy?
+ if currentTask.busy then
+ return
+ end
+
+ ESX.ShowHelpNotification(_U('impound_prompt'))
+ TaskStartScenarioInPlace(playerPed, 'CODE_HUMAN_MEDIC_TEND_TO_DEAD', 0, true)
+
+ currentTask.busy = true
+ currentTask.task = ESX.SetTimeout(10000, function()
+ ClearPedTasks(playerPed)
+ ImpoundVehicle(vehicle)
+ Citizen.Wait(100) -- sleep the entire script to let stuff sink back to reality
+ end)
+
+ -- keep track of that vehicle!
+ Citizen.CreateThread(function()
+ while currentTask.busy do
+ Citizen.Wait(1000)
+
+ vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 3.0, 0, 71)
+ if not DoesEntityExist(vehicle) and currentTask.busy then
+ ESX.ShowNotification(_U('impound_canceled_moved'))
+ ESX.ClearTimeout(currentTask.task)
+ ClearPedTasks(playerPed)
+ currentTask.busy = false
+ break
+ end
+ end
+ end)
+ end
+ else
+ ESX.ShowNotification(_U('no_vehicles_nearby'))
+ end
+
+ end, function(data2, menu2)
+ menu2.close()
+ end)
+ elseif data.current.value == 'object_spawner' then
+ ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'citizen_interaction', {
+ title = _U('traffic_interaction'),
+ align = 'top-left',
+ elements = {
+ {label = _U('cone'), model = 'prop_roadcone02a'},
+ {label = _U('barrier'), model = 'prop_barrier_work05'},
+ {label = _U('spikestrips'), model = 'p_ld_stinger_s'},
+ {label = _U('box'), model = 'prop_boxpile_07d'},
+ {label = _U('cash'), model = 'hei_prop_cash_crate_half_full'}
+ }}, function(data2, menu2)
+ local playerPed = PlayerPedId()
+ local coords, forward = GetEntityCoords(playerPed), GetEntityForwardVector(playerPed)
+ local objectCoords = (coords + forward * 1.0)
+
+ ESX.Game.SpawnObject(data2.current.model, objectCoords, function(obj)
+ SetEntityHeading(obj, GetEntityHeading(playerPed))
+ PlaceObjectOnGroundProperly(obj)
+ end)
+ end, function(data2, menu2)
+ menu2.close()
+ end)
+ end
+ end, function(data, menu)
+ menu.close()
+ end)
+end
+
+function OpenIdentityCardMenu(player)
+ ESX.TriggerServerCallback('esx_policejob:getOtherPlayerData', function(data)
+ local elements = {
+ {label = _U('name', data.name)},
+ {label = _U('job', ('%s - %s'):format(data.job, data.grade))}
+ }
+
+ if Config.EnableESXIdentity then
+ table.insert(elements, {label = _U('sex', _U(data.sex))})
+ table.insert(elements, {label = _U('dob', data.dob)})
+ table.insert(elements, {label = _U('height', data.height)})
+ end
+
+ if data.drunk then
+ table.insert(elements, {label = _U('bac', data.drunk)})
+ end
+
+ if data.licenses then
+ table.insert(elements, {label = _U('license_label')})
+
+ for i=1, #data.licenses, 1 do
+ table.insert(elements, {label = data.licenses[i].label})
+ end
+ end
+
+ ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'citizen_interaction', {
+ title = _U('citizen_interaction'),
+ align = 'top-left',
+ elements = elements
+ }, nil, function(data, menu)
+ menu.close()
+ end)
+ end, GetPlayerServerId(player))
+end
+
+function OpenBodySearchMenu(player)
+ ESX.TriggerServerCallback('esx_policejob:getOtherPlayerData', function(data)
+ local elements = {}
+
+ for i=1, #data.accounts, 1 do
+ if data.accounts[i].name == 'black_money' and data.accounts[i].money > 0 then
+ table.insert(elements, {
+ label = _U('confiscate_dirty', ESX.Math.Round(data.accounts[i].money)),
+ value = 'black_money',
+ itemType = 'item_account',
+ amount = data.accounts[i].money
+ })
+
+ break
+ end
+ end
+
+ table.insert(elements, {label = _U('guns_label')})
+
+ for i=1, #data.weapons, 1 do
+ table.insert(elements, {
+ label = _U('confiscate_weapon', ESX.GetWeaponLabel(data.weapons[i].name), data.weapons[i].ammo),
+ value = data.weapons[i].name,
+ itemType = 'item_weapon',
+ amount = data.weapons[i].ammo
+ })
+ end
+
+ table.insert(elements, {label = _U('inventory_label')})
+
+ for i=1, #data.inventory, 1 do
+ if data.inventory[i].count > 0 then
+ table.insert(elements, {
+ label = _U('confiscate_inv', data.inventory[i].count, data.inventory[i].label),
+ value = data.inventory[i].name,
+ itemType = 'item_standard',
+ amount = data.inventory[i].count
+ })
+ end
+ end
+
+ ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'body_search', {
+ title = _U('search'),
+ align = 'top-left',
+ elements = elements
+ }, function(data, menu)
+ if data.current.value then
+ TriggerServerEvent('esx_policejob:confiscatePlayerItem', GetPlayerServerId(player), data.current.itemType, data.current.value, data.current.amount)
+ OpenBodySearchMenu(player)
+ end
+ end, function(data, menu)
+ menu.close()
+ end)
+ end, GetPlayerServerId(player))
+end
+
+function OpenFineMenu(player)
+ ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'fine', {
+ title = _U('fine'),
+ align = 'top-left',
+ elements = {
+ {label = _U('traffic_offense'), value = 0},
+ {label = _U('minor_offense'), value = 1},
+ {label = _U('average_offense'), value = 2},
+ {label = _U('major_offense'), value = 3}
+ }}, function(data, menu)
+ OpenFineCategoryMenu(player, data.current.value)
+ end, function(data, menu)
+ menu.close()
+ end)
+end
+
+function OpenFineCategoryMenu(player, category)
+ ESX.TriggerServerCallback('esx_policejob:getFineList', function(fines)
+ local elements = {}
+
+ for k,fine in ipairs(fines) do
+ table.insert(elements, {
+ label = ('%s %s'):format(fine.label, _U('armory_item', ESX.Math.GroupDigits(fine.amount))),
+ value = fine.id,
+ amount = fine.amount,
+ fineLabel = fine.label
+ })
+ end
+
+ ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'fine_category', {
+ title = _U('fine'),
+ align = 'top-left',
+ elements = elements
+ }, function(data, menu)
+ menu.close()
+
+ if Config.EnablePlayerManagement then
+ TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(player), 'society_police', _U('fine_total', data.current.fineLabel), data.current.amount)
+ else
+ TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(player), '', _U('fine_total', data.current.fineLabel), data.current.amount)
+ end
+
+ ESX.SetTimeout(300, function()
+ OpenFineCategoryMenu(player, category)
+ end)
+ end, function(data, menu)
+ menu.close()
+ end)
+ end, category)
+end
+
+function LookupVehicle()
+ ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'lookup_vehicle', {
+ title = _U('search_database_title'),
+ }, function(data, menu)
+ local length = string.len(data.value)
+ if not data.value or length < 2 or length > 8 then
+ ESX.ShowNotification(_U('search_database_error_invalid'))
+ else
+ ESX.TriggerServerCallback('esx_policejob:getVehicleInfos', function(retrivedInfo)
+ local elements = {{label = _U('plate', retrivedInfo.plate)}}
+ menu.close()
+
+ if not retrivedInfo.owner then
+ table.insert(elements, {label = _U('owner_unknown')})
+ else
+ table.insert(elements, {label = _U('owner', retrivedInfo.owner)})
+ end
+
+ ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_infos', {
+ title = _U('vehicle_info'),
+ align = 'top-left',
+ elements = elements
+ }, nil, function(data2, menu2)
+ menu2.close()
+ end)
+ end, data.value)
+
+ end
+ end, function(data, menu)
+ menu.close()
+ end)
+end
+
+function ShowPlayerLicense(player)
+ local elements = {}
+
+ ESX.TriggerServerCallback('esx_policejob:getOtherPlayerData', function(playerData)
+ if playerData.licenses then
+ for i=1, #playerData.licenses, 1 do
+ if playerData.licenses[i].label and playerData.licenses[i].type then
+ table.insert(elements, {
+ label = playerData.licenses[i].label,
+ type = playerData.licenses[i].type
+ })
+ end
+ end
+ end
+
+ ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'manage_license', {
+ title = _U('license_revoke'),
+ align = 'top-left',
+ elements = elements,
+ }, function(data, menu)
+ ESX.ShowNotification(_U('licence_you_revoked', data.current.label, playerData.name))
+ TriggerServerEvent('esx_policejob:message', GetPlayerServerId(player), _U('license_revoked', data.current.label))
+
+ TriggerServerEvent('esx_license:removeLicense', GetPlayerServerId(player), data.current.type)
+
+ ESX.SetTimeout(300, function()
+ ShowPlayerLicense(player)
+ end)
+ end, function(data, menu)
+ menu.close()
+ end)
+
+ end, GetPlayerServerId(player))
+end
+
+function OpenUnpaidBillsMenu(player)
+ local elements = {}
+
+ ESX.TriggerServerCallback('esx_billing:getTargetBills', function(bills)
+ for k,bill in ipairs(bills) do
+ table.insert(elements, {
+ label = ('%s - %s'):format(bill.label, _U('armory_item', ESX.Math.GroupDigits(bill.amount))),
+ billId = bill.id
+ })
+ end
+
+ ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'billing', {
+ title = _U('unpaid_bills'),
+ align = 'top-left',
+ elements = elements
+ }, nil, function(data, menu)
+ menu.close()
+ end)
+ end, GetPlayerServerId(player))
+end
+
+function OpenVehicleInfosMenu(vehicleData)
+ ESX.TriggerServerCallback('esx_policejob:getVehicleInfos', function(retrivedInfo)
+ local elements = {{label = _U('plate', retrivedInfo.plate)}}
+
+ if not retrivedInfo.owner then
+ table.insert(elements, {label = _U('owner_unknown')})
+ else
+ table.insert(elements, {label = _U('owner', retrivedInfo.owner)})
+ end
+
+ ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_infos', {
+ title = _U('vehicle_info'),
+ align = 'top-left',
+ elements = elements
+ }, nil, function(data, menu)
+ menu.close()
+ end)
+ end, vehicleData.plate)
+end
+
+function OpenGetWeaponMenu()
+ ESX.TriggerServerCallback('esx_policejob:getArmoryWeapons', function(weapons)
+ local elements = {}
+
+ for i=1, #weapons, 1 do
+ if weapons[i].count > 0 then
+ table.insert(elements, {
+ label = 'x' .. weapons[i].count .. ' ' .. ESX.GetWeaponLabel(weapons[i].name),
+ value = weapons[i].name
+ })
+ end
+ end
+
+ ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'armory_get_weapon', {
+ title = _U('get_weapon_menu'),
+ align = 'top-left',
+ elements = elements
+ }, function(data, menu)
+ menu.close()
+
+ ESX.TriggerServerCallback('esx_policejob:removeArmoryWeapon', function()
+ OpenGetWeaponMenu()
+ end, data.current.value)
+ end, function(data, menu)
+ menu.close()
+ end)
+ end)
+end
+
+function OpenPutWeaponMenu()
+ local elements = {}
+ local playerPed = PlayerPedId()
+ local weaponList = ESX.GetWeaponList()
+
+ for i=1, #weaponList, 1 do
+ local weaponHash = GetHashKey(weaponList[i].name)
+
+ if HasPedGotWeapon(playerPed, weaponHash, false) and weaponList[i].name ~= 'WEAPON_UNARMED' then
+ table.insert(elements, {
+ label = weaponList[i].label,
+ value = weaponList[i].name
+ })
+ end
+ end
+
+ ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'armory_put_weapon', {
+ title = _U('put_weapon_menu'),
+ align = 'top-left',
+ elements = elements
+ }, function(data, menu)
+ menu.close()
+
+ ESX.TriggerServerCallback('esx_policejob:addArmoryWeapon', function()
+ OpenPutWeaponMenu()
+ end, data.current.value, true)
+ end, function(data, menu)
+ menu.close()
+ end)
+end
+
+function OpenBuyWeaponsMenu()
+ local elements = {}
+ local playerPed = PlayerPedId()
+
+ for k,v in ipairs(Config.AuthorizedWeapons[ESX.PlayerData.job.grade_name]) do
+ local weaponNum, weapon = ESX.GetWeapon(v.weapon)
+ local components, label = {}
+ local hasWeapon = HasPedGotWeapon(playerPed, GetHashKey(v.weapon), false)
+
+ if v.components then
+ for i=1, #v.components do
+ if v.components[i] then
+ local component = weapon.components[i]
+ local hasComponent = HasPedGotWeaponComponent(playerPed, GetHashKey(v.weapon), component.hash)
+
+ if hasComponent then
+ label = ('%s: %s'):format(component.label, _U('armory_owned'))
+ else
+ if v.components[i] > 0 then
+ label = ('%s: %s'):format(component.label, _U('armory_item', ESX.Math.GroupDigits(v.components[i])))
+ else
+ label = ('%s: %s'):format(component.label, _U('armory_free'))
+ end
+ end
+
+ table.insert(components, {
+ label = label,
+ componentLabel = component.label,
+ hash = component.hash,
+ name = component.name,
+ price = v.components[i],
+ hasComponent = hasComponent,
+ componentNum = i
+ })
+ end
+ end
+ end
+
+ if hasWeapon and v.components then
+ label = ('%s: >'):format(weapon.label)
+ elseif hasWeapon and not v.components then
+ label = ('%s: %s'):format(weapon.label, _U('armory_owned'))
+ else
+ if v.price > 0 then
+ label = ('%s: %s'):format(weapon.label, _U('armory_item', ESX.Math.GroupDigits(v.price)))
+ else
+ label = ('%s: %s'):format(weapon.label, _U('armory_free'))
+ end
+ end
+
+ table.insert(elements, {
+ label = label,
+ weaponLabel = weapon.label,
+ name = weapon.name,
+ components = components,
+ price = v.price,
+ hasWeapon = hasWeapon
+ })
+ end
+
+ ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'armory_buy_weapons', {
+ title = _U('armory_weapontitle'),
+ align = 'top-left',
+ elements = elements
+ }, function(data, menu)
+ if data.current.hasWeapon then
+ if #data.current.components > 0 then
+ OpenWeaponComponentShop(data.current.components, data.current.name, menu)
+ end
+ else
+ ESX.TriggerServerCallback('esx_policejob:buyWeapon', function(bought)
+ if bought then
+ if data.current.price > 0 then
+ ESX.ShowNotification(_U('armory_bought', data.current.weaponLabel, ESX.Math.GroupDigits(data.current.price)))
+ end
+
+ menu.close()
+ OpenBuyWeaponsMenu()
+ else
+ ESX.ShowNotification(_U('armory_money'))
+ end
+ end, data.current.name, 1)
+ end
+ end, function(data, menu)
+ menu.close()
+ end)
+end
+
+function OpenWeaponComponentShop(components, weaponName, parentShop)
+ ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'armory_buy_weapons_components', {
+ title = _U('armory_componenttitle'),
+ align = 'top-left',
+ elements = components
+ }, function(data, menu)
+ if data.current.hasComponent then
+ ESX.ShowNotification(_U('armory_hascomponent'))
+ else
+ ESX.TriggerServerCallback('esx_policejob:buyWeapon', function(bought)
+ if bought then
+ if data.current.price > 0 then
+ ESX.ShowNotification(_U('armory_bought', data.current.componentLabel, ESX.Math.GroupDigits(data.current.price)))
+ end
+
+ menu.close()
+ parentShop.close()
+ OpenBuyWeaponsMenu()
+ else
+ ESX.ShowNotification(_U('armory_money'))
+ end
+ end, weaponName, 2, data.current.componentNum)
+ end
+ end, function(data, menu)
+ menu.close()
+ end)
+end
+
+function OpenGetStocksMenu()
+ ESX.TriggerServerCallback('esx_policejob:getStockItems', function(items)
+ local elements = {}
+
+ for i=1, #items, 1 do
+ table.insert(elements, {
+ label = 'x' .. items[i].count .. ' ' .. items[i].label,
+ value = items[i].name
+ })
+ end
+
+ ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'stocks_menu', {
+ title = _U('police_stock'),
+ align = 'top-left',
+ elements = elements
+ }, function(data, menu)
+ local itemName = data.current.value
+
+ ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'stocks_menu_get_item_count', {
+ title = _U('quantity')
+ }, function(data2, menu2)
+ local count = tonumber(data2.value)
+
+ if not count then
+ ESX.ShowNotification(_U('quantity_invalid'))
+ else
+ menu2.close()
+ menu.close()
+ TriggerServerEvent('esx_policejob:getStockItem', itemName, count)
+
+ Citizen.Wait(300)
+ OpenGetStocksMenu()
+ end
+ end, function(data2, menu2)
+ menu2.close()
+ end)
+ end, function(data, menu)
+ menu.close()
+ end)
+ end)
+end
+
+function OpenPutStocksMenu()
+ ESX.TriggerServerCallback('esx_policejob:getPlayerInventory', function(inventory)
+ local elements = {}
+
+ for i=1, #inventory.items, 1 do
+ local item = inventory.items[i]
+
+ if item.count > 0 then
+ table.insert(elements, {
+ label = item.label .. ' x' .. item.count,
+ type = 'item_standard',
+ value = item.name
+ })
+ end
+ end
+
+ ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'stocks_menu', {
+ title = _U('inventory'),
+ align = 'top-left',
+ elements = elements
+ }, function(data, menu)
+ local itemName = data.current.value
+
+ ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'stocks_menu_put_item_count', {
+ title = _U('quantity')
+ }, function(data2, menu2)
+ local count = tonumber(data2.value)
+
+ if not count then
+ ESX.ShowNotification(_U('quantity_invalid'))
+ else
+ menu2.close()
+ menu.close()
+ TriggerServerEvent('esx_policejob:putStockItems', itemName, count)
+
+ Citizen.Wait(300)
+ OpenPutStocksMenu()
+ end
+ end, function(data2, menu2)
+ menu2.close()
+ end)
+ end, function(data, menu)
+ menu.close()
+ end)
+ end)
+end
+
+RegisterNetEvent('esx:setJob')
+AddEventHandler('esx:setJob', function(job)
+ ESX.PlayerData.job = job
+
+ Citizen.Wait(5000)
+ TriggerServerEvent('esx_policejob:forceBlip')
+end)
+
+RegisterNetEvent('esx_phone:loaded')
+AddEventHandler('esx_phone:loaded', function(phoneNumber, contacts)
+ local specialContact = {
+ name = _U('phone_police'),
+ number = 'police',
+ base64Icon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NDFGQTJDRkI0QUJCMTFFN0JBNkQ5OENBMUI4QUEzM0YiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NDFGQTJDRkM0QUJCMTFFN0JBNkQ5OENBMUI4QUEzM0YiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo0MUZBMkNGOTRBQkIxMUU3QkE2RDk4Q0ExQjhBQTMzRiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo0MUZBMkNGQTRBQkIxMUU3QkE2RDk4Q0ExQjhBQTMzRiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PoW66EYAAAjGSURBVHjapJcLcFTVGcd/u3cfSXaTLEk2j80TCI8ECI9ABCyoiBqhBVQqVG2ppVKBQqUVgUl5OU7HKqNOHUHU0oHamZZWoGkVS6cWAR2JPJuAQBPy2ISEvLN57+v2u2E33e4k6Ngz85+9d++95/zP9/h/39GpqsqiRYsIGz8QZAq28/8PRfC+4HT4fMXFxeiH+GC54NeCbYLLATLpYe/ECx4VnBTsF0wWhM6lXY8VbBE0Ch4IzLcpfDFD2P1TgrdC7nMCZLRxQ9AkiAkQCn77DcH3BC2COoFRkCSIG2JzLwqiQi0RSmCD4JXbmNKh0+kc/X19tLtc9Ll9sk9ZS1yoU71YIk3xsbEx8QaDEc2ttxmaJSKC1ggSKBK8MKwTFQVXRzs3WzpJGjmZgvxcMpMtWIwqsjztvSrlzjYul56jp+46qSmJmMwR+P3+4aZ8TtCprRkk0DvUW7JjmV6lsqoKW/pU1q9YQOE4Nxkx4ladE7zd8ivuVmJQfXZKW5dx5EwPRw4fxNx2g5SUVLw+33AkzoRaQDP9SkFu6OKqz0uF8yaz7vsOL6ycQVLkcSg/BlWNsjuFoKE1knqDSl5aNnmPLmThrE0UvXqQqvJPyMrMGorEHwQfEha57/3P7mXS684GFjy8kreLppPUuBXfyd/ibeoS2kb0mWPANhJdYjb61AxUvx5PdT3+4y+Tb3mTd19ZSebE+VTXVGNQlHAC7w4VhH8TbA36vKq6ilnzlvPSunHw6Trc7XpZ14AyfgYeyz18crGN1Alz6e3qwNNQSv4dZox1h/BW9+O7eIaEsVv41Y4XeHJDG83Nl4mLTwzGhJYtx0PzNTjOB9KMTlc7Nkcem39YAGU7cbeBKVLMPGMVf296nMd2VbBq1wmizHoqqm/wrS1/Zf0+N19YN2PIu1fcIda4Vk66Zx/rVi+jo9eIX9wZGGcFXUMR6BHUa76/2ezioYcXMtpyAl91DSaTfDxlJbtLprHm2ecpObqPuTPzSNV9yKz4a4zJSuLo71/j8Q17ON69EmXiPIlNMe6FoyzOqWPW/MU03Lw5EFcyKghTrNDh7+/vw545mcJcWbTiGKpRdGPMXbx90sGmDaux6sXk+kimjU+BjnMkx3kYP34cXrFuZ+3nrHi6iDMt92JITcPjk3R3naRwZhpuNSqoD93DKaFVU7j2dhcF8+YzNlpErbIBTVh8toVccbaysPB+4pMcuPw25kwSsau7BIlmHpy3guaOPtISYyi/UkaJM5Lpc5agq5Xkcl6gIHkmqaMn0dtylcjIyPThCNyhaXyfR2W0I1our0v6qBii07ih5rDtGSOxNVdk1y4R2SR8jR/g7hQD9l1jUeY/WLJB5m39AlZN4GZyIQ1fFJNsEgt0duBIc5GRkcZF53mNwIzhXPDgQPoZIkiMkbTxtstDMVnmFA4cOsbz2/aKjSQjev4Mp9ZAg+hIpFhB3EH5Yal16+X+Kq3dGfxkzRY+KauBjBzREvGN0kNCTARu94AejBLMHorAQ7cEQMGs2cXvkWshYLDi6e9l728O8P1XW6hKeB2yv42q18tjj+iFTGoSi+X9jJM9RTxS9E+OHT0krhNiZqlbqraoT7RAU5bBGrEknEBhgJks7KXbLS8qERI0ErVqF/Y4K6NHZfLZB+/wzJvncacvFd91oXO3o/O40MfZKJOKu/rne+mRQByXM4lYreb1tUnkizVVA/0SpfpbWaCNBeEE5gb/UH19NLqEgDF+oNDQWcn41Cj0EXFEWqzkOIyYekslFkThsvMxpIyE2hIc6lXGZ6cPyK7Nnk5OipixRdxgUESAYmhq68VsGgy5CYKCUAJTg0+izApXne3CJFmUTwg4L3FProFxU+6krqmXu3MskkhSD2av41jLdzlnfFrSdCZxyqfMnppN6ZUa7pwt0h3fiK9DCt4IO9e7YqisvI7VYgmNv7mhBKKD/9psNi5dOMv5ZjukjsLdr0ffWsyTi6eSlfcA+dmiVyOXs+/sHNZu3M6PdxzgVO9GmDSHsSNqmTz/R6y6Xxqma4fwaS5Mn85n1ZE0Vl3CHBER3lUNEhiURpPJRFdTOcVnpUJnPIhR7cZXfoH5UYc5+E4RzRH3sfSnl9m2dSMjE+Tz9msse+o5dr7UwcQ5T3HwlWUkNuzG3dKFSTbsNs7m/Y8vExOlC29UWkMJlAxKoRQMR3IC7x85zOn6fHS50+U/2Untx2R1voinu5no+DQmz7yPXmMKZnsu0wrm0Oe3YhOVHdm8A09dBQYhTv4T7C+xUPrZh8Qn2MMr4qcDSRfoirWgKAvtgOpv1JI8Zi77X15G7L+fxeOUOiUFxZiULD5fSlNzNM62W+k1yq5gjajGX/ZHvOIyxd+Fkj+P092rWP/si0Qr7VisMaEWuCiYonXFwbAUTWWPYLV245NITnGkUXnpI9butLJn2y6iba+hlp7C09qBcvoN7FYL9mhxo1/y/LoEXK8Pv6qIC8WbBY/xr9YlPLf9dZT+OqKTUwfmDBm/GOw7ws4FWpuUP2gJEZvKqmocuXPZuWYJMzKuSsH+SNwh3bo0p6hao6HeEqwYEZ2M6aKWd3PwTCy7du/D0F1DsmzE6/WGLr5LsDF4LggnYBacCOboQLHQ3FFfR58SR+HCR1iQH8ukhA5s5o5AYZMwUqOp74nl8xvRHDlRTsnxYpJsUjtsceHt2C8Fm0MPJrphTkZvBc4It9RKLOFx91Pf0Igu0k7W2MmkOewS2QYJUJVWVz9VNbXUVVwkyuAmKTFJayrDo/4Jwe/CT0aGYTrWVYEeUfsgXssMRcpyenraQJa0VX9O3ZU+Ma1fax4xGxUsUVFkOUbcama1hf+7+LmA9juHWshwmwOE1iMmCFYEzg1jtIm1BaxW6wCGGoFdewPfvyE4ertTiv4rHC73B855dwp2a23bbd4tC1hvhOCbX7b4VyUQKhxrtSOaYKngasizvwi0RmOS4O1QZf2yYfiaR+73AvhTQEVf+rpn9/8IMAChKDrDzfsdIQAAAABJRU5ErkJggg=='
+ }
+
+ TriggerEvent('esx_phone:addSpecialContact', specialContact.name, specialContact.number, specialContact.base64Icon)
+end)
+
+-- don't show dispatches if the player isn't in service
+AddEventHandler('esx_phone:cancelMessage', function(dispatchNumber)
+ if ESX.PlayerData.job and ESX.PlayerData.job.name == 'police' and ESX.PlayerData.job.name == dispatchNumber then
+ -- if esx_service is enabled
+ if Config.EnableESXService and not playerInService then
+ CancelEvent()
+ end
+ end
+end)
+
+AddEventHandler('esx_policejob:hasEnteredMarker', function(station, part, partNum)
+ if part == 'Cloakroom' then
+ CurrentAction = 'menu_cloakroom'
+ CurrentActionMsg = _U('open_cloackroom')
+ CurrentActionData = {}
+ elseif part == 'Armory' then
+ CurrentAction = 'menu_armory'
+ CurrentActionMsg = _U('open_armory')
+ CurrentActionData = {station = station}
+ elseif part == 'Vehicles' then
+ CurrentAction = 'menu_vehicle_spawner'
+ CurrentActionMsg = _U('garage_prompt')
+ CurrentActionData = {station = station, part = part, partNum = partNum}
+ elseif part == 'Helicopters' then
+ CurrentAction = 'Helicopters'
+ CurrentActionMsg = _U('helicopter_prompt')
+ CurrentActionData = {station = station, part = part, partNum = partNum}
+ elseif part == 'BossActions' then
+ CurrentAction = 'menu_boss_actions'
+ CurrentActionMsg = _U('open_bossmenu')
+ CurrentActionData = {}
+ end
+end)
+
+AddEventHandler('esx_policejob:hasExitedMarker', function(station, part, partNum)
+ if not isInShopMenu then
+ ESX.UI.Menu.CloseAll()
+ end
+
+ CurrentAction = nil
+end)
+
+AddEventHandler('esx_policejob:hasEnteredEntityZone', function(entity)
+ local playerPed = PlayerPedId()
+
+ if ESX.PlayerData.job and ESX.PlayerData.job.name == 'police' and IsPedOnFoot(playerPed) then
+ CurrentAction = 'remove_entity'
+ CurrentActionMsg = _U('remove_prop')
+ CurrentActionData = {entity = entity}
+ end
+
+ if GetEntityModel(entity) == GetHashKey('p_ld_stinger_s') then
+ local playerPed = PlayerPedId()
+ local coords = GetEntityCoords(playerPed)
+
+ if IsPedInAnyVehicle(playerPed, false) then
+ local vehicle = GetVehiclePedIsIn(playerPed)
+
+ for i=0, 7, 1 do
+ SetVehicleTyreBurst(vehicle, i, true, 1000)
+ end
+ end
+ end
+end)
+
+AddEventHandler('esx_policejob:hasExitedEntityZone', function(entity)
+ if CurrentAction == 'remove_entity' then
+ CurrentAction = nil
+ end
+end)
+
+RegisterNetEvent('esx_policejob:handcuff')
+AddEventHandler('esx_policejob:handcuff', function()
+ isHandcuffed = not isHandcuffed
+ local playerPed = PlayerPedId()
+
+ if isHandcuffed then
+ RequestAnimDict('mp_arresting')
+ while not HasAnimDictLoaded('mp_arresting') do
+ Citizen.Wait(100)
+ end
+
+ TaskPlayAnim(playerPed, 'mp_arresting', 'idle', 8.0, -8, -1, 49, 0, 0, 0, 0)
+
+ SetEnableHandcuffs(playerPed, true)
+ DisablePlayerFiring(playerPed, true)
+ SetCurrentPedWeapon(playerPed, GetHashKey('WEAPON_UNARMED'), true) -- unarm player
+ SetPedCanPlayGestureAnims(playerPed, false)
+ FreezeEntityPosition(playerPed, true)
+ DisplayRadar(false)
+
+ if Config.EnableHandcuffTimer then
+ if handcuffTimer.active then
+ ESX.ClearTimeout(handcuffTimer.task)
+ end
+
+ StartHandcuffTimer()
+ end
+ else
+ if Config.EnableHandcuffTimer and handcuffTimer.active then
+ ESX.ClearTimeout(handcuffTimer.task)
+ end
+
+ ClearPedSecondaryTask(playerPed)
+ SetEnableHandcuffs(playerPed, false)
+ DisablePlayerFiring(playerPed, false)
+ SetPedCanPlayGestureAnims(playerPed, true)
+ FreezeEntityPosition(playerPed, false)
+ DisplayRadar(true)
+ end
+end)
+
+RegisterNetEvent('esx_policejob:unrestrain')
+AddEventHandler('esx_policejob:unrestrain', function()
+ if isHandcuffed then
+ local playerPed = PlayerPedId()
+ isHandcuffed = false
+
+ ClearPedSecondaryTask(playerPed)
+ SetEnableHandcuffs(playerPed, false)
+ DisablePlayerFiring(playerPed, false)
+ SetPedCanPlayGestureAnims(playerPed, true)
+ FreezeEntityPosition(playerPed, false)
+ DisplayRadar(true)
+
+ -- end timer
+ if Config.EnableHandcuffTimer and handcuffTimer.active then
+ ESX.ClearTimeout(handcuffTimer.task)
+ end
+ end
+end)
+
+RegisterNetEvent('esx_policejob:drag')
+AddEventHandler('esx_policejob:drag', function(copId)
+ if isHandcuffed then
+ dragStatus.isDragged = not dragStatus.isDragged
+ dragStatus.CopId = copId
+ end
+end)
+
+Citizen.CreateThread(function()
+ local wasDragged
+
+ while true do
+ Citizen.Wait(0)
+ local playerPed = PlayerPedId()
+
+ if isHandcuffed and dragStatus.isDragged then
+ local targetPed = GetPlayerPed(GetPlayerFromServerId(dragStatus.CopId))
+
+ if DoesEntityExist(targetPed) and IsPedOnFoot(targetPed) and not IsPedDeadOrDying(targetPed, true) then
+ if not wasDragged then
+ AttachEntityToEntity(playerPed, targetPed, 11816, 0.54, 0.54, 0.0, 0.0, 0.0, 0.0, false, false, false, false, 2, true)
+ wasDragged = true
+ else
+ Citizen.Wait(1000)
+ end
+ else
+ wasDragged = false
+ dragStatus.isDragged = false
+ DetachEntity(playerPed, true, false)
+ end
+ elseif wasDragged then
+ wasDragged = false
+ DetachEntity(playerPed, true, false)
+ else
+ Citizen.Wait(500)
+ end
+ end
+end)
+
+RegisterNetEvent('esx_policejob:putInVehicle')
+AddEventHandler('esx_policejob:putInVehicle', function()
+ if isHandcuffed then
+ local playerPed = PlayerPedId()
+ local coords = GetEntityCoords(playerPed)
+
+ if IsAnyVehicleNearPoint(coords, 5.0) then
+ local vehicle = GetClosestVehicle(coords, 5.0, 0, 71)
+
+ if DoesEntityExist(vehicle) then
+ local maxSeats, freeSeat = GetVehicleMaxNumberOfPassengers(vehicle)
+
+ for i=maxSeats - 1, 0, -1 do
+ if IsVehicleSeatFree(vehicle, i) then
+ freeSeat = i
+ break
+ end
+ end
+
+ if freeSeat then
+ TaskWarpPedIntoVehicle(playerPed, vehicle, freeSeat)
+ dragStatus.isDragged = false
+ end
+ end
+ end
+ end
+end)
+
+RegisterNetEvent('esx_policejob:OutVehicle')
+AddEventHandler('esx_policejob:OutVehicle', function()
+ local playerPed = PlayerPedId()
+
+ if IsPedSittingInAnyVehicle(playerPed) then
+ local vehicle = GetVehiclePedIsIn(playerPed, false)
+ TaskLeaveVehicle(playerPed, vehicle, 64)
+ end
+end)
+
+-- Handcuff
+Citizen.CreateThread(function()
+ while true do
+ Citizen.Wait(0)
+ local playerPed = PlayerPedId()
+
+ if isHandcuffed then
+ DisableControlAction(0, 1, true) -- Disable pan
+ DisableControlAction(0, 2, true) -- Disable tilt
+ DisableControlAction(0, 24, true) -- Attack
+ DisableControlAction(0, 257, true) -- Attack 2
+ DisableControlAction(0, 25, true) -- Aim
+ DisableControlAction(0, 263, true) -- Melee Attack 1
+ DisableControlAction(0, 32, true) -- W
+ DisableControlAction(0, 34, true) -- A
+ DisableControlAction(0, 31, true) -- S
+ DisableControlAction(0, 30, true) -- D
+
+ DisableControlAction(0, 45, true) -- Reload
+ DisableControlAction(0, 22, true) -- Jump
+ DisableControlAction(0, 44, true) -- Cover
+ DisableControlAction(0, 37, true) -- Select Weapon
+ DisableControlAction(0, 23, true) -- Also 'enter'?
+
+ DisableControlAction(0, 288, true) -- Disable phone
+ DisableControlAction(0, 289, true) -- Inventory
+ DisableControlAction(0, 170, true) -- Animations
+ DisableControlAction(0, 167, true) -- Job
+
+ DisableControlAction(0, 0, true) -- Disable changing view
+ DisableControlAction(0, 26, true) -- Disable looking behind
+ DisableControlAction(0, 73, true) -- Disable clearing animation
+ DisableControlAction(2, 199, true) -- Disable pause screen
+
+ DisableControlAction(0, 59, true) -- Disable steering in vehicle
+ DisableControlAction(0, 71, true) -- Disable driving forward in vehicle
+ DisableControlAction(0, 72, true) -- Disable reversing in vehicle
+
+ DisableControlAction(2, 36, true) -- Disable going stealth
+
+ DisableControlAction(0, 47, true) -- Disable weapon
+ DisableControlAction(0, 264, true) -- Disable melee
+ DisableControlAction(0, 257, true) -- Disable melee
+ DisableControlAction(0, 140, true) -- Disable melee
+ DisableControlAction(0, 141, true) -- Disable melee
+ DisableControlAction(0, 142, true) -- Disable melee
+ DisableControlAction(0, 143, true) -- Disable melee
+ DisableControlAction(0, 75, true) -- Disable exit vehicle
+ DisableControlAction(27, 75, true) -- Disable exit vehicle
+
+ if IsEntityPlayingAnim(playerPed, 'mp_arresting', 'idle', 3) ~= 1 then
+ ESX.Streaming.RequestAnimDict('mp_arresting', function()
+ TaskPlayAnim(playerPed, 'mp_arresting', 'idle', 8.0, -8, -1, 49, 0.0, false, false, false)
+ end)
+ end
+ else
+ Citizen.Wait(500)
+ end
+ end
+end)
+
+-- Create blips
+Citizen.CreateThread(function()
+ for k,v in pairs(Config.PoliceStations) do
+ local blip = AddBlipForCoord(v.Blip.Coords)
+
+ SetBlipSprite (blip, v.Blip.Sprite)
+ SetBlipDisplay(blip, v.Blip.Display)
+ SetBlipScale (blip, v.Blip.Scale)
+ SetBlipColour (blip, v.Blip.Colour)
+ SetBlipAsShortRange(blip, true)
+
+ BeginTextCommandSetBlipName('STRING')
+ AddTextComponentSubstringPlayerName(_U('map_blip'))
+ EndTextCommandSetBlipName(blip)
+ end
+end)
+
+-- Draw markers and more
+Citizen.CreateThread(function()
+ while true do
+ Citizen.Wait(0)
+
+ if ESX.PlayerData.job and ESX.PlayerData.job.name == 'police' then
+ local playerPed = PlayerPedId()
+ local playerCoords = GetEntityCoords(playerPed)
+ local isInMarker, hasExited, letSleep = false, false, true
+ local currentStation, currentPart, currentPartNum
+
+ for k,v in pairs(Config.PoliceStations) do
+ for i=1, #v.Cloakrooms, 1 do
+ local distance = #(playerCoords - v.Cloakrooms[i])
+
+ if distance < Config.DrawDistance then
+ DrawMarker(Config.MarkerType.Cloakrooms, v.Cloakrooms[i], 0.0, 0.0, 0.0, 0, 0.0, 0.0, 1.0, 1.0, 1.0, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, true, false, false, false)
+ letSleep = false
+
+ if distance < Config.MarkerSize.x then
+ isInMarker, currentStation, currentPart, currentPartNum = true, k, 'Cloakroom', i
+ end
+ end
+ end
+
+ for i=1, #v.Armories, 1 do
+ local distance = #(playerCoords - v.Armories[i])
+
+ if distance < Config.DrawDistance then
+ DrawMarker(Config.MarkerType.Armories, v.Armories[i], 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.5, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, true, false, false, false)
+ letSleep = false
+
+ if distance < Config.MarkerSize.x then
+ isInMarker, currentStation, currentPart, currentPartNum = true, k, 'Armory', i
+ end
+ end
+ end
+
+ for i=1, #v.Vehicles, 1 do
+ local distance = #(playerCoords - v.Vehicles[i].Spawner)
+
+ if distance < Config.DrawDistance then
+ DrawMarker(Config.MarkerType.Vehicles, v.Vehicles[i].Spawner, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, true, false, false, false)
+ letSleep = false
+
+ if distance < Config.MarkerSize.x then
+ isInMarker, currentStation, currentPart, currentPartNum = true, k, 'Vehicles', i
+ end
+ end
+ end
+
+ for i=1, #v.Helicopters, 1 do
+ local distance = #(playerCoords - v.Helicopters[i].Spawner)
+
+ if distance < Config.DrawDistance then
+ DrawMarker(Config.MarkerType.Helicopters, v.Helicopters[i].Spawner, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, true, false, false, false)
+ letSleep = false
+
+ if distance < Config.MarkerSize.x then
+ isInMarker, currentStation, currentPart, currentPartNum = true, k, 'Helicopters', i
+ end
+ end
+ end
+
+ if Config.EnablePlayerManagement and ESX.PlayerData.job.grade_name == 'boss' then
+ for i=1, #v.BossActions, 1 do
+ local distance = #(playerCoords - v.BossActions[i])
+
+ if distance < Config.DrawDistance then
+ DrawMarker(Config.MarkerType.BossActions, v.BossActions[i], 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, true, false, false, false)
+ letSleep = false
+
+ if distance < Config.MarkerSize.x then
+ isInMarker, currentStation, currentPart, currentPartNum = true, k, 'BossActions', i
+ end
+ end
+ end
+ end
+ end
+
+ if isInMarker and not HasAlreadyEnteredMarker or (isInMarker and (LastStation ~= currentStation or LastPart ~= currentPart or LastPartNum ~= currentPartNum)) then
+ if
+ (LastStation and LastPart and LastPartNum) and
+ (LastStation ~= currentStation or LastPart ~= currentPart or LastPartNum ~= currentPartNum)
+ then
+ TriggerEvent('esx_policejob:hasExitedMarker', LastStation, LastPart, LastPartNum)
+ hasExited = true
+ end
+
+ HasAlreadyEnteredMarker = true
+ LastStation = currentStation
+ LastPart = currentPart
+ LastPartNum = currentPartNum
+
+ TriggerEvent('esx_policejob:hasEnteredMarker', currentStation, currentPart, currentPartNum)
+ end
+
+ if not hasExited and not isInMarker and HasAlreadyEnteredMarker then
+ HasAlreadyEnteredMarker = false
+ TriggerEvent('esx_policejob:hasExitedMarker', LastStation, LastPart, LastPartNum)
+ end
+
+ if letSleep then
+ Citizen.Wait(500)
+ end
+ else
+ Citizen.Wait(500)
+ end
+ end
+end)
+
+-- Enter / Exit entity zone events
+Citizen.CreateThread(function()
+ local trackedEntities = {
+ 'prop_roadcone02a',
+ 'prop_barrier_work05',
+ 'p_ld_stinger_s',
+ 'prop_boxpile_07d',
+ 'hei_prop_cash_crate_half_full'
+ }
+
+ while true do
+ Citizen.Wait(500)
+
+ local playerPed = PlayerPedId()
+ local playerCoords = GetEntityCoords(playerPed)
+
+ local closestDistance = -1
+ local closestEntity = nil
+
+ for i=1, #trackedEntities, 1 do
+ local object = GetClosestObjectOfType(playerCoords, 3.0, GetHashKey(trackedEntities[i]), false, false, false)
+
+ if DoesEntityExist(object) then
+ local objCoords = GetEntityCoords(object)
+ local distance = #(playerCoords - objCoords)
+
+ if closestDistance == -1 or closestDistance > distance then
+ closestDistance = distance
+ closestEntity = object
+ end
+ end
+ end
+
+ if closestDistance ~= -1 and closestDistance <= 3.0 then
+ if LastEntity ~= closestEntity then
+ TriggerEvent('esx_policejob:hasEnteredEntityZone', closestEntity)
+ LastEntity = closestEntity
+ end
+ else
+ if LastEntity then
+ TriggerEvent('esx_policejob:hasExitedEntityZone', LastEntity)
+ LastEntity = nil
+ end
+ end
+ end
+end)
+
+-- Key Controls
+Citizen.CreateThread(function()
+ while true do
+ Citizen.Wait(0)
+
+ if CurrentAction then
+ ESX.ShowHelpNotification(CurrentActionMsg)
+
+ if IsControlJustReleased(0, 38) and ESX.PlayerData.job and ESX.PlayerData.job.name == 'police' then
+
+ if CurrentAction == 'menu_cloakroom' then
+ OpenCloakroomMenu()
+ elseif CurrentAction == 'menu_armory' then
+ if not Config.EnableESXService then
+ OpenArmoryMenu(CurrentActionData.station)
+ elseif playerInService then
+ OpenArmoryMenu(CurrentActionData.station)
+ else
+ ESX.ShowNotification(_U('service_not'))
+ end
+ elseif CurrentAction == 'menu_vehicle_spawner' then
+ if not Config.EnableESXService then
+ OpenVehicleSpawnerMenu('car', CurrentActionData.station, CurrentActionData.part, CurrentActionData.partNum)
+ elseif playerInService then
+ OpenVehicleSpawnerMenu('car', CurrentActionData.station, CurrentActionData.part, CurrentActionData.partNum)
+ else
+ ESX.ShowNotification(_U('service_not'))
+ end
+ elseif CurrentAction == 'Helicopters' then
+ if not Config.EnableESXService then
+ OpenVehicleSpawnerMenu('helicopter', CurrentActionData.station, CurrentActionData.part, CurrentActionData.partNum)
+ elseif playerInService then
+ OpenVehicleSpawnerMenu('helicopter', CurrentActionData.station, CurrentActionData.part, CurrentActionData.partNum)
+ else
+ ESX.ShowNotification(_U('service_not'))
+ end
+ elseif CurrentAction == 'delete_vehicle' then
+ ESX.Game.DeleteVehicle(CurrentActionData.vehicle)
+ elseif CurrentAction == 'menu_boss_actions' then
+ ESX.UI.Menu.CloseAll()
+ TriggerEvent('esx_society:openBossMenu', 'police', function(data, menu)
+ menu.close()
+
+ CurrentAction = 'menu_boss_actions'
+ CurrentActionMsg = _U('open_bossmenu')
+ CurrentActionData = {}
+ end, { wash = false }) -- disable washing money
+ elseif CurrentAction == 'remove_entity' then
+ DeleteEntity(CurrentActionData.entity)
+ end
+
+ CurrentAction = nil
+ end
+ end -- CurrentAction end
+
+ if IsControlJustReleased(0, 167) and not isDead and ESX.PlayerData.job and ESX.PlayerData.job.name == 'police' and not ESX.UI.Menu.IsOpen('default', GetCurrentResourceName(), 'police_actions') then
+ if not Config.EnableESXService then
+ OpenPoliceActionsMenu()
+ elseif playerInService then
+ OpenPoliceActionsMenu()
+ else
+ ESX.ShowNotification(_U('service_not'))
+ end
+ end
+
+ if IsControlJustReleased(0, 38) and currentTask.busy then
+ ESX.ShowNotification(_U('impound_canceled'))
+ ESX.ClearTimeout(currentTask.task)
+ ClearPedTasks(PlayerPedId())
+
+ currentTask.busy = false
+ end
+ end
+end)
+
+-- Create blip for colleagues
+function createBlip(id)
+ local ped = GetPlayerPed(id)
+ local blip = GetBlipFromEntity(ped)
+
+ if not DoesBlipExist(blip) then -- Add blip and create head display on player
+ blip = AddBlipForEntity(ped)
+ SetBlipSprite(blip, 1)
+ ShowHeadingIndicatorOnBlip(blip, true) -- Player Blip indicator
+ SetBlipRotation(blip, math.ceil(GetEntityHeading(ped))) -- update rotation
+ SetBlipNameToPlayerName(blip, id) -- update blip name
+ SetBlipScale(blip, 0.85) -- set scale
+ SetBlipAsShortRange(blip, true)
+
+ table.insert(blipsCops, blip) -- add blip to array so we can remove it later
+ end
+end
+
+RegisterNetEvent('esx_policejob:updateBlip')
+AddEventHandler('esx_policejob:updateBlip', function()
+
+ -- Refresh all blips
+ for k, existingBlip in pairs(blipsCops) do
+ RemoveBlip(existingBlip)
+ end
+
+ -- Clean the blip table
+ blipsCops = {}
+
+ -- Enable blip?
+ if Config.EnableESXService and not playerInService then
+ return
+ end
+
+ if not Config.EnableJobBlip then
+ return
+ end
+
+ -- Is the player a cop? In that case show all the blips for other cops
+ if ESX.PlayerData.job and ESX.PlayerData.job.name == 'police' then
+ ESX.TriggerServerCallback('esx_society:getOnlinePlayers', function(players)
+ for i=1, #players, 1 do
+ if players[i].job.name == 'police' then
+ local id = GetPlayerFromServerId(players[i].source)
+ if NetworkIsPlayerActive(id) and GetPlayerPed(id) ~= PlayerPedId() then
+ createBlip(id)
+ end
+ end
+ end
+ end)
+ end
+
+end)
+
+AddEventHandler('playerSpawned', function(spawn)
+ isDead = false
+ TriggerEvent('esx_policejob:unrestrain')
+
+ if not hasAlreadyJoined then
+ TriggerServerEvent('esx_policejob:spawned')
+ end
+ hasAlreadyJoined = true
+end)
+
+AddEventHandler('esx:onPlayerDeath', function(data)
+ isDead = true
+end)
+
+AddEventHandler('onResourceStop', function(resource)
+ if resource == GetCurrentResourceName() then
+ TriggerEvent('esx_policejob:unrestrain')
+ TriggerEvent('esx_phone:removeSpecialContact', 'police')
+
+ if Config.EnableESXService then
+ TriggerServerEvent('esx_service:disableService', 'police')
+ end
+
+ if Config.EnableHandcuffTimer and handcuffTimer.active then
+ ESX.ClearTimeout(handcuffTimer.task)
+ end
+ end
+end)
+
+-- handcuff timer, unrestrain the player after an certain amount of time
+function StartHandcuffTimer()
+ if Config.EnableHandcuffTimer and handcuffTimer.active then
+ ESX.ClearTimeout(handcuffTimer.task)
+ end
+
+ handcuffTimer.active = true
+
+ handcuffTimer.task = ESX.SetTimeout(Config.HandcuffTimer, function()
+ ESX.ShowNotification(_U('unrestrained_timer'))
+ TriggerEvent('esx_policejob:unrestrain')
+ handcuffTimer.active = false
+ end)
+end
+
+-- TODO
+-- - return to garage if owned
+-- - message owner that his vehicle has been impounded
+function ImpoundVehicle(vehicle)
+ --local vehicleName = GetLabelText(GetDisplayNameFromVehicleModel(GetEntityModel(vehicle)))
+ ESX.Game.DeleteVehicle(vehicle)
+ ESX.ShowNotification(_U('impound_successful'))
+ currentTask.busy = false
+end
diff --git a/_resources/esx_policejob/client/vehicle.lua b/_resources/esx_policejob/client/vehicle.lua
new file mode 100644
index 00000000..2a0d04b4
--- /dev/null
+++ b/_resources/esx_policejob/client/vehicle.lua
@@ -0,0 +1,326 @@
+
+local spawnedVehicles = {}
+
+function OpenVehicleSpawnerMenu(type, station, part, partNum)
+ local playerCoords = GetEntityCoords(PlayerPedId())
+
+ ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle', {
+ title = _U('garage_title'),
+ align = 'top-left',
+ elements = {
+ {label = _U('garage_storeditem'), action = 'garage'},
+ {label = _U('garage_storeitem'), action = 'store_garage'},
+ {label = _U('garage_buyitem'), action = 'buy_vehicle'}
+ }}, function(data, menu)
+ if data.current.action == 'buy_vehicle' then
+ local shopElements = {}
+ local shopCoords = Config.PoliceStations[station][part][partNum].InsideShop
+ local authorizedVehicles = Config.AuthorizedVehicles[type][ESX.PlayerData.job.grade_name]
+
+ if authorizedVehicles then
+ if #authorizedVehicles > 0 then
+ for k,vehicle in ipairs(authorizedVehicles) do
+ if IsModelInCdimage(vehicle.model) then
+ local vehicleLabel = GetLabelText(GetDisplayNameFromVehicleModel(vehicle.model))
+
+ table.insert(shopElements, {
+ label = ('%s - %s'):format(vehicleLabel, _U('shop_item', ESX.Math.GroupDigits(vehicle.price))),
+ name = vehicleLabel,
+ model = vehicle.model,
+ price = vehicle.price,
+ props = vehicle.props,
+ type = type
+ })
+ end
+ end
+
+ if #shopElements > 0 then
+ OpenShopMenu(shopElements, playerCoords, shopCoords)
+ else
+ ESX.ShowNotification(_U('garage_notauthorized'))
+ end
+ else
+ ESX.ShowNotification(_U('garage_notauthorized'))
+ end
+ else
+ ESX.ShowNotification(_U('garage_notauthorized'))
+ end
+ elseif data.current.action == 'garage' then
+ local garage = {}
+
+ ESX.TriggerServerCallback('esx_vehicleshop:retrieveJobVehicles', function(jobVehicles)
+ if #jobVehicles > 0 then
+ local allVehicleProps = {}
+
+ for k,v in ipairs(jobVehicles) do
+ local props = json.decode(v.vehicle)
+
+ if IsModelInCdimage(props.model) then
+ local vehicleName = GetLabelText(GetDisplayNameFromVehicleModel(props.model))
+ local label = ('%s - %s: '):format(vehicleName, props.plate)
+
+ if v.stored then
+ label = label .. ('%s'):format(_U('garage_stored'))
+ else
+ label = label .. ('%s'):format(_U('garage_notstored'))
+ end
+
+ table.insert(garage, {
+ label = label,
+ stored = v.stored,
+ model = props.model,
+ plate = props.plate
+ })
+
+ allVehicleProps[props.plate] = props
+ end
+ end
+
+ if #garage > 0 then
+ ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_garage', {
+ title = _U('garage_title'),
+ align = 'top-left',
+ elements = garage
+ }, function(data2, menu2)
+ if data2.current.stored then
+ local foundSpawn, spawnPoint = GetAvailableVehicleSpawnPoint(station, part, partNum)
+
+ if foundSpawn then
+ menu2.close()
+
+ ESX.Game.SpawnVehicle(data2.current.model, spawnPoint.coords, spawnPoint.heading, function(vehicle)
+ local vehicleProps = allVehicleProps[data2.current.plate]
+ ESX.Game.SetVehicleProperties(vehicle, vehicleProps)
+
+ TriggerServerEvent('esx_vehicleshop:setJobVehicleState', data2.current.plate, false)
+ ESX.ShowNotification(_U('garage_released'))
+ end)
+ end
+ else
+ ESX.ShowNotification(_U('garage_notavailable'))
+ end
+ end, function(data2, menu2)
+ menu2.close()
+ end)
+ else
+ ESX.ShowNotification(_U('garage_empty'))
+ end
+ else
+ ESX.ShowNotification(_U('garage_empty'))
+ end
+ end, type)
+ elseif data.current.action == 'store_garage' then
+ StoreNearbyVehicle(playerCoords)
+ end
+ end, function(data, menu)
+ menu.close()
+ end)
+end
+
+function StoreNearbyVehicle(playerCoords)
+ local vehicles, vehiclePlates = ESX.Game.GetVehiclesInArea(playerCoords, 30.0), {}
+
+ if #vehicles > 0 then
+ for k,v in ipairs(vehicles) do
+
+ -- Make sure the vehicle we're saving is empty, or else it wont be deleted
+ if GetVehicleNumberOfPassengers(v) == 0 and IsVehicleSeatFree(v, -1) then
+ table.insert(vehiclePlates, {
+ vehicle = v,
+ plate = ESX.Math.Trim(GetVehicleNumberPlateText(v))
+ })
+ end
+ end
+ else
+ ESX.ShowNotification(_U('garage_store_nearby'))
+ return
+ end
+
+ ESX.TriggerServerCallback('esx_policejob:storeNearbyVehicle', function(storeSuccess, foundNum)
+ if storeSuccess then
+ local vehicleId = vehiclePlates[foundNum]
+ local attempts = 0
+ ESX.Game.DeleteVehicle(vehicleId.vehicle)
+ IsBusy = true
+
+ Citizen.CreateThread(function()
+ BeginTextCommandBusyspinnerOn('STRING')
+ AddTextComponentSubstringPlayerName(_U('garage_storing'))
+ EndTextCommandBusyspinnerOn(4)
+
+ while IsBusy do
+ Citizen.Wait(100)
+ end
+
+ BusyspinnerOff()
+ end)
+
+ -- Workaround for vehicle not deleting when other players are near it.
+ while DoesEntityExist(vehicleId.vehicle) do
+ Citizen.Wait(500)
+ attempts = attempts + 1
+
+ -- Give up
+ if attempts > 30 then
+ break
+ end
+
+ vehicles = ESX.Game.GetVehiclesInArea(playerCoords, 30.0)
+ if #vehicles > 0 then
+ for k,v in ipairs(vehicles) do
+ if ESX.Math.Trim(GetVehicleNumberPlateText(v)) == vehicleId.plate then
+ ESX.Game.DeleteVehicle(v)
+ break
+ end
+ end
+ end
+ end
+
+ IsBusy = false
+ ESX.ShowNotification(_U('garage_has_stored'))
+ else
+ ESX.ShowNotification(_U('garage_has_notstored'))
+ end
+ end, vehiclePlates)
+end
+
+function GetAvailableVehicleSpawnPoint(station, part, partNum)
+ local spawnPoints = Config.PoliceStations[station][part][partNum].SpawnPoints
+ local found, foundSpawnPoint = false, nil
+
+ for i=1, #spawnPoints, 1 do
+ if ESX.Game.IsSpawnPointClear(spawnPoints[i].coords, spawnPoints[i].radius) then
+ found, foundSpawnPoint = true, spawnPoints[i]
+ break
+ end
+ end
+
+ if found then
+ return true, foundSpawnPoint
+ else
+ ESX.ShowNotification(_U('vehicle_blocked'))
+ return false
+ end
+end
+
+function OpenShopMenu(elements, restoreCoords, shopCoords)
+ local playerPed = PlayerPedId()
+ isInShopMenu = true
+
+ ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_shop', {
+ title = _U('vehicleshop_title'),
+ align = 'top-left',
+ elements = elements
+ }, function(data, menu)
+ ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_shop_confirm', {
+ title = _U('vehicleshop_confirm', data.current.name, data.current.price),
+ align = 'top-left',
+ elements = {
+ {label = _U('confirm_no'), value = 'no'},
+ {label = _U('confirm_yes'), value = 'yes'}
+ }}, function(data2, menu2)
+ if data2.current.value == 'yes' then
+ local newPlate = exports['esx_vehicleshop']:GeneratePlate()
+ local vehicle = GetVehiclePedIsIn(playerPed, false)
+ local props = ESX.Game.GetVehicleProperties(vehicle)
+ props.plate = newPlate
+
+ ESX.TriggerServerCallback('esx_policejob:buyJobVehicle', function (bought)
+ if bought then
+ ESX.ShowNotification(_U('vehicleshop_bought', data.current.name, ESX.Math.GroupDigits(data.current.price)))
+
+ isInShopMenu = false
+ ESX.UI.Menu.CloseAll()
+ DeleteSpawnedVehicles()
+ FreezeEntityPosition(playerPed, false)
+ SetEntityVisible(playerPed, true)
+
+ ESX.Game.Teleport(playerPed, restoreCoords)
+ else
+ ESX.ShowNotification(_U('vehicleshop_money'))
+ menu2.close()
+ end
+ end, props, data.current.type)
+ else
+ menu2.close()
+ end
+ end, function(data2, menu2)
+ menu2.close()
+ end)
+ end, function(data, menu)
+ isInShopMenu = false
+ ESX.UI.Menu.CloseAll()
+
+ DeleteSpawnedVehicles()
+ FreezeEntityPosition(playerPed, false)
+ SetEntityVisible(playerPed, true)
+
+ ESX.Game.Teleport(playerPed, restoreCoords)
+ end, function(data, menu)
+ DeleteSpawnedVehicles()
+ WaitForVehicleToLoad(data.current.model)
+
+ ESX.Game.SpawnLocalVehicle(data.current.model, shopCoords, 0.0, function(vehicle)
+ table.insert(spawnedVehicles, vehicle)
+ TaskWarpPedIntoVehicle(playerPed, vehicle, -1)
+ FreezeEntityPosition(vehicle, true)
+ SetModelAsNoLongerNeeded(data.current.model)
+
+ if data.current.props then
+ ESX.Game.SetVehicleProperties(vehicle, data.current.props)
+ end
+ end)
+ end)
+
+ WaitForVehicleToLoad(elements[1].model)
+ ESX.Game.SpawnLocalVehicle(elements[1].model, shopCoords, 0.0, function(vehicle)
+ table.insert(spawnedVehicles, vehicle)
+ TaskWarpPedIntoVehicle(playerPed, vehicle, -1)
+ FreezeEntityPosition(vehicle, true)
+ SetModelAsNoLongerNeeded(elements[1].model)
+
+ if elements[1].props then
+ ESX.Game.SetVehicleProperties(vehicle, elements[1].props)
+ end
+ end)
+end
+
+Citizen.CreateThread(function()
+ while true do
+ Citizen.Wait(0)
+
+ if isInShopMenu then
+ DisableControlAction(0, 75, true) -- Disable exit vehicle
+ DisableControlAction(27, 75, true) -- Disable exit vehicle
+ else
+ Citizen.Wait(500)
+ end
+ end
+end)
+
+function DeleteSpawnedVehicles()
+ while #spawnedVehicles > 0 do
+ local vehicle = spawnedVehicles[1]
+ ESX.Game.DeleteVehicle(vehicle)
+ table.remove(spawnedVehicles, 1)
+ end
+end
+
+function WaitForVehicleToLoad(modelHash)
+ modelHash = (type(modelHash) == 'number' and modelHash or GetHashKey(modelHash))
+
+ if not HasModelLoaded(modelHash) then
+ RequestModel(modelHash)
+
+ BeginTextCommandBusyspinnerOn('STRING')
+ AddTextComponentSubstringPlayerName(_U('vehicleshop_awaiting_model'))
+ EndTextCommandBusyspinnerOn(4)
+
+ while not HasModelLoaded(modelHash) do
+ Citizen.Wait(0)
+ DisableAllControlActions(0)
+ end
+
+ BusyspinnerOff()
+ end
+end
diff --git a/_resources/esx_policejob/config.lua b/_resources/esx_policejob/config.lua
new file mode 100644
index 00000000..7717309c
--- /dev/null
+++ b/_resources/esx_policejob/config.lua
@@ -0,0 +1,329 @@
+Config = {}
+
+Config.DrawDistance = 10.0 -- How close do you need to be for the markers to be drawn (in GTA units).
+Config.MarkerType = {Cloakrooms = 20, Armories = 21, BossActions = 22, Vehicles = 36, Helicopters = 34}
+Config.MarkerSize = {x = 1.5, y = 1.5, z = 0.5}
+Config.MarkerColor = {r = 50, g = 50, b = 204}
+
+Config.EnablePlayerManagement = false -- Enable if you want society managing.
+Config.EnableArmoryManagement = false
+Config.EnableESXIdentity = false -- Enable if you're using esx_identity.
+Config.EnableLicenses = false -- Enable if you're using esx_license.
+
+Config.EnableHandcuffTimer = true -- Enable handcuff timer? will unrestrain player after the time ends.
+Config.HandcuffTimer = 10 * 60000 -- 10 minutes.
+
+Config.EnableJobBlip = false -- Enable blips for cops on duty, requires esx_society.
+Config.EnableCustomPeds = false -- Enable custom peds in cloak room? See Config.CustomPeds below to customize peds.
+
+Config.EnableESXService = false -- Enable esx service?
+Config.MaxInService = -1 -- How much people can be in service at once?
+
+Config.Locale = 'en'
+
+Config.PoliceStations = {
+
+ LSPD = {
+
+ Blip = {
+ Coords = vector3(425.1, -979.5, 30.7),
+ Sprite = 60,
+ Display = 4,
+ Scale = 1.2,
+ Colour = 29
+ },
+
+ Cloakrooms = {
+ vector3(452.6, -992.8, 30.6)
+ },
+
+ Armories = {
+ vector3(451.7, -980.1, 30.6)
+ },
+
+ Vehicles = {
+ {
+ Spawner = vector3(454.6, -1017.4, 28.4),
+ InsideShop = vector3(228.5, -993.5, -99.5),
+ SpawnPoints = {
+ {coords = vector3(438.4, -1018.3, 27.7), heading = 90.0, radius = 6.0},
+ {coords = vector3(441.0, -1024.2, 28.3), heading = 90.0, radius = 6.0},
+ {coords = vector3(453.5, -1022.2, 28.0), heading = 90.0, radius = 6.0},
+ {coords = vector3(450.9, -1016.5, 28.1), heading = 90.0, radius = 6.0}
+ }
+ },
+
+ {
+ Spawner = vector3(473.3, -1018.8, 28.0),
+ InsideShop = vector3(228.5, -993.5, -99.0),
+ SpawnPoints = {
+ {coords = vector3(475.9, -1021.6, 28.0), heading = 276.1, radius = 6.0},
+ {coords = vector3(484.1, -1023.1, 27.5), heading = 302.5, radius = 6.0}
+ }
+ }
+ },
+
+ Helicopters = {
+ {
+ Spawner = vector3(461.1, -981.5, 43.6),
+ InsideShop = vector3(477.0, -1106.4, 43.0),
+ SpawnPoints = {
+ {coords = vector3(449.5, -981.2, 43.6), heading = 92.6, radius = 10.0}
+ }
+ }
+ },
+
+ BossActions = {
+ vector3(448.4, -973.2, 30.6)
+ }
+
+ }
+
+}
+
+Config.AuthorizedWeapons = {
+ recruit = {
+ {weapon = 'WEAPON_APPISTOL', components = {0, 0, 1000, 4000, nil}, price = 10000},
+ {weapon = 'WEAPON_NIGHTSTICK', price = 0},
+ {weapon = 'WEAPON_STUNGUN', price = 1500},
+ {weapon = 'WEAPON_FLASHLIGHT', price = 80}
+ },
+
+ officer = {
+ {weapon = 'WEAPON_APPISTOL', components = {0, 0, 1000, 4000, nil}, price = 10000},
+ {weapon = 'WEAPON_ADVANCEDRIFLE', components = {0, 6000, 1000, 4000, 8000, nil}, price = 50000},
+ {weapon = 'WEAPON_NIGHTSTICK', price = 0},
+ {weapon = 'WEAPON_STUNGUN', price = 500},
+ {weapon = 'WEAPON_FLASHLIGHT', price = 0}
+ },
+
+ sergeant = {
+ {weapon = 'WEAPON_APPISTOL', components = {0, 0, 1000, 4000, nil}, price = 10000},
+ {weapon = 'WEAPON_ADVANCEDRIFLE', components = {0, 6000, 1000, 4000, 8000, nil}, price = 50000},
+ {weapon = 'WEAPON_PUMPSHOTGUN', components = {2000, 6000, nil}, price = 70000},
+ {weapon = 'WEAPON_NIGHTSTICK', price = 0},
+ {weapon = 'WEAPON_STUNGUN', price = 500},
+ {weapon = 'WEAPON_FLASHLIGHT', price = 0}
+ },
+
+ lieutenant = {
+ {weapon = 'WEAPON_APPISTOL', components = {0, 0, 1000, 4000, nil}, price = 10000},
+ {weapon = 'WEAPON_ADVANCEDRIFLE', components = {0, 6000, 1000, 4000, 8000, nil}, price = 50000},
+ {weapon = 'WEAPON_PUMPSHOTGUN', components = {2000, 6000, nil}, price = 70000},
+ {weapon = 'WEAPON_NIGHTSTICK', price = 0},
+ {weapon = 'WEAPON_STUNGUN', price = 500},
+ {weapon = 'WEAPON_FLASHLIGHT', price = 0}
+ },
+
+ boss = {
+ {weapon = 'WEAPON_APPISTOL', components = {0, 0, 1000, 4000, nil}, price = 10000},
+ {weapon = 'WEAPON_ADVANCEDRIFLE', components = {0, 6000, 1000, 4000, 8000, nil}, price = 50000},
+ {weapon = 'WEAPON_PUMPSHOTGUN', components = {2000, 6000, nil}, price = 70000},
+ {weapon = 'WEAPON_NIGHTSTICK', price = 0},
+ {weapon = 'WEAPON_STUNGUN', price = 500},
+ {weapon = 'WEAPON_FLASHLIGHT', price = 0}
+ }
+}
+
+Config.AuthorizedVehicles = {
+ car = {
+ recruit = {},
+
+ officer = {
+ {model = 'police3', price = 20000}
+ },
+
+ sergeant = {
+ {model = 'policet', price = 18500},
+ {model = 'policeb', price = 30500}
+ },
+
+ lieutenant = {
+ {model = 'riot', price = 70000},
+ {model = 'fbi2', price = 60000}
+ },
+
+ boss = {}
+ },
+
+ helicopter = {
+ recruit = {},
+
+ officer = {},
+
+ sergeant = {},
+
+ lieutenant = {
+ {model = 'polmav', props = {modLivery = 0}, price = 200000}
+ },
+
+ boss = {
+ {model = 'polmav', props = {modLivery = 0}, price = 100000}
+ }
+ }
+}
+
+Config.CustomPeds = {
+ shared = {
+ {label = 'Sheriff Ped', maleModel = 's_m_y_sheriff_01', femaleModel = 's_f_y_sheriff_01'},
+ {label = 'Police Ped', maleModel = 's_m_y_cop_01', femaleModel = 's_f_y_cop_01'}
+ },
+
+ recruit = {},
+
+ officer = {},
+
+ sergeant = {},
+
+ lieutenant = {},
+
+ boss = {
+ {label = 'SWAT Ped', maleModel = 's_m_y_swat_01', femaleModel = 's_m_y_swat_01'}
+ }
+}
+
+-- CHECK SKINCHANGER CLIENT MAIN.LUA for matching elements
+Config.Uniforms = {
+ recruit = {
+ male = {
+ tshirt_1 = 59, tshirt_2 = 1,
+ torso_1 = 55, torso_2 = 0,
+ decals_1 = 0, decals_2 = 0,
+ arms = 41,
+ pants_1 = 25, pants_2 = 0,
+ shoes_1 = 25, shoes_2 = 0,
+ helmet_1 = 46, helmet_2 = 0,
+ chain_1 = 0, chain_2 = 0,
+ ears_1 = 2, ears_2 = 0
+ },
+ female = {
+ tshirt_1 = 36, tshirt_2 = 1,
+ torso_1 = 48, torso_2 = 0,
+ decals_1 = 0, decals_2 = 0,
+ arms = 44,
+ pants_1 = 34, pants_2 = 0,
+ shoes_1 = 27, shoes_2 = 0,
+ helmet_1 = 45, helmet_2 = 0,
+ chain_1 = 0, chain_2 = 0,
+ ears_1 = 2, ears_2 = 0
+ }
+ },
+
+ officer = {
+ male = {
+ tshirt_1 = 58, tshirt_2 = 0,
+ torso_1 = 55, torso_2 = 0,
+ decals_1 = 0, decals_2 = 0,
+ arms = 41,
+ pants_1 = 25, pants_2 = 0,
+ shoes_1 = 25, shoes_2 = 0,
+ helmet_1 = -1, helmet_2 = 0,
+ chain_1 = 0, chain_2 = 0,
+ ears_1 = 2, ears_2 = 0
+ },
+ female = {
+ tshirt_1 = 35, tshirt_2 = 0,
+ torso_1 = 48, torso_2 = 0,
+ decals_1 = 0, decals_2 = 0,
+ arms = 44,
+ pants_1 = 34, pants_2 = 0,
+ shoes_1 = 27, shoes_2 = 0,
+ helmet_1 = -1, helmet_2 = 0,
+ chain_1 = 0, chain_2 = 0,
+ ears_1 = 2, ears_2 = 0
+ }
+ },
+
+ sergeant = {
+ male = {
+ tshirt_1 = 58, tshirt_2 = 0,
+ torso_1 = 55, torso_2 = 0,
+ decals_1 = 8, decals_2 = 1,
+ arms = 41,
+ pants_1 = 25, pants_2 = 0,
+ shoes_1 = 25, shoes_2 = 0,
+ helmet_1 = -1, helmet_2 = 0,
+ chain_1 = 0, chain_2 = 0,
+ ears_1 = 2, ears_2 = 0
+ },
+ female = {
+ tshirt_1 = 35, tshirt_2 = 0,
+ torso_1 = 48, torso_2 = 0,
+ decals_1 = 7, decals_2 = 1,
+ arms = 44,
+ pants_1 = 34, pants_2 = 0,
+ shoes_1 = 27, shoes_2 = 0,
+ helmet_1 = -1, helmet_2 = 0,
+ chain_1 = 0, chain_2 = 0,
+ ears_1 = 2, ears_2 = 0
+ }
+ },
+
+ lieutenant = {
+ male = {
+ tshirt_1 = 58, tshirt_2 = 0,
+ torso_1 = 55, torso_2 = 0,
+ decals_1 = 8, decals_2 = 2,
+ arms = 41,
+ pants_1 = 25, pants_2 = 0,
+ shoes_1 = 25, shoes_2 = 0,
+ helmet_1 = -1, helmet_2 = 0,
+ chain_1 = 0, chain_2 = 0,
+ ears_1 = 2, ears_2 = 0
+ },
+ female = {
+ tshirt_1 = 35, tshirt_2 = 0,
+ torso_1 = 48, torso_2 = 0,
+ decals_1 = 7, decals_2 = 2,
+ arms = 44,
+ pants_1 = 34, pants_2 = 0,
+ shoes_1 = 27, shoes_2 = 0,
+ helmet_1 = -1, helmet_2 = 0,
+ chain_1 = 0, chain_2 = 0,
+ ears_1 = 2, ears_2 = 0
+ }
+ },
+
+ boss = {
+ male = {
+ tshirt_1 = 58, tshirt_2 = 0,
+ torso_1 = 55, torso_2 = 0,
+ decals_1 = 8, decals_2 = 3,
+ arms = 41,
+ pants_1 = 25, pants_2 = 0,
+ shoes_1 = 25, shoes_2 = 0,
+ helmet_1 = -1, helmet_2 = 0,
+ chain_1 = 0, chain_2 = 0,
+ ears_1 = 2, ears_2 = 0
+ },
+ female = {
+ tshirt_1 = 35, tshirt_2 = 0,
+ torso_1 = 48, torso_2 = 0,
+ decals_1 = 7, decals_2 = 3,
+ arms = 44,
+ pants_1 = 34, pants_2 = 0,
+ shoes_1 = 27, shoes_2 = 0,
+ helmet_1 = -1, helmet_2 = 0,
+ chain_1 = 0, chain_2 = 0,
+ ears_1 = 2, ears_2 = 0
+ }
+ },
+
+ bullet_wear = {
+ male = {
+ bproof_1 = 11, bproof_2 = 1
+ },
+ female = {
+ bproof_1 = 13, bproof_2 = 1
+ }
+ },
+
+ gilet_wear = {
+ male = {
+ tshirt_1 = 59, tshirt_2 = 1
+ },
+ female = {
+ tshirt_1 = 36, tshirt_2 = 1
+ }
+ }
+}
diff --git a/_resources/esx_policejob/esx_policejob.sql b/_resources/esx_policejob/esx_policejob.sql
new file mode 100644
index 00000000..fcc92964
--- /dev/null
+++ b/_resources/esx_policejob/esx_policejob.sql
@@ -0,0 +1,89 @@
+USE `es_extended`;
+
+INSERT INTO `addon_account` (name, label, shared) VALUES
+ ('society_police', 'Police', 1)
+;
+
+INSERT INTO `datastore` (name, label, shared) VALUES
+ ('society_police', 'Police', 1)
+;
+
+INSERT INTO `addon_inventory` (name, label, shared) VALUES
+ ('society_police', 'Police', 1)
+;
+
+INSERT INTO `jobs` (name, label) VALUES
+ ('police', 'LSPD')
+;
+
+INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES
+ ('police',0,'recruit','Recrue',20,'{}','{}'),
+ ('police',1,'officer','Officier',40,'{}','{}'),
+ ('police',2,'sergeant','Sergent',60,'{}','{}'),
+ ('police',3,'lieutenant','Lieutenant',85,'{}','{}'),
+ ('police',4,'boss','Commandant',100,'{}','{}')
+;
+
+CREATE TABLE `fine_types` (
+ `id` int NOT NULL AUTO_INCREMENT,
+ `label` varchar(255) DEFAULT NULL,
+ `amount` int DEFAULT NULL,
+ `category` int DEFAULT NULL,
+
+ PRIMARY KEY (`id`)
+);
+
+INSERT INTO `fine_types` (label, amount, category) VALUES
+ ('Usage abusif du klaxon',30,0),
+ ('Franchir une ligne continue',40,0),
+ ('Circulation à contresens',250,0),
+ ('Demi-tour non autorisé',250,0),
+ ('Circulation hors-route',170,0),
+ ('Non-respect des distances de sécurité',30,0),
+ ('Arrêt dangereux / interdit',150,0),
+ ('Stationnement gênant / interdit',70,0),
+ ('Non respect de la priorité à droite',70,0),
+ ('Non-respect à un véhicule prioritaire',90,0),
+ ('Non-respect d\'un stop',105,0),
+ ('Non-respect d\'un feu rouge',130,0),
+ ('Dépassement dangereux',100,0),
+ ('Véhicule non en état',100,0),
+ ('Conduite sans permis',1500,0),
+ ('Délit de fuite',800,0),
+ ('Excès de vitesse < 5 kmh',90,0),
+ ('Excès de vitesse 5-15 kmh',120,0),
+ ('Excès de vitesse 15-30 kmh',180,0),
+ ('Excès de vitesse > 30 kmh',300,0),
+ ('Entrave de la circulation',110,1),
+ ('Dégradation de la voie publique',90,1),
+ ('Trouble à l\'ordre publique',90,1),
+ ('Entrave opération de police',130,1),
+ ('Insulte envers / entre civils',75,1),
+ ('Outrage à agent de police',110,1),
+ ('Menace verbale ou intimidation envers civil',90,1),
+ ('Menace verbale ou intimidation envers policier',150,1),
+ ('Manifestation illégale',250,1),
+ ('Tentative de corruption',1500,1),
+ ('Arme blanche sortie en ville',120,2),
+ ('Arme léthale sortie en ville',300,2),
+ ('Port d\'arme non autorisé (défaut de license)',600,2),
+ ('Port d\'arme illégal',700,2),
+ ('Pris en flag lockpick',300,2),
+ ('Vol de voiture',1800,2),
+ ('Vente de drogue',1500,2),
+ ('Fabriquation de drogue',1500,2),
+ ('Possession de drogue',650,2),
+ ('Prise d\'ôtage civil',1500,2),
+ ('Prise d\'ôtage agent de l\'état',2000,2),
+ ('Braquage particulier',650,2),
+ ('Braquage magasin',650,2),
+ ('Braquage de banque',1500,2),
+ ('Tir sur civil',2000,3),
+ ('Tir sur agent de l\'état',2500,3),
+ ('Tentative de meurtre sur civil',3000,3),
+ ('Tentative de meurtre sur agent de l\'état',5000,3),
+ ('Meurtre sur civil',10000,3),
+ ('Meurte sur agent de l\'état',30000,3),
+ ('Meurtre involontaire',1800,3),
+ ('Escroquerie à l\'entreprise',2000,2)
+;
diff --git a/_resources/esx_policejob/fxmanifest.lua b/_resources/esx_policejob/fxmanifest.lua
new file mode 100644
index 00000000..5f07436d
--- /dev/null
+++ b/_resources/esx_policejob/fxmanifest.lua
@@ -0,0 +1,51 @@
+fx_version 'adamant'
+
+game 'gta5'
+
+description 'ESX Police Job'
+
+version '1.3.0'
+
+server_scripts {
+ '@mysql-async/lib/MySQL.lua',
+ '@es_extended/locale.lua',
+ 'locales/br.lua',
+ 'locales/de.lua',
+ 'locales/en.lua',
+ 'locales/pl.lua',
+ 'locales/fr.lua',
+ 'locales/fi.lua',
+ 'locales/es.lua',
+ 'locales/sv.lua',
+ 'locales/ko.lua',
+ 'locales/cs.lua',
+ 'locales/nl.lua',
+ 'locales/tr.lua',
+ 'config.lua',
+ 'server/main.lua'
+}
+
+client_scripts {
+ '@es_extended/locale.lua',
+ 'locales/br.lua',
+ 'locales/de.lua',
+ 'locales/en.lua',
+ 'locales/pl.lua',
+ 'locales/fr.lua',
+ 'locales/fi.lua',
+ 'locales/es.lua',
+ 'locales/sv.lua',
+ 'locales/ko.lua',
+ 'locales/cs.lua',
+ 'locales/nl.lua',
+ 'locales/tr.lua',
+ 'config.lua',
+ 'client/main.lua',
+ 'client/vehicle.lua'
+}
+
+dependencies {
+ 'es_extended',
+ 'esx_billing',
+ 'esx_vehicleshop'
+}
diff --git a/_resources/esx_policejob/locales/br.lua b/_resources/esx_policejob/locales/br.lua
new file mode 100644
index 00000000..cadc743f
--- /dev/null
+++ b/_resources/esx_policejob/locales/br.lua
@@ -0,0 +1,151 @@
+Locales['br'] = {
+ -- Cloackroom
+ ['cloakroom'] = 'Vestiário',
+ ['citizen_wear'] = 'Roupa casual',
+ ['police_wear'] = 'Uniforme da Polícia',
+ ['gilet_wear'] = 'orange reflective jacket',
+ ['bullet_wear'] = 'bulletproof vest',
+ ['no_outfit'] = 'there\'s no uniform that fits you!',
+ ['open_cloackroom'] = 'Pressione ~INPUT_CONTEXT~ para se trocar',
+ -- Armory
+ ['remove_object'] = 'take object',
+ ['deposit_object'] = 'deposit object',
+ ['get_weapon'] = 'Pegar arma',
+ ['put_weapon'] = 'Entregar arma',
+ ['buy_weapons'] = 'Comprar armas',
+ ['armory'] = 'Arsenal',
+ ['open_armory'] = 'Pressione ~INPUT_CONTEXT~ para acessar o arsenal',
+ ['armory_owned'] = 'owned',
+ ['armory_free'] = 'free',
+ ['armory_item'] = '$%s',
+ ['armory_weapontitle'] = 'armory - Buy weapon',
+ ['armory_componenttitle'] = 'armory - Weapon attatchments',
+ ['armory_bought'] = 'you bought an ~y~%s~s~ for ~g~$%s~s~',
+ ['armory_money'] = 'you cannot afford that weapon',
+ ['armory_hascomponent'] = 'you have that attatchment equiped!',
+ ['get_weapon_menu'] = 'armory - Withdraw Weapon',
+ ['put_weapon_menu'] = 'armory - Store Weapon',
+ -- Vehicles
+ ['vehicle_menu'] = 'vehicle',
+ ['vehicle_blocked'] = 'all available spawn points are currently blocked!',
+ ['garage_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Vehicle Actions~s~.',
+ ['garage_title'] = 'vehicle Actions',
+ ['garage_stored'] = 'stored',
+ ['garage_notstored'] = 'not in garage',
+ ['garage_storing'] = 'we\'re attempting to remove the vehicle, make sure no players are around it.',
+ ['garage_has_stored'] = 'the vehicle has been stored in your garage',
+ ['garage_has_notstored'] = 'no nearby owned vehicles were found',
+ ['garage_notavailable'] = 'your vehicle is not stored in the garage.',
+ ['garage_blocked'] = 'there\'s no available spawn points!',
+ ['garage_empty'] = 'you dont have any vehicles in your garage.',
+ ['garage_released'] = 'your vehicle has been released from the garage.',
+ ['garage_store_nearby'] = 'there is no nearby vehicles.',
+ ['garage_storeditem'] = 'open garage',
+ ['garage_storeitem'] = 'store vehicle in garage',
+ ['garage_buyitem'] = 'vehicle shop',
+ ['garage_notauthorized'] = 'you\'re not authorized to buy this kind of vehicles.',
+ ['helicopter_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Helicopter Actions~s~.',
+ ['shop_item'] = '$%s',
+ ['vehicleshop_title'] = 'vehicle Shop',
+ ['vehicleshop_confirm'] = 'do you want to buy this vehicle?',
+ ['vehicleshop_bought'] = 'you have bought ~y~%s~s~ for ~g~$%s~s~',
+ ['vehicleshop_money'] = 'you cannot afford that vehicle',
+ ['vehicleshop_awaiting_model'] = 'the vehicle is currently ~g~DOWNLOADING & LOADING~s~ please wait',
+ ['confirm_no'] = 'no',
+ ['confirm_yes'] = 'yes',
+ -- Service
+ ['service_max'] = 'you cannot enter service, max officers in service: %s/%s',
+ ['service_not'] = 'you have not entered service! You\'ll have to get changed first.',
+ ['service_anonunce'] = 'service information',
+ ['service_in'] = 'you\'ve entered service, welcome!',
+ ['service_in_announce'] = 'operator ~y~%s~s~ has entered service!',
+ ['service_out'] = 'you have left service.',
+ ['service_out_announce'] = 'operator ~y~%s~s~ has left their service.',
+ -- Action Menu
+ ['citizen_interaction'] = 'Interagir com o cidadão',
+ ['vehicle_interaction'] = 'Interagir com o veículo',
+ ['object_spawner'] = 'Interagir com as rodovias',
+
+ ['id_card'] = 'Carteira de identidade',
+ ['search'] = 'Procurar',
+ ['handcuff'] = 'Algemar / Soltar',
+ ['drag'] = 'drag',
+ ['put_in_vehicle'] = 'Colocar no veículo',
+ ['out_the_vehicle'] = 'take out of vehicle',
+ ['fine'] = 'Multa',
+ ['unpaid_bills'] = 'manage unpaid bills',
+ ['license_check'] = 'manage license',
+ ['license_revoke'] = 'revoke license',
+ ['license_revoked'] = 'your ~b~%s~s~ has been ~y~revoked~s~!',
+ ['licence_you_revoked'] = 'you revoked a ~b~%s~s~ which belonged to ~y~%s~s~',
+ ['no_players_nearby'] = 'nenhum jogador nas proximidades',
+ ['being_searched'] = 'you are being ~y~searched~s~ by the ~b~Police~s~',
+ -- Vehicle interaction
+ ['vehicle_info'] = 'Informações',
+ ['pick_lock'] = 'Trancar veículo',
+ ['vehicle_unlocked'] = 'Veículo ~g~destravado~s~',
+ ['no_vehicles_nearby'] = 'Nenhum veículo nas proximidades',
+ ['impound'] = 'apreender carro',
+ ['impound_prompt'] = 'Pressione ~INPUT_CONTEXT~ para cancelar a ~y~apreender~s~',
+ ['impound_canceled'] = 'you canceled the impound',
+ ['impound_canceled_moved'] = 'o apreender foi cancelado porque o veículo mudou',
+ ['impound_successful'] = 'você apreendeu o veículo',
+ ['search_database'] = 'informação do veículo',
+ ['search_database_title'] = 'informações do veículo - pesquisa com número de registro',
+ ['search_database_error_invalid'] = 'que ~r~não~s~ é um número de registro ~y~válido~s~',
+ -- Traffic interaction
+ ['traffic_interaction'] = 'Interagir com as rodovias',
+ ['cone'] = 'Cones',
+ ['barrier'] = 'Barreira',
+ ['spikestrips'] = 'Fita de pregos',
+ ['box'] = 'Caixa',
+ ['cash'] = 'Caixa de dinheiro',
+ -- ID Card Menu
+ ['name'] = 'name: %s',
+ ['job'] = 'job: %s',
+ ['sex'] = 'sex: %s',
+ ['dob'] = 'DOB: %s',
+ ['height'] = 'height: %s',
+ ['bac'] = 'BAC: %s',
+ ['unknown'] = 'unknown',
+ ['male'] = 'male',
+ ['female'] = 'female',
+ -- Body Search Menu
+ ['guns_label'] = '--- Armas ---',
+ ['inventory_label'] = '--- Inventário ---',
+ ['license_label'] = ' --- Licenses ---',
+ ['confiscate'] = 'confiscar %s',
+ ['confiscate_weapon'] = 'confiscate %s with %s bullets',
+ ['confiscate_inv'] = 'Confiscar %sx %s',
+ ['confiscate_dirty'] = 'Confiscar dinheiro sujo: $%s',
+ ['you_confiscated'] = 'you confiscated ~y~%sx~s~ ~b~%s~s~ from ~b~%s~s~',
+ ['got_confiscated'] = '~y~%sx~s~ ~b~%s~s~ were confiscated by ~y~%s~s~',
+ ['you_confiscated_account'] = 'you confiscated ~g~$%s~s~ (%s) from ~b~%s~s~',
+ ['got_confiscated_account'] = '~g~$%s~s~ (%s) was confiscated by ~y~%s~s~',
+ ['you_confiscated_weapon'] = 'you confiscated ~b~%s~s~ from ~b~%s~s~ with ~o~%s~s~ bullets',
+ ['got_confiscated_weapon'] = 'your ~b~%s~s~ with ~o~%s~s~ bullets was confiscated by ~y~%s~s~',
+ ['traffic_offense'] = 'Infrações de transito',
+ ['minor_offense'] = 'Infração leve',
+ ['average_offense'] = 'Infração média',
+ ['major_offense'] = 'Infração grave',
+ ['fine_total'] = 'multa: %s',
+ -- Vehicle Info Menu
+ ['plate'] = 'placa: %s',
+ ['owner_unknown'] = 'proprietário: Desconhecido',
+ ['owner'] = 'proprietário: %s',
+ -- Boss Menu
+ ['open_bossmenu'] = 'Pressione ~INPUT_CONTEXT~ para abrir o menu',
+ ['quantity_invalid'] = 'invalid quantity',
+ ['have_withdrawn'] = 'you have withdrawn ~y~%sx~s~ ~b~%s~s~',
+ ['have_deposited'] = 'you have deposited ~y~%sx~s~ ~b~%s~s~',
+ ['quantity'] = 'quantity',
+ ['inventory'] = 'inventory',
+ ['police_stock'] = 'police Stock',
+ -- Misc
+ ['remove_prop'] = 'Pressione ~INPUT_CONTEXT~ para remover o objeto',
+ ['map_blip'] = 'Departamento de Polícia',
+ ['unrestrained_timer'] = 'you feel your handcuffs slowly losing grip and fading away.',
+ -- Notifications
+ ['alert_police'] = 'Alerta da Polícia',
+ ['phone_police'] = 'police',
+}
diff --git a/_resources/esx_policejob/locales/cs.lua b/_resources/esx_policejob/locales/cs.lua
new file mode 100644
index 00000000..0c494b2f
--- /dev/null
+++ b/_resources/esx_policejob/locales/cs.lua
@@ -0,0 +1,151 @@
+Locales['cs'] = {
+ -- Cloakroom
+ ['cloakroom'] = 'satna',
+ ['citizen_wear'] = 'civilní oblek',
+ ['police_wear'] = 'policejní oblek',
+ ['gilet_wear'] = 'oranžová reflexní vesta',
+ ['bullet_wear'] = 'neprůstřelná vesta',
+ ['no_outfit'] = 'není zde žádná uniforma, která by ti sedla!',
+ ['open_cloackroom'] = 'stiskni ~INPUT_CONTEXT~ pro změnu ~y~oblečení~s~.',
+ -- Armory
+ ['remove_object'] = 'vzít objekt',
+ ['deposit_object'] = 'odevzdat objekt',
+ ['get_weapon'] = 'vzít zbraň ze zbrojnice',
+ ['put_weapon'] = 'uchovat zbraň ve zbrojnici',
+ ['buy_weapons'] = 'koupit zbraně',
+ ['armory'] = 'zbrojnice',
+ ['open_armory'] = 'stiskni ~INPUT_CONTEXT~ pro přístup do ~y~zbrojnice~s~.',
+ ['armory_owned'] = 'vlastněno',
+ ['armory_free'] = 'zdarma',
+ ['armory_item'] = '$%s',
+ ['armory_weapontitle'] = 'zbrojnice',
+ ['armory_componenttitle'] = 'zbrojnice - Příslušenství ke zbraním',
+ ['armory_bought'] = 'zakoupil jsi ~y~%s~s~ za ~g~$%s~s~',
+ ['armory_money'] = 'nemáš dostatek peněz na tuto zbraň',
+ ['armory_hascomponent'] = 'toto příslušenství máš již nainstalováno!',
+ ['get_weapon_menu'] = 'zbrojnice - Vzít zbraň',
+ ['put_weapon_menu'] = 'zbrojnice - Uchovat zbraň',
+ -- Vehicles
+ ['vehicle_menu'] = 'vozidlo',
+ ['vehicle_blocked'] = 'vsechny dostupne spawn pointy jsou blokovany!',
+ ['garage_prompt'] = 'stiskni ~INPUT_CONTEXT~ pro otevreni ~y~akce vozidel~s~.',
+ ['garage_title'] = 'akce vozidel',
+ ['garage_stored'] = 'uloženo',
+ ['garage_notstored'] = 'není v garáži',
+ ['garage_storing'] = 'pokousime se o odstraneni vozidla, ujisti se, ze kolem nej nejsou hraci.',
+ ['garage_has_stored'] = 'vozidlo bylo ulozeno do garaze',
+ ['garage_has_notstored'] = 'zadne nejblizsi vlastnene vozidlo nenalezeno',
+ ['garage_notavailable'] = 'tvoje vozidlo neni ulozeno v garazi.',
+ ['garage_blocked'] = 'nejsou zde zadne spawn pointy!',
+ ['garage_empty'] = 'zadne vozidlo nemas v garazi.',
+ ['garage_released'] = 'tvoje vozidlo bylo vyjmuto z garaze.',
+ ['garage_store_nearby'] = 'nejsou poblíž zádná vozidla.',
+ ['garage_storeditem'] = 'otevřít garáž',
+ ['garage_storeitem'] = 'uchovat vozidlo v garáži',
+ ['garage_buyitem'] = 'prodej vozidel',
+ ['garage_notauthorized'] = 'nemas opravneni ke koupi tohoto vozidla.',
+ ['helicopter_prompt'] = 'stiskni ~INPUT_CONTEXT~ pro pristup k ~y~akcim Helikopter~s~.',
+ ['shop_item'] = '$%s',
+ ['vehicleshop_title'] = 'prodejce vozidel',
+ ['vehicleshop_confirm'] = 'opravdu chces koupit toto vozidlo?',
+ ['vehicleshop_bought'] = 'koupil jsi ~y~%s~s~ za ~r~$%s~s~',
+ ['vehicleshop_money'] = 'toto vozidlo si nemuzete dovolit',
+ ['vehicleshop_awaiting_model'] = 'vozidlo se prave ~g~stahuje a nacita~s~ prosim pockej',
+ ['confirm_no'] = 'ne',
+ ['confirm_yes'] = 'ano',
+ -- Service
+ ['service_max'] = 'nemuzete vstoupit do sluzby, max dustojníci v provozu: %s/%s',
+ ['service_not'] = 'nezadali jste sluzbu! Nejprve se musíte zmenit.',
+ ['service_anonunce'] = 'informace o sluzbe',
+ ['service_in'] = 'vstoupil jsi do sluzby, vitej!',
+ ['service_in_announce'] = 'operator ~y~%s~s~ se pripojil do sluzby!',
+ ['service_out'] = 'opustil jsi sluzbu.',
+ ['service_out_announce'] = 'operator ~y~%s~s~ opustil jejich sluzbu.',
+ -- Action Menu
+ ['citizen_interaction'] = 'Interakce s občanem',
+ ['vehicle_interaction'] = 'Interakce vozidla',
+ ['object_spawner'] = 'Objekty',
+
+ ['id_card'] = 'Občanský průkaz',
+ ['search'] = 'prohledat',
+ ['handcuff'] = 'poutat / odpoutat',
+ ['drag'] = 'prenést',
+ ['put_in_vehicle'] = 'vlozit do vozidla',
+ ['out_the_vehicle'] = 'vytahnout z vozidla',
+ ['fine'] = 'pokuta',
+ ['unpaid_bills'] = 'spravovat nezaplacené pokuty',
+ ['license_check'] = 'spravovat průkazy',
+ ['license_revoke'] = 'zneplatnit průkaz',
+ ['license_revoked'] = 'vase ~b~%s~s~ bylo ~y~zruseno~s~!',
+ ['licence_you_revoked'] = 'zrusil jsi ~b~%s~s~ ktery patril ~y~%s~s~',
+ ['no_players_nearby'] = 'zadny hrac pobliz!',
+ ['being_searched'] = 'prave jsi ~y~prohledavan~s~ ~b~policii~s~',
+ -- Vehicle interaction
+ ['vehicle_info'] = 'informace o vozidle',
+ ['pick_lock'] = 'vypáčit vozidlo',
+ ['vehicle_unlocked'] = 'vozidlo je ~g~Odemčeno~s~',
+ ['no_vehicles_nearby'] = 'there is no vehicles nearby',
+ ['impound'] = 'odtahnout vozidlo',
+ ['impound_prompt'] = 'zmackni ~INPUT_CONTEXT~ pro zruseni ~y~odtahnuti~s~',
+ ['impound_canceled'] = 'zrusil jsi odtah',
+ ['impound_canceled_moved'] = 'odtah byl zrusen,protoze se vozidlo pohlo!',
+ ['impound_successful'] = 'uspesne jsi odtahl vozidlo',
+ ['search_database'] = 'informace o vozidle',
+ ['search_database_title'] = 'informace o vozidle - pomocí registracnich cisel',
+ ['search_database_error_invalid'] = 'tohle ~r~neni~s~ ~y~spravne~s~ registracni cislo',
+ -- Traffic interaction
+ ['traffic_interaction'] = 'interakce provozu',
+ ['cone'] = 'kuzel',
+ ['barrier'] = 'bariera',
+ ['spikestrips'] = 'ostnaty pas',
+ ['box'] = 'box',
+ ['cash'] = 'box penez',
+ -- ID Card Menu
+ ['name'] = 'jméno: %s',
+ ['job'] = 'práce: %s',
+ ['sex'] = 'pohlaví: %s',
+ ['dob'] = 'DOB: %s',
+ ['height'] = 'výška: %s',
+ ['bac'] = 'BAC: %s',
+ ['unknown'] = 'neznámé',
+ ['male'] = 'muž',
+ ['female'] = 'žena',
+ -- Body Search Menu
+ ['guns_label'] = '--- Zbraně ---',
+ ['inventory_label'] = '--- Inventář ---',
+ ['license_label'] = ' --- Průkazy ---',
+ ['confiscate'] = 'zabavit %s',
+ ['confiscate_weapon'] = 'zabavit %s s %s naboji',
+ ['confiscate_inv'] = 'zabavit %sx %s',
+ ['confiscate_dirty'] = 'zabavit spinave penize: $%s',
+ ['you_confiscated'] = 'zabavil jsi ~y~%sx~s~ ~b~%s~s~ od ~b~%s~s~',
+ ['got_confiscated'] = '~y~%sx~s~ ~b~%s~s~ byly zabaveny od ~y~%s~s~',
+ ['you_confiscated_account'] = 'zabavil jsi ~g~$%s~s~ (%s) od ~b~%s~s~',
+ ['got_confiscated_account'] = '~g~$%s~s~ (%s) byly zabaveny ~y~%s~s~',
+ ['you_confiscated_weapon'] = 'zabavil jsi ~b~%s~s~ od ~b~%s~s~ s ~o~%s~s~ naboji ',
+ ['got_confiscated_weapon'] = 'tvoje ~b~%s~s~ s ~o~%s~s~ bylo zabaveno od ~y~%s~s~',
+ ['traffic_offense'] = 'dopravní přestupek',
+ ['minor_offense'] = 'malý přestupek',
+ ['average_offense'] = 'přestupek',
+ ['major_offense'] = 'trestný čin',
+ ['fine_total'] = 'pokuta: %s',
+ -- Vehicle Info Menu
+ ['plate'] = 'SPZ: %s',
+ ['owner_unknown'] = 'vlastník: Neznámý',
+ ['owner'] = 'vlastník: %s',
+ -- Boss Menu
+ ['open_bossmenu'] = 'stiskni ~INPUT_CONTEXT~ pro otevření menu',
+ ['quantity_invalid'] = 'neplatné množství',
+ ['have_withdrawn'] = 'vybral jsi ~y~%sx~s~ ~b~%s~s~',
+ ['have_deposited'] = 'vložil jsi ~y~%sx~s~ ~b~%s~s~',
+ ['quantity'] = 'množství',
+ ['inventory'] = 'inventář',
+ ['police_stock'] = 'policejní sklad',
+ -- Misc
+ ['remove_prop'] = 'stiskni ~INPUT_CONTEXT~ pro odstranění předmětu',
+ ['map_blip'] = 'policejní stanice',
+ ['unrestrained_timer'] = 'cítíš, že tvé pouta pomalu ztrácejí přilnavost a padají.',
+ -- Notifications
+ ['alert_police'] = 'policejní poplach',
+ ['phone_police'] = 'policie',
+}
diff --git a/_resources/esx_policejob/locales/de.lua b/_resources/esx_policejob/locales/de.lua
new file mode 100644
index 00000000..5ed2776f
--- /dev/null
+++ b/_resources/esx_policejob/locales/de.lua
@@ -0,0 +1,151 @@
+Locales['de'] = {
+ -- Cloackroom
+ ['cloakroom'] = 'Garderobe',
+ ['citizen_wear'] = 'Zivilkleidung',
+ ['police_wear'] = 'Arbeitskleidung',
+ ['gilet_wear'] = 'orange reflective jacket',
+ ['bullet_wear'] = 'bulletproof vest',
+ ['no_outfit'] = 'there\'s no uniform that fits you!',
+ ['open_cloackroom'] = 'Drücke ~INPUT_CONTEXT~ um dich umzuziehen',
+ -- Armory
+ ['remove_object'] = 'take object',
+ ['deposit_object'] = 'deposit object',
+ ['get_weapon'] = 'Waffen holen',
+ ['put_weapon'] = 'Waffen bringen',
+ ['buy_weapons'] = 'Waffen kaufen',
+ ['armory'] = 'Waffenkammer',
+ ['open_armory'] = 'Drücke ~INPUT_CONTEXT~ um die Waffenkammer zu öffnen',
+ ['armory_owned'] = 'owned',
+ ['armory_free'] = 'free',
+ ['armory_item'] = '$%s',
+ ['armory_weapontitle'] = 'armory - Buy weapon',
+ ['armory_componenttitle'] = 'armory - Weapon attatchments',
+ ['armory_bought'] = 'you bought an ~y~%s~s~ for ~g~$%s~s~',
+ ['armory_money'] = 'you cannot afford that weapon',
+ ['armory_hascomponent'] = 'you have that attatchment equiped!',
+ ['get_weapon_menu'] = 'armory - Withdraw Weapon',
+ ['put_weapon_menu'] = 'armory - Store Weapon',
+ -- Vehicles
+ ['vehicle_menu'] = 'vehicle',
+ ['vehicle_blocked'] = 'all available spawn points are currently blocked!',
+ ['garage_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Vehicle Actions~s~.',
+ ['garage_title'] = 'vehicle Actions',
+ ['garage_stored'] = 'stored',
+ ['garage_notstored'] = 'not in garage',
+ ['garage_storing'] = 'we\'re attempting to remove the vehicle, make sure no players are around it.',
+ ['garage_has_stored'] = 'the vehicle has been stored in your garage',
+ ['garage_has_notstored'] = 'no nearby owned vehicles were found',
+ ['garage_notavailable'] = 'your vehicle is not stored in the garage.',
+ ['garage_blocked'] = 'there\'s no available spawn points!',
+ ['garage_empty'] = 'you dont have any vehicles in your garage.',
+ ['garage_released'] = 'your vehicle has been released from the garage.',
+ ['garage_store_nearby'] = 'there is no nearby vehicles.',
+ ['garage_storeditem'] = 'open garage',
+ ['garage_storeitem'] = 'store vehicle in garage',
+ ['garage_buyitem'] = 'vehicle shop',
+ ['garage_notauthorized'] = 'you\'re not authorized to buy this kind of vehicles.',
+ ['helicopter_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Helicopter Actions~s~.',
+ ['shop_item'] = '$%s',
+ ['vehicleshop_title'] = 'vehicle Shop',
+ ['vehicleshop_confirm'] = 'do you want to buy this vehicle?',
+ ['vehicleshop_bought'] = 'you have bought ~y~%s~s~ for ~r~$%s~s~',
+ ['vehicleshop_money'] = 'you cannot afford that vehicle',
+ ['vehicleshop_awaiting_model'] = 'the vehicle is currently ~g~DOWNLOADING & LOADING~s~ please wait',
+ ['confirm_no'] = 'no',
+ ['confirm_yes'] = 'yes',
+ -- Service
+ ['service_max'] = 'you cannot enter service, max officers in service: %s/%s',
+ ['service_not'] = 'you have not entered service! You\'ll have to get changed first.',
+ ['service_anonunce'] = 'service information',
+ ['service_in'] = 'you\'ve entered service, welcome!',
+ ['service_in_announce'] = 'operator ~y~%s~s~ has entered service!',
+ ['service_out'] = 'you have left service.',
+ ['service_out_announce'] = 'operator ~y~%s~s~ has left their service.',
+ -- Action Menu
+ ['citizen_interaction'] = 'Zivilistenaktionen',
+ ['vehicle_interaction'] = 'Fahrzeuginteraktionen',
+ ['object_spawner'] = 'Objekt Spawner',
+
+ ['id_card'] = 'ID Karte',
+ ['search'] = 'Suche',
+ ['handcuff'] = 'Festnehmen / Freilassen',
+ ['drag'] = 'drag',
+ ['put_in_vehicle'] = 'In Fahrzeug setzen',
+ ['out_the_vehicle'] = 'take out of vehicle',
+ ['fine'] = 'Strafe',
+ ['unpaid_bills'] = 'manage unpaid bills',
+ ['license_check'] = 'manage license',
+ ['license_revoke'] = 'revoke license',
+ ['license_revoked'] = 'your ~b~%s~s~ has been ~y~revoked~s~!',
+ ['licence_you_revoked'] = 'you revoked a ~b~%s~s~ which belonged to ~y~%s~s~',
+ ['no_players_nearby'] = 'keine Spieler in der Nähe',
+ ['being_searched'] = 'you are being ~y~searched~s~ by the ~b~Police~s~',
+ -- Vehicle interaction
+ ['vehicle_info'] = 'Fahrzeug Info',
+ ['pick_lock'] = 'Fahrzeug öffnen',
+ ['vehicle_unlocked'] = 'Fahrzeug ~g~offen~s~',
+ ['no_vehicles_nearby'] = 'Keine Fahrzeuge in der Nähe',
+ ['impound'] = 'impound vehicle',
+ ['impound_prompt'] = 'press ~INPUT_CONTEXT~ to cancel the ~y~impound~s~',
+ ['impound_canceled'] = 'you canceled the impound',
+ ['impound_canceled_moved'] = 'the impound has been canceled because the vehicle moved',
+ ['impound_successful'] = 'you have impounded the vehicle',
+ ['search_database'] = 'vehicle information',
+ ['search_database_title'] = 'vehicle information - search with registration number',
+ ['search_database_error_invalid'] = 'that is ~r~not~s~ a ~y~valid~s~ registration number',
+ -- Traffic interaction
+ ['traffic_interaction'] = 'Straßeninteraktionen',
+ ['cone'] = 'Hütchen',
+ ['barrier'] = 'Barriere',
+ ['spikestrips'] = 'Nagelband',
+ ['box'] = 'Box',
+ ['cash'] = 'Box mit Geld',
+ -- ID Card Menu
+ ['name'] = 'name: %s',
+ ['job'] = 'job: %s',
+ ['sex'] = 'sex: %s',
+ ['dob'] = 'DOB: %s',
+ ['height'] = 'height: %s',
+ ['bac'] = 'BAC: %s',
+ ['unknown'] = 'unknown',
+ ['male'] = 'male',
+ ['female'] = 'female',
+ -- Body Search Menu
+ ['guns_label'] = '--- Waffen ---',
+ ['inventory_label'] = '--- Inventar ---',
+ ['license_label'] = ' --- Licenses ---',
+ ['confiscate'] = 'konfeszieren %s',
+ ['confiscate_weapon'] = 'confiscate %s with %s bullets',
+ ['confiscate_inv'] = 'konfeziere %sx %s',
+ ['confiscate_dirty'] = 'schwarzgeld konfesziert: $%s',
+ ['you_confiscated'] = 'you confiscated ~y~%sx~s~ ~b~%s~s~ from ~b~%s~s~',
+ ['got_confiscated'] = '~y~%sx~s~ ~b~%s~s~ were confiscated by ~y~%s~s~',
+ ['you_confiscated_account'] = 'you confiscated ~g~$%s~s~ (%s) from ~b~%s~s~',
+ ['got_confiscated_account'] = '~g~$%s~s~ (%s) was confiscated by ~y~%s~s~',
+ ['you_confiscated_weapon'] = 'you confiscated ~b~%s~s~ from ~b~%s~s~ with ~o~%s~s~ bullets',
+ ['got_confiscated_weapon'] = 'your ~b~%s~s~ with ~o~%s~s~ bullets was confiscated by ~y~%s~s~',
+ ['traffic_offense'] = 'Verkehrs vergehen',
+ ['minor_offense'] = 'Geringes vergehen',
+ ['average_offense'] = 'Normales vergehen',
+ ['major_offense'] = 'Hohes vergehen',
+ ['fine_total'] = 'strafe: %s',
+ -- Vehicle Info Menu
+ ['plate'] = 'plate: %s',
+ ['owner_unknown'] = 'besitzer: Unbekannt',
+ ['owner'] = 'besitzer: %s',
+ -- Boss Menu
+ ['open_bossmenu'] = 'Drücke ~INPUT_CONTEXT~ um das Menü zu öffnen',
+ ['quantity_invalid'] = 'invalid quantity',
+ ['have_withdrawn'] = 'you have withdrawn ~y~%sx~s~ ~b~%s~s~',
+ ['have_deposited'] = 'you have deposited ~y~%sx~s~ ~b~%s~s~',
+ ['quantity'] = 'quantity',
+ ['inventory'] = 'inventory',
+ ['police_stock'] = 'police Stock',
+ -- Misc
+ ['remove_prop'] = 'Drücke ~INPUT_CONTEXT~ um das Objekt zu entfernen',
+ ['map_blip'] = 'Polizeistation',
+ ['unrestrained_timer'] = 'you feel your handcuffs slowly losing grip and fading away.',
+ -- Notifications
+ ['alert_police'] = 'Polizei alamieren',
+ ['phone_police'] = 'police',
+}
diff --git a/_resources/esx_policejob/locales/en.lua b/_resources/esx_policejob/locales/en.lua
new file mode 100644
index 00000000..e7585c78
--- /dev/null
+++ b/_resources/esx_policejob/locales/en.lua
@@ -0,0 +1,151 @@
+Locales['en'] = {
+ -- Cloakroom
+ ['cloakroom'] = 'locker room',
+ ['citizen_wear'] = 'civilian Outfit',
+ ['police_wear'] = 'police Outfit',
+ ['gilet_wear'] = 'orange reflective jacket',
+ ['bullet_wear'] = 'bulletproof vest',
+ ['no_outfit'] = 'there\'s no uniform that fits you!',
+ ['open_cloackroom'] = 'press ~INPUT_CONTEXT~ to change ~y~clothes~s~.',
+ -- Armory
+ ['remove_object'] = 'withdraw object',
+ ['deposit_object'] = 'deposit object',
+ ['get_weapon'] = 'withdraw weapon from armory',
+ ['put_weapon'] = 'store weapon in armory',
+ ['buy_weapons'] = 'buy weapons',
+ ['armory'] = 'armory',
+ ['open_armory'] = 'press ~INPUT_CONTEXT~ to access the ~y~Armory~s~.',
+ ['armory_owned'] = 'owned',
+ ['armory_free'] = 'free',
+ ['armory_item'] = '$%s',
+ ['armory_weapontitle'] = 'armory - Buy weapon',
+ ['armory_componenttitle'] = 'armory - Weapon attatchments',
+ ['armory_bought'] = 'you bought an ~y~%s~s~ for ~g~$%s~s~',
+ ['armory_money'] = 'you cannot afford that weapon',
+ ['armory_hascomponent'] = 'you have that attatchment equiped!',
+ ['get_weapon_menu'] = 'armory - Withdraw Weapon',
+ ['put_weapon_menu'] = 'armory - Store Weapon',
+ -- Vehicles
+ ['vehicle_menu'] = 'vehicle',
+ ['vehicle_blocked'] = 'all available spawn points are currently blocked!',
+ ['garage_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Vehicle Actions~s~.',
+ ['garage_title'] = 'vehicle Actions',
+ ['garage_stored'] = 'stored',
+ ['garage_notstored'] = 'not in garage',
+ ['garage_storing'] = 'we\'re attempting to remove the vehicle, make sure no players are around it.',
+ ['garage_has_stored'] = 'the vehicle has been stored in your garage',
+ ['garage_has_notstored'] = 'no nearby owned vehicles were found',
+ ['garage_notavailable'] = 'your vehicle is not stored in the garage.',
+ ['garage_blocked'] = 'there\'s no available spawn points!',
+ ['garage_empty'] = 'you dont have any vehicles in your garage.',
+ ['garage_released'] = 'your vehicle has been released from the garage.',
+ ['garage_store_nearby'] = 'there is no nearby vehicles.',
+ ['garage_storeditem'] = 'open garage',
+ ['garage_storeitem'] = 'store vehicle in garage',
+ ['garage_buyitem'] = 'vehicle shop',
+ ['garage_notauthorized'] = 'you\'re not authorized to buy this kind of vehicles.',
+ ['helicopter_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Helicopter Actions~s~.',
+ ['shop_item'] = '$%s',
+ ['vehicleshop_title'] = 'vehicle Shop',
+ ['vehicleshop_confirm'] = 'do you want to buy this vehicle?',
+ ['vehicleshop_bought'] = 'you have bought ~y~%s~s~ for ~r~$%s~s~',
+ ['vehicleshop_money'] = 'you cannot afford that vehicle',
+ ['vehicleshop_awaiting_model'] = 'the vehicle is currently ~g~DOWNLOADING & LOADING~s~ please wait',
+ ['confirm_no'] = 'no',
+ ['confirm_yes'] = 'yes',
+ -- Service
+ ['service_max'] = 'you cannot enter service, max officers in service: %s/%s',
+ ['service_not'] = 'you have not entered service! You\'ll have to get changed first.',
+ ['service_anonunce'] = 'service information',
+ ['service_in'] = 'you\'ve entered service, welcome!',
+ ['service_in_announce'] = 'operator ~y~%s~s~ has entered service!',
+ ['service_out'] = 'you have left service.',
+ ['service_out_announce'] = 'operator ~y~%s~s~ has left their service.',
+ -- Action Menu
+ ['citizen_interaction'] = 'citizen Interaction',
+ ['vehicle_interaction'] = 'vehicle Interaction',
+ ['object_spawner'] = 'object Spawner',
+
+ ['id_card'] = 'ID Card',
+ ['search'] = 'search',
+ ['handcuff'] = 'cuff / Uncuff',
+ ['drag'] = 'escort',
+ ['put_in_vehicle'] = 'put in Vehicle',
+ ['out_the_vehicle'] = 'drag out from vehicle',
+ ['fine'] = 'fine',
+ ['unpaid_bills'] = 'manage unpaid bills',
+ ['license_check'] = 'manage license',
+ ['license_revoke'] = 'revoke license',
+ ['license_revoked'] = 'your ~b~%s~s~ has been ~y~revoked~s~!',
+ ['licence_you_revoked'] = 'you revoked a ~b~%s~s~ which belonged to ~y~%s~s~',
+ ['no_players_nearby'] = 'there is no player(s) nearby!',
+ ['being_searched'] = 'you are being ~y~searched~s~ by the ~b~Police~s~',
+ -- Vehicle interaction
+ ['vehicle_info'] = 'vehicle Info',
+ ['pick_lock'] = 'lockpick Vehicle',
+ ['vehicle_unlocked'] = 'vehicle ~g~Unlocked~s~',
+ ['no_vehicles_nearby'] = 'there is no vehicles nearby',
+ ['impound'] = 'impound vehicle',
+ ['impound_prompt'] = 'press ~INPUT_CONTEXT~ to cancel the ~y~impound~s~',
+ ['impound_canceled'] = 'you canceled the impound',
+ ['impound_canceled_moved'] = 'the impound has been canceled because the vehicle moved',
+ ['impound_successful'] = 'you have impounded the vehicle',
+ ['search_database'] = 'vehicle information',
+ ['search_database_title'] = 'vehicle information - search with registration number',
+ ['search_database_error_invalid'] = 'that is ~r~not~s~ a ~y~valid~s~ registration number',
+ -- Traffic interaction
+ ['traffic_interaction'] = 'interaction Traffic',
+ ['cone'] = 'cone',
+ ['barrier'] = 'barrier',
+ ['spikestrips'] = 'spikestrips',
+ ['box'] = 'box',
+ ['cash'] = 'box of cash',
+ -- ID Card Menu
+ ['name'] = 'name: %s',
+ ['job'] = 'job: %s',
+ ['sex'] = 'sex: %s',
+ ['dob'] = 'DOB: %s',
+ ['height'] = 'height: %s',
+ ['bac'] = 'BAC: %s',
+ ['unknown'] = 'unknown',
+ ['male'] = 'male',
+ ['female'] = 'female',
+ -- Body Search Menu
+ ['guns_label'] = '--- Guns ---',
+ ['inventory_label'] = '--- Inventory ---',
+ ['license_label'] = ' --- Licenses ---',
+ ['confiscate'] = 'confiscate %s',
+ ['confiscate_weapon'] = 'confiscate %s with %s bullets',
+ ['confiscate_inv'] = 'confiscate %sx %s',
+ ['confiscate_dirty'] = 'confiscate dirty money: $%s',
+ ['you_confiscated'] = 'you confiscated ~y~%sx~s~ ~b~%s~s~ from ~b~%s~s~',
+ ['got_confiscated'] = '~y~%sx~s~ ~b~%s~s~ were confiscated by ~y~%s~s~',
+ ['you_confiscated_account'] = 'you confiscated ~g~$%s~s~ (%s) from ~b~%s~s~',
+ ['got_confiscated_account'] = '~g~$%s~s~ (%s) was confiscated by ~y~%s~s~',
+ ['you_confiscated_weapon'] = 'you confiscated ~b~%s~s~ from ~b~%s~s~ with ~o~%s~s~ bullets',
+ ['got_confiscated_weapon'] = 'your ~b~%s~s~ with ~o~%s~s~ bullets was confiscated by ~y~%s~s~',
+ ['traffic_offense'] = 'traffic Offense',
+ ['minor_offense'] = 'minor Offense',
+ ['average_offense'] = 'average Offense',
+ ['major_offense'] = 'major Offense',
+ ['fine_total'] = 'fine: %s',
+ -- Vehicle Info Menu
+ ['plate'] = 'plate: %s',
+ ['owner_unknown'] = 'owner: Unknown',
+ ['owner'] = 'owner: %s',
+ -- Boss Menu
+ ['open_bossmenu'] = 'press ~INPUT_CONTEXT~ to open the menu',
+ ['quantity_invalid'] = 'invalid quantity',
+ ['have_withdrawn'] = 'you have withdrawn ~y~%sx~s~ ~b~%s~s~',
+ ['have_deposited'] = 'you have deposited ~y~%sx~s~ ~b~%s~s~',
+ ['quantity'] = 'quantity',
+ ['inventory'] = 'inventory',
+ ['police_stock'] = 'police Stock',
+ -- Misc
+ ['remove_prop'] = 'press ~INPUT_CONTEXT~ to delete the object',
+ ['map_blip'] = 'police Station',
+ ['unrestrained_timer'] = 'you feel your handcuffs slowly losing grip and fading away.',
+ -- Notifications
+ ['alert_police'] = 'police alert',
+ ['phone_police'] = 'police',
+}
diff --git a/_resources/esx_policejob/locales/es.lua b/_resources/esx_policejob/locales/es.lua
new file mode 100644
index 00000000..6c01770d
--- /dev/null
+++ b/_resources/esx_policejob/locales/es.lua
@@ -0,0 +1,151 @@
+Locales['es'] = {
+ -- Cloakroom
+ ['cloakroom'] = 'Taquilla',
+ ['citizen_wear'] = 'Ropa de civil',
+ ['police_wear'] = 'Uniforme',
+ ['gilet_wear'] = 'Chaqueta reflectante naranja',
+ ['bullet_wear'] = 'Chaleco antibalas',
+ ['no_outfit'] = '¡No hay ningún uniforme disponible para ti!',
+ ['open_cloackroom'] = 'Presionar ~INPUT_CONTEXT~ para abrir su taquilla',
+ -- Armory
+ ['remove_object'] = 'Coger objeto',
+ ['deposit_object'] = 'Depositar objeto',
+ ['get_weapon'] = 'Coger arma',
+ ['put_weapon'] = 'Depositar arma',
+ ['buy_weapons'] = 'Comprar armas',
+ ['armory'] = 'Armeria',
+ ['open_armory'] = 'Presionar ~INPUT_CONTEXT~ para acceder a la armeria',
+ ['armory_owned'] = 'Comprada',
+ ['armory_free'] = 'Gratis',
+ ['armory_item'] = '$%s',
+ ['armory_weapontitle'] = 'Armeria - Comprar arma',
+ ['armory_componenttitle'] = 'Armeria - Complementos del arma',
+ ['armory_bought'] = 'compraste una ~y~%s~s~ por ~g~$%s~s~',
+ ['armory_money'] = 'No dispones de suficiente dinero para comprar esta arma',
+ ['armory_hascomponent'] = '¡Ya dispones de ese complemento!',
+ ['get_weapon_menu'] = 'Armeria - Retirar arma',
+ ['put_weapon_menu'] = 'Armeria - Guardar arma',
+ -- Vehicles
+ ['vehicle_menu'] = 'Vehículos',
+ ['vehicle_blocked'] = '¡Todos los puntos de aparición de vehículos están ocupados!',
+ ['garage_prompt'] = 'Presione ~INPUT_CONTEXT~ para acceder a ~y~Acciones del Vehículo~s~.',
+ ['garage_title'] = 'Acciones del vehículo',
+ ['garage_stored'] = 'Guardado',
+ ['garage_notstored'] = 'No se encuentra en el garaje',
+ ['garage_storing'] = 'Estamos intentando borrar el vehículo, asegurate de que no haya jugadores cerca.',
+ ['garage_has_stored'] = 'El vehículo ha sido guardado en su garaje',
+ ['garage_has_notstored'] = 'no nearby owned vehicles were found',
+ ['garage_notavailable'] = 'Su vehículo no está guardado en el garaje.',
+ ['garage_blocked'] = '¡No hay ningún punto de spawn disponible!',
+ ['garage_empty'] = 'No dispones de ningún vehículo en su garaje.',
+ ['garage_released'] = 'your vehicle has been released from the garage.',
+ ['garage_store_nearby'] = 'No hay vehículos cercanos.',
+ ['garage_storeditem'] = 'Abrir garaje',
+ ['garage_storeitem'] = 'Guardar vehículo en el garaje',
+ ['garage_buyitem'] = 'Tienda de vehículos',
+ ['garage_notauthorized'] = 'No estás autorizado a comprar este tipo de vehículos.',
+ ['helicopter_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Helicopter Actions~s~.',
+ ['shop_item'] = '$%s',
+ ['vehicleshop_title'] = 'Tienda de vehículos',
+ ['vehicleshop_confirm'] = '¿Quieres comprar este vehículo?',
+ ['vehicleshop_bought'] = 'Has comprado un ~y~%s~s~ por ~r~$%s~s~',
+ ['vehicleshop_money'] = 'No tienes suficiente dinero para comprar este vehículo',
+ ['vehicleshop_awaiting_model'] = 'El vehículo se está ~g~DESCARGANDO Y CARGANDO~s~ porfavor espere',
+ ['confirm_no'] = 'no',
+ ['confirm_yes'] = 'si',
+ -- Service
+ ['service_max'] = 'No puedes entrar de servicio porque se ha alcanzado el número máximo: %s/%s',
+ ['service_not'] = '¡No has entrado de servicio! Debes hacerlo primeramente.',
+ ['service_anonunce'] = 'Información de servicio',
+ ['service_in'] = 'Has entrado de servicio. ¡Bienvenido!',
+ ['service_in_announce'] = '¡El agente ~y~%s~s~ ha entrado de servicio!',
+ ['service_out'] = 'Has salido de servicio.',
+ ['service_out_announce'] = 'El agente ~y~%s~s~ se ha salido de servicio.',
+ -- Action Menu
+ ['citizen_interaction'] = 'Interacción ciudadana',
+ ['vehicle_interaction'] = 'Interacción vehículo',
+ ['object_spawner'] = 'Colocar objetos',
+
+ ['id_card'] = 'Documento de identidad',
+ ['search'] = 'Buscar',
+ ['handcuff'] = 'Poner/quitar Esposas',
+ ['drag'] = 'escoltar',
+ ['put_in_vehicle'] = 'Meter en el vehículo',
+ ['out_the_vehicle'] = 'Sacar del vehículo',
+ ['fine'] = 'Multa',
+ ['unpaid_bills'] = 'manage unpaid bills',
+ ['license_check'] = 'Gestionar licencia',
+ ['license_revoke'] = 'Revocar licencia',
+ ['license_revoked'] = 'Su ~b~%s~s~ ha sido ~y~revocar~s~!',
+ ['licence_you_revoked'] = 'you revoked a ~b~%s~s~ which belonged to ~y~%s~s~',
+ ['no_players_nearby'] = 'no hay jugadores cerca',
+ ['being_searched'] = 'you are being ~y~searched~s~ by the ~b~Police~s~',
+ -- Vehicle interaction
+ ['vehicle_info'] = 'Información del vehículo',
+ ['pick_lock'] = 'Forzar coche',
+ ['vehicle_unlocked'] = 'Vehículo desbloqueado~s~',
+ ['no_vehicles_nearby'] = 'No hay vehículos cerca',
+ ['impound'] = 'Confiscar vehículo',
+ ['impound_prompt'] = 'Presione ~INPUT_CONTEXT~ para cancelar ~y~impound~s~',
+ ['impound_canceled'] = 'you canceled the impound',
+ ['impound_canceled_moved'] = 'the impound has been canceled because the vehicle moved',
+ ['impound_successful'] = 'you have impounded the vehicle',
+ ['search_database'] = 'vehicle information',
+ ['search_database_title'] = 'vehicle information - search with registration number',
+ ['search_database_error_invalid'] = 'that is ~r~not~s~ a ~y~valid~s~ registration number',
+ -- Traffic interaction
+ ['traffic_interaction'] = 'Rutas de interacción',
+ ['cone'] = 'Cono',
+ ['barrier'] = 'Barrera',
+ ['spikestrips'] = 'Grada',
+ ['box'] = 'Caja',
+ ['cash'] = 'Dinero',
+ -- ID Card Menu
+ ['name'] = 'Nombre: %s',
+ ['job'] = 'Trabajo: %s',
+ ['sex'] = 'Sexo: %s',
+ ['dob'] = 'DOB: %s',
+ ['height'] = 'Altura: %s',
+ ['bac'] = 'BAC: %s',
+ ['unknown'] = 'Desconocido',
+ ['male'] = 'Hombre',
+ ['female'] = 'Mujer',
+ -- Body Search Menu
+ ['guns_label'] = '--- Armas ---',
+ ['inventory_label'] = '--- Inventario ---',
+ ['license_label'] = ' --- Licenses ---',
+ ['confiscate'] = 'confiscar %s',
+ ['confiscate_weapon'] = 'confiscate %s with %s bullets',
+ ['confiscate_inv'] = 'confiscar %sx %s',
+ ['confiscate_dirty'] = 'confiscar dinero negro: €%s',
+ ['you_confiscated'] = 'you confiscated ~y~%sx~s~ ~b~%s~s~ from ~b~%s~s~',
+ ['got_confiscated'] = '~y~%sx~s~ ~b~%s~s~ were confiscated by ~y~%s~s~',
+ ['you_confiscated_account'] = 'Has confiscado ~g~€%s~s~ (%s) de ~b~%s~s~',
+ ['got_confiscated_account'] = '~g~€%s~s~ (%s) ha sido confiscado por ~y~%s~s~',
+ ['you_confiscated_weapon'] = 'you confiscated ~b~%s~s~ from ~b~%s~s~ with ~o~%s~s~ bullets',
+ ['got_confiscated_weapon'] = 'your ~b~%s~s~ with ~o~%s~s~ bullets was confiscated by ~y~%s~s~',
+ ['traffic_offense'] = 'Delito de tráfico',
+ ['minor_offense'] = 'Delito menor',
+ ['average_offense'] = 'Delito medio',
+ ['major_offense'] = 'Delito grave',
+ ['fine_total'] = 'Multa total: %s',
+ -- Vehicle Info Menu
+ ['plate'] = 'n°: %s',
+ ['owner_unknown'] = 'propietario: Desconocido',
+ ['owner'] = 'propietario: %s',
+ -- Boss Menu
+ ['open_bossmenu'] = 'presionar ~INPUT_CONTEXT~ para abrir el menú',
+ ['quantity_invalid'] = 'cantidad invalida',
+ ['have_withdrawn'] = 'you have withdrawn ~y~%sx~s~ ~b~%s~s~',
+ ['have_deposited'] = 'you have deposited ~y~%sx~s~ ~b~%s~s~',
+ ['quantity'] = 'cantidad',
+ ['inventory'] = 'inventario',
+ ['police_stock'] = 'almacen Policial',
+ -- Misc
+ ['remove_prop'] = 'presionar ~INPUT_CONTEXT~ para eliminar el objeto',
+ ['map_blip'] = 'comisaría de policía',
+ ['unrestrained_timer'] = 'you feel your handcuffs slowly losing grip and fading away.',
+ -- Notifications
+ ['alert_police'] = 'alerta policia',
+ ['phone_police'] = 'policia',
+}
diff --git a/_resources/esx_policejob/locales/fi.lua b/_resources/esx_policejob/locales/fi.lua
new file mode 100644
index 00000000..abf04045
--- /dev/null
+++ b/_resources/esx_policejob/locales/fi.lua
@@ -0,0 +1,151 @@
+Locales['fi'] = {
+ -- Cloakroom
+ ['cloakroom'] = 'vaatelokero',
+ ['citizen_wear'] = 'siviiliasu',
+ ['police_wear'] = 'poliisiasu',
+ ['gilet_wear'] = 'huomioliivi',
+ ['bullet_wear'] = 'luotiliivi',
+ ['no_outfit'] = 'täällä ei ole sinulle sopivaa asua',
+ ['open_cloackroom'] = 'paina ~INPUT_CONTEXT~ vaihtaaksesi ~y~vaatteita~s~.',
+ -- Armory
+ ['remove_object'] = 'ota esine',
+ ['deposit_object'] = 'talleta esine',
+ ['get_weapon'] = 'ota ase',
+ ['put_weapon'] = 'laita ase pois',
+ ['buy_weapons'] = 'osta aseita',
+ ['armory'] = 'asevarasto',
+ ['open_armory'] = 'paina ~INPUT_CONTEXT~ avataksesi asevarasto',
+ ['armory_owned'] = 'owned',
+ ['armory_free'] = 'free',
+ ['armory_item'] = '$%s',
+ ['armory_weapontitle'] = 'armory - Buy weapon',
+ ['armory_componenttitle'] = 'armory - Weapon attatchments',
+ ['armory_bought'] = 'you bought an ~y~%s~s~ for ~g~$%s~s~',
+ ['armory_money'] = 'you cannot afford that weapon',
+ ['armory_hascomponent'] = 'you have that attatchment equiped!',
+ ['get_weapon_menu'] = 'armory - Withdraw Weapon',
+ ['put_weapon_menu'] = 'armory - Store Weapon',
+ -- Vehicles
+ ['vehicle_menu'] = 'vehicle',
+ ['vehicle_blocked'] = 'all available spawn points are currently blocked!',
+ ['garage_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Vehicle Actions~s~.',
+ ['garage_title'] = 'vehicle Actions',
+ ['garage_stored'] = 'stored',
+ ['garage_notstored'] = 'not in garage',
+ ['garage_storing'] = 'we\'re attempting to remove the vehicle, make sure no players are around it.',
+ ['garage_has_stored'] = 'the vehicle has been stored in your garage',
+ ['garage_has_notstored'] = 'no nearby owned vehicles were found',
+ ['garage_notavailable'] = 'your vehicle is not stored in the garage.',
+ ['garage_blocked'] = 'there\'s no available spawn points!',
+ ['garage_empty'] = 'you dont have any vehicles in your garage.',
+ ['garage_released'] = 'your vehicle has been released from the garage.',
+ ['garage_store_nearby'] = 'there is no nearby vehicles.',
+ ['garage_storeditem'] = 'open garage',
+ ['garage_storeitem'] = 'store vehicle in garage',
+ ['garage_buyitem'] = 'vehicle shop',
+ ['garage_notauthorized'] = 'you\'re not authorized to buy this kind of vehicles.',
+ ['helicopter_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Helicopter Actions~s~.',
+ ['shop_item'] = '$%s',
+ ['vehicleshop_title'] = 'vehicle Shop',
+ ['vehicleshop_confirm'] = 'do you want to buy this vehicle?',
+ ['vehicleshop_bought'] = 'you have bought ~y~%s~s~ for ~r~$%s~s~',
+ ['vehicleshop_money'] = 'you cannot afford that vehicle',
+ ['vehicleshop_awaiting_model'] = 'the vehicle is currently ~g~DOWNLOADING & LOADING~s~ please wait',
+ ['confirm_no'] = 'no',
+ ['confirm_yes'] = 'yes',
+ -- Service
+ ['service_max'] = 'you cannot enter service, max officers in service: %s/%s',
+ ['service_not'] = 'you have not entered service! You\'ll have to get changed first.',
+ ['service_anonunce'] = 'service information',
+ ['service_in'] = 'you\'ve entered service, welcome!',
+ ['service_in_announce'] = 'operator ~y~%s~s~ has entered service!',
+ ['service_out'] = 'you have left service.',
+ ['service_out_announce'] = 'operator ~y~%s~s~ has left their service.',
+ -- Action Menu
+ ['citizen_interaction'] = 'siviilin vuorovaikutus',
+ ['vehicle_interaction'] = 'ajoneuvon vuorovaikutus',
+ ['object_spawner'] = 'objekti spawneri',
+
+ ['id_card'] = 'henkilöllisyystodistus',
+ ['search'] = 'tutki',
+ ['handcuff'] = 'raudat On/Off',
+ ['drag'] = 'raahaa',
+ ['put_in_vehicle'] = 'laita ajoneuvoon',
+ ['out_the_vehicle'] = 'ota ulos ajoneuvosta',
+ ['fine'] = 'sakko',
+ ['unpaid_bills'] = 'hallinoi maksamattomia laskuja',
+ ['license_check'] = 'hallitse lisenssejä',
+ ['license_revoke'] = 'kumoa lisenssi',
+ ['license_revoked'] = 'sinun ~b~%s~s~ ~y~kumottiin~s~!',
+ ['licence_you_revoked'] = 'sinä kumosit ~b~%s~s~ mikä kuului henkilölle ~y~%s~s~',
+ ['no_players_nearby'] = 'ei pelaajia lähettyvillä',
+ ['being_searched'] = 'you are being ~y~searched~s~ by the ~b~Police~s~',
+ -- Vehicle interaction
+ ['vehicle_info'] = 'ajoneuvon tiedot',
+ ['pick_lock'] = 'tiirikoi ovet',
+ ['vehicle_unlocked'] = 'ajoneuvo ~g~Avattu~s~',
+ ['no_vehicles_nearby'] = 'ei ajoneuvoja lähettyvillä',
+ ['impound'] = 'takavarikoi ajoneuvo',
+ ['impound_prompt'] = 'paina ~INPUT_CONTEXT~ peruaksesi ~y~takavarikointi~s~',
+ ['impound_canceled'] = 'sinä peruit takavarikoinnin',
+ ['impound_canceled_moved'] = 'takavarikointi peruuntui koska ajoneuvo liikku',
+ ['impound_successful'] = 'takavarikoit ajoneuvon',
+ ['search_database'] = 'ajoneuvon tiedot',
+ ['search_database_title'] = 'ajoneuvon tiedot - etsi rekisterinumerolla',
+ ['search_database_error_invalid'] = 'tämä ~r~ei ole~s~ ~y~voimassa oleva~s~ rekisterinumero',
+ -- Traffic interaction
+ ['traffic_interaction'] = 'liikenteen vuorovaikutus',
+ ['cone'] = 'kartio',
+ ['barrier'] = 'este',
+ ['spikestrips'] = 'piikkimatto',
+ ['box'] = 'laatikko',
+ ['cash'] = 'rahalaatikko',
+ -- ID Card Menu
+ ['name'] = 'nimi: %s',
+ ['job'] = 'työ: %s',
+ ['sex'] = 'sukupuoli: %s',
+ ['dob'] = 'syntymäaika: %s',
+ ['height'] = 'pituus: %s',
+ ['bac'] = 'alkometri: %s',
+ ['unknown'] = 'tuntematon',
+ ['male'] = 'mies',
+ ['female'] = 'nainen',
+ -- Body Search Menu
+ ['guns_label'] = '--- Aseet ---',
+ ['inventory_label'] = '--- Reppu ---',
+ ['license_label'] = ' --- Lisenssit ---',
+ ['confiscate'] = 'takavarikoi %s',
+ ['confiscate_weapon'] = 'confiscate %s with %s bullets',
+ ['confiscate_inv'] = 'takavarikoi %sx %s',
+ ['confiscate_dirty'] = 'takavarikoi likainen raha: $%s',
+ ['you_confiscated'] = 'sinä takavarioit ~y~%sx~s~ ~b~%s~s~ pelaajalta ~b~%s~s~',
+ ['got_confiscated'] = '~y~%sx~s~ ~b~%s~s~ takavarikoitiin sinulta pelaajan ~y~%s~s~ toimesta',
+ ['you_confiscated_account'] = 'sinä takavarikoit ~g~$%s~s~ (%s) pelaajalta ~b~%s~s~',
+ ['got_confiscated_account'] = '~g~$%s~s~ (%s) takavarikoitiin sinulta pelaajan ~y~%s~s~ toimesta',
+ ['you_confiscated_weapon'] = 'sinä takavarikoit ~b~%s~s~ pelaajalta ~b~%s~s~ jossa oli ~o~%s~s~ panosta',
+ ['got_confiscated_weapon'] = 'sinun ~b~%s~s~ jossa oli ~o~%s~s~ panosta takavarikoitiin sinulta~y~%s~s~',
+ ['traffic_offense'] = 'liikenne rikokset',
+ ['minor_offense'] = 'lievät rikokset',
+ ['average_offense'] = 'keskisuuret rikokset',
+ ['major_offense'] = 'vakavat rikokset',
+ ['fine_total'] = 'sakko: %s',
+ --Vehicle Info Menu
+ ['plate'] = 'kilpi: %s',
+ ['owner_unknown'] = 'omistaja: Tuntematon',
+ ['owner'] = 'omistaja: %s',
+ --Boss Menu
+ ['open_bossmenu'] = 'paina ~INPUT_CONTEXT~ avataksesi valikon',
+ ['quantity_invalid'] = 'invalid quantity',
+ ['have_withdrawn'] = 'sinä otit varastosta ~y~%sx~s~ ~b~%s~s~',
+ ['have_deposited'] = 'sinä talletit varastoon ~y~%sx~s~ ~b~%s~s~',
+ ['quantity'] = 'määrä',
+ ['inventory'] = 'varasto',
+ ['police_stock'] = 'poliisin Varasto',
+ -- Misc
+ ['remove_prop'] = 'paina ~INPUT_CONTEXT~ poistaaksesi objektin',
+ ['map_blip'] = 'poliisilaitos',
+ ['unrestrained_timer'] = 'tunnet kuinka hitaasti käsiraudat alkavat löystyä ja irtoavat',
+ -- Notifications
+ ['alert_police'] = 'hälyytys Poliisi',
+ ['phone_police'] = 'poliisi',
+}
\ No newline at end of file
diff --git a/_resources/esx_policejob/locales/fr.lua b/_resources/esx_policejob/locales/fr.lua
new file mode 100644
index 00000000..df9583c2
--- /dev/null
+++ b/_resources/esx_policejob/locales/fr.lua
@@ -0,0 +1,151 @@
+Locales['fr'] = {
+ -- Cloakroom
+ ['cloakroom'] = 'vestiaire',
+ ['citizen_wear'] = 'tenue Civil',
+ ['police_wear'] = 'tenue Policier',
+ ['gilet_wear'] = 'gilet orange',
+ ['bullet_wear'] = 'gilet pare-balles',
+ ['no_outfit'] = 'il n\'y a pas d\'uniforme à votre taille...',
+ ['open_cloackroom'] = 'appuyez sur ~INPUT_CONTEXT~ pour vous changer',
+ -- Armory
+ ['remove_object'] = 'prendre Objet',
+ ['deposit_object'] = 'déposer objet',
+ ['get_weapon'] = 'prendre Arme',
+ ['put_weapon'] = 'déposer Arme',
+ ['buy_weapons'] = 'acheter Armes',
+ ['armory'] = 'armurerie',
+ ['open_armory'] = 'appuyez sur ~INPUT_CONTEXT~ pour accéder à l\'armurerie',
+ ['armory_owned'] = 'possédé',
+ ['armory_free'] = 'gratuit',
+ ['armory_item'] = '$%s',
+ ['armory_weapontitle'] = 'armurerie - Acheter une arme',
+ ['armory_componenttitle'] = 'armurerie - Accessoires d\'armes',
+ ['armory_bought'] = 'vous achetez un ~y~%s~s~ pour ~g~$%s~s~',
+ ['armory_money'] = 'vous ne pouvez pas acheter cette arme',
+ ['armory_hascomponent'] = 'vous avez cet accessoire équipé!',
+ ['get_weapon_menu'] = 'armurerie - Retirer arme',
+ ['put_weapon_menu'] = 'armurerie - Stocker arme',
+ -- Vehicles
+ ['vehicle_menu'] = 'véhicule',
+ ['vehicle_blocked'] = 'tous les points de spawn sont bloqués!',
+ ['garage_prompt'] = 'appuyez sur ~INPUT_CONTEXT~ pour accéder aux ~y~Actions Véhicule~s~.',
+ ['garage_title'] = 'actions Véhicules',
+ ['garage_stored'] = 'rangé',
+ ['garage_notstored'] = 'sorti(e)',
+ ['garage_storing'] = 'tentative de suppression du véhicule, assurez-vous que personne ne soit autour.',
+ ['garage_has_stored'] = 'le véhicule a bien été rangé dans le garage',
+ ['garage_has_notstored'] = 'aucun véhicule dans le garage',
+ ['garage_notavailable'] = 'votre véhicule n\'est pas rangé dans le garage.',
+ ['garage_blocked'] = 'la sortie du garage est obstruée!',
+ ['garage_empty'] = 'vous n\'avez aucun véhicule dans le garage.',
+ ['garage_released'] = 'votre véhicule a été sorti.',
+ ['garage_store_nearby'] = 'aucun véhicule a proximité.',
+ ['garage_storeditem'] = 'ouvrir le garage',
+ ['garage_storeitem'] = 'ranger le véhicule',
+ ['garage_buyitem'] = 'magasin véhicule',
+ ['garage_notauthorized'] = 'vous n\'êtes pas autorisé à acheter ce type de véhicules.',
+ ['helicopter_prompt'] = 'appuyez sur ~INPUT_CONTEXT~ pour accéder aux ~y~Actions de l\'hélicoptère~s~.',
+ ['shop_item'] = '$%s',
+ ['vehicleshop_title'] = 'magasin véhicule',
+ ['vehicleshop_confirm'] = 'voulez-vous acheter ce véhicule?',
+ ['vehicleshop_bought'] = 'vous avez acheté ~y~%s~s~ pour ~r~$%s~s~',
+ ['vehicleshop_money'] = 'vous ne pouvez pas acheter ce véhicule',
+ ['vehicleshop_awaiting_model'] = 'le véhicule est actuellement en ~g~PRÉPARATION~s~ veuillez patienter',
+ ['confirm_no'] = 'non',
+ ['confirm_yes'] = 'oui',
+ -- Service
+ ['service_max'] = 'vous ne pouvez pas entrer en service, officiers en service: %s/%s',
+ ['service_not'] = 'vous n\'êtes pas en service! Vous devez d\'abord enfiler votre tenue.',
+ ['service_anonunce'] = 'prise de service',
+ ['service_in'] = 'vous êtes en service, bon courage!',
+ ['service_in_announce'] = 'l\'officier ~y~%s~s~ est entré en service!',
+ ['service_out'] = 'vous avez terminé votre service.',
+ ['service_out_announce'] = 'l\'officier ~y~%s~s~ a quitté son service.',
+ -- Action Menu
+ ['citizen_interaction'] = 'interaction citoyen',
+ ['vehicle_interaction'] = 'interaction véhicule',
+ ['object_spawner'] = 'placer objets',
+
+ ['id_card'] = 'carte d\'identité',
+ ['search'] = 'fouiller',
+ ['handcuff'] = 'menotter / Démenotter',
+ ['drag'] = 'escorter',
+ ['put_in_vehicle'] = 'mettre dans véhicule',
+ ['out_the_vehicle'] = 'sortir du véhicule',
+ ['fine'] = 'Amende',
+ ['unpaid_bills'] = 'gérer les amendes impayées',
+ ['license_check'] = 'gérer les licences',
+ ['license_revoke'] = 'révoquer la licence',
+ ['license_revoked'] = 'votre ~b~%s~s~ a été ~y~révoqué~s~!',
+ ['licence_you_revoked'] = 'vous avez révoqué un ~b~%s~s~ qui appartenait à ~y~%s~s~',
+ ['no_players_nearby'] = 'aucun joueur à proximité',
+ ['being_searched'] = 'vous êtes ~y~recherché(e)~s~ par la ~b~Police~s~',
+ -- Vehicle interaction
+ ['vehicle_info'] = 'infos véhicule',
+ ['pick_lock'] = 'crocheter véhicule',
+ ['vehicle_unlocked'] = 'véhicule ~g~déverouillé~s~',
+ ['no_vehicles_nearby'] = 'aucun véhicule à proximité',
+ ['impound'] = 'véhicule en fourrière',
+ ['impound_prompt'] = 'appuyez sur ~INPUT_CONTEXT~ pour annuler la ~y~saisie du véhicule~s~',
+ ['impound_canceled'] = 'vous avez annulé la saisie',
+ ['impound_canceled_moved'] = 'la saisie a été annulée parce que le véhicule a déménagé',
+ ['impound_successful'] = 'vous avez saisi le véhicule',
+ ['search_database'] = 'vehicle information',
+ ['search_database_title'] = 'informations sur le véhicule - recherche avec numéro d\'enregistrement',
+ ['search_database_error_invalid'] = 'Ce n\'est ~r~pas~s~ un ~y~numéro d\'enregistrement valide~s~',
+ -- Traffic interaction
+ ['traffic_interaction'] = 'interaction routière',
+ ['cone'] = 'plot',
+ ['barrier'] = 'barrière',
+ ['spikestrips'] = 'herse',
+ ['box'] = 'caisse',
+ ['cash'] = 'caisse',
+ -- ID Card Menu
+ ['name'] = 'nom: %s',
+ ['job'] = 'métier: %s',
+ ['sex'] = 'sexe: %s',
+ ['dob'] = 'DDN: %s',
+ ['height'] = 'taille: %s',
+ ['bac'] = 'BAC: %s',
+ ['unknown'] = 'inconnu',
+ ['male'] = 'homme',
+ ['female'] = 'femme',
+ -- Body Search Menu
+ ['guns_label'] = '--- Armes ---',
+ ['inventory_label'] = '--- Inventaire ---',
+ ['license_label'] = ' --- Licenses ---',
+ ['confiscate'] = 'confisquer %s',
+ ['confiscate_weapon'] = 'confisqué %s avec %s balles',
+ ['confiscate_inv'] = 'confisquer %sx %s',
+ ['confiscate_dirty'] = 'confisquer argent sale: €%s',
+ ['you_confiscated'] = 'vous avez confisqué ~y~%sx~s~ ~b~%s~s~ à ~b~%s~s~',
+ ['got_confiscated'] = '~y~%sx~s~ ~b~%s~s~ ont été confisqués par ~y~%s~s~',
+ ['you_confiscated_account'] = 'vous avez confisqué ~g~$%s~s~ (%s) à ~b~%s~s~',
+ ['got_confiscated_account'] = '~g~$%s~s~ (%s) ont été confisqués par ~y~%s~s~',
+ ['you_confiscated_weapon'] = 'vous avez confisqué ~b~%s~s~ à ~b~%s~s~ avec ~o~%s~s~ balles',
+ ['got_confiscated_weapon'] = 'votre ~b~%s~s~ avec ~o~%s~s~ balles a été confisqué par ~y~%s~s~',
+ ['traffic_offense'] = 'code de la route',
+ ['minor_offense'] = 'délit mineur',
+ ['average_offense'] = 'délit moyen',
+ ['major_offense'] = 'délit grave',
+ ['fine_total'] = 'amende: %s',
+ -- Vehicle Info Menu
+ ['plate'] = 'n°: %s',
+ ['owner_unknown'] = 'propriétaire: Inconnu',
+ ['owner'] = 'propriétaire: %s',
+ -- Boss Menu
+ ['open_bossmenu'] = 'appuyez sur ~INPUT_CONTEXT~ pour ouvrir le menu',
+ ['quantity_invalid'] = 'quantité invalide',
+ ['have_withdrawn'] = 'vous avez retiré ~y~%sx~s~ ~b~%s~s~',
+ ['have_deposited'] = 'vous avez déposé ~y~%sx~s~ ~b~%s~s~',
+ ['quantity'] = 'quantité',
+ ['inventory'] = 'inventaire',
+ ['police_stock'] = 'coffre de la police',
+ -- Misc
+ ['remove_prop'] = 'appuyez sur ~INPUT_CONTEXT~ pour enlever l\'objet',
+ ['map_blip'] = 'Commissariat',
+ ['unrestrained_timer'] = 'vous sentez que vos menottes deviennent fragiles.',
+ -- Notifications
+ ['alert_police'] = 'alerte police',
+ ['phone_police'] = 'police',
+}
diff --git a/_resources/esx_policejob/locales/ko.lua b/_resources/esx_policejob/locales/ko.lua
new file mode 100644
index 00000000..e85e9998
--- /dev/null
+++ b/_resources/esx_policejob/locales/ko.lua
@@ -0,0 +1,151 @@
+Locales['ko'] = {
+ -- Cloakroom
+ ['cloakroom'] = '라커룸',
+ ['citizen_wear'] = '민간인 복장',
+ ['police_wear'] = '경찰 복장',
+ ['gilet_wear'] = '오렌지 반사 재킷',
+ ['bullet_wear'] = '방탄 조끼',
+ ['no_outfit'] = '당신에게 맞는 유니폼이 없습니다!',
+ ['open_cloackroom'] = '~y~옷~s~을 변경하려면 ~INPUT_CONTEXT~를 누르십시오.',
+ -- Armory
+ ['remove_object'] = '오브젝트를 빼다',
+ ['deposit_object'] = '오브젝트를 두다',
+ ['get_weapon'] = '병기고에서 무기를 빼다',
+ ['put_weapon'] = '병기고에 무기를 넣다',
+ ['buy_weapons'] = '무기 구매',
+ ['armory'] = '병기고',
+ ['open_armory'] = '~INPUT_CONTEXT~를 눌러 ~y~병기고~s~에 접근하십시오.',
+ ['armory_owned'] = '소유',
+ ['armory_free'] = '자유',
+ ['armory_item'] = '$%s',
+ ['armory_weapontitle'] = '병기고 - 무기 구매',
+ ['armory_componenttitle'] = '병기고 - 무기 부착물',
+ ['armory_bought'] = '당신은 ~g~$%s~s~에 ~y~%s~s~를 구매했습니다',
+ ['armory_money'] = '당신은 이 무기를 살 수 없습니다',
+ ['armory_hascomponent'] = '이 부착물이 장착되어 있습니다!',
+ ['get_weapon_menu'] = '병기고 - 무기 빼다',
+ ['put_weapon_menu'] = '병기고 - 무기 넣다',
+ -- Vehicles
+ ['vehicle_menu'] = '차량',
+ ['vehicle_blocked'] = '모든 스폰 지점이 차단되었습니다!',
+ ['garage_prompt'] = '~INPUT_CONTEXT~를 눌러 ~y~차량 동작~s~에 액세스하십시오.',
+ ['garage_title'] = '차량 행동',
+ ['garage_stored'] = '저장됨',
+ ['garage_notstored'] = '차고가 아님',
+ ['garage_storing'] = '차량을 제거하려고 합니다. 주변에 아무도 없는지 확인하십시오.',
+ ['garage_has_stored'] = '차량이 차고에 보관되었습니다',
+ ['garage_has_notstored'] = '차고에 차량이 없습니다',
+ ['garage_notavailable'] = '차량이 차고에 저장되어 있지 않습니다',
+ ['garage_blocked'] = '차고 출구가 막혔습니다!',
+ ['garage_empty'] = '차고에 차량이 없습니다.',
+ ['garage_released'] = '차량이 출시되었습니다',
+ ['garage_store_nearby'] = '주변에 차량이 없습니다.',
+ ['garage_storeditem'] = '차고 열기',
+ ['garage_storeitem'] = '차량 정리',
+ ['garage_buyitem'] = '차량 상점',
+ ['garage_notauthorized'] = 'you\'re not authorized to buy this kind of vehicles.',
+ ['helicopter_prompt'] = '~y~헬리콥터 동작~s~에 액세스하려면 ~INPUT_CONTEXT~를 누릅니다.',
+ ['shop_item'] = '$%s',
+ ['vehicleshop_title'] = '차량 판매점',
+ ['vehicleshop_confirm'] = '이 차량을 사고 싶습니까?',
+ ['vehicleshop_bought'] = '당신은 ~r~$%s~s~에 ~y~%s~s~를 구매했습니다',
+ ['vehicleshop_money'] = '이 차량을 살 수 없습니다',
+ ['vehicleshop_awaiting_model'] = '차량이 현재 ~g~다운로드 및 로딩중입니다~s~. 잠시만 기다려주십시오',
+ ['confirm_no'] = '아니요',
+ ['confirm_yes'] = '예',
+ -- Service
+ ['service_max'] = '서비스에 진입 할 수 없습니다. 최대 임원 : %s/%s',
+ ['service_not'] = '당신은 서비스를 입력하지 않았습니다! 먼저 변경해야합니다.',
+ ['service_anonunce'] = '서비스 정보',
+ ['service_in'] = '당신은 서비스에 들어갔다, 환영합니다!',
+ ['service_in_announce'] = '~y~%s~s~가 서비스에 들어 왔습니다!',
+ ['service_out'] = '당신은 서비스를 떠났습니다.',
+ ['service_out_announce'] = '~y~%s~s~가 서비스를 떠났습니다.',
+ -- Action Menu
+ ['citizen_interaction'] = '시민 상호 작용',
+ ['vehicle_interaction'] = '차량 상호 작용',
+ ['object_spawner'] = '오브젝트 Spawner',
+
+ ['id_card'] = '신분증',
+ ['search'] = '수색',
+ ['handcuff'] = '수갑을 채우다 / 수갑을 풀어주다',
+ ['drag'] = '호위',
+ ['put_in_vehicle'] = '차량에 넣다',
+ ['out_the_vehicle'] = '차량을 끌다',
+ ['fine'] = '벌금',
+ ['unpaid_bills'] = '미지급 벌금 관리',
+ ['license_check'] = '라이선스 관리',
+ ['license_revoke'] = '라이선스 취소',
+ ['license_revoked'] = '~b~%s~s~는 ~y~취소~s~입니다!',
+ ['licence_you_revoked'] = '~y~%s~s~에 속하는 ~b~%s~s~를 취소했습니다.',
+ ['no_players_nearby'] = '근처에 플레이어가 없습니다!',
+ ['being_searched'] = '~b~경찰~s~이 당신을 ~y~수색~s~',
+ -- Vehicle interaction
+ ['vehicle_info'] = '차량 정보',
+ ['pick_lock'] = '차량 락픽',
+ ['vehicle_unlocked'] = '차량 ~g~잠금 해제~s~',
+ ['no_vehicles_nearby'] = '근처에 차량이 없습니다',
+ ['impound'] = '차량을 견인하다',
+ ['impound_prompt'] = '~y~견인~s~을 취소하려면 ~INPUT_CONTEXT~를 누릅니다',
+ ['impound_canceled'] = '당신은 견인을 취소했습니다',
+ ['impound_canceled_moved'] = '차량이 움직였기 때문에 견인이 취소되었습니다',
+ ['impound_successful'] = '당신은 차량을 견인했습니다',
+ ['search_database'] = '차량 정보',
+ ['search_database_title'] = '차량 정보 - 등록번호로 검색',
+ ['search_database_error_invalid'] = '~y~유효한~s~ 등록 번호가 ~r~아닙니다.~s~',
+ -- Traffic interaction
+ ['traffic_interaction'] = '교통 상호 작용',
+ ['cone'] = '원뿔',
+ ['barrier'] = '장벽',
+ ['spikestrips'] = '스파이크 스트립',
+ ['box'] = '상자',
+ ['cash'] = '현금 상자',
+ -- ID Card Menu
+ ['name'] = '이름: %s',
+ ['job'] = '직업: %s',
+ ['sex'] = '성별: %s',
+ ['dob'] = '생일: %s',
+ ['height'] = '키: %s',
+ ['bac'] = '혈중 알코올 농도: %s',
+ ['unknown'] = '알 수 없는',
+ ['male'] = '남자',
+ ['female'] = '여자',
+ -- Body Search Menu
+ ['guns_label'] = '--- 총 ---',
+ ['inventory_label'] = '--- 인벤토리 ---',
+ ['license_label'] = ' --- 라이선스 ---',
+ ['confiscate'] = '%s 을 압수',
+ ['confiscate_weapon'] = '%s 와 %s 총알을 압수',
+ ['confiscate_inv'] = '%sx %s 을 압수',
+ ['confiscate_dirty'] = '더러운 돈을 압수: $%s',
+ ['you_confiscated'] = '당신은 ~y~%sx~s~ ~b~%s~s~을 ~b~%s~s~에게서 압수했습니다',
+ ['got_confiscated'] = '~y~%sx~s~ ~b~%s~s~이(가) ~y~%s~s~에 압수되었습니다',
+ ['you_confiscated_account'] = '당신은 ~g~$%s~s~ (%s) 를 ~b~%s~s~ 에게서 압수했습니다.',
+ ['got_confiscated_account'] = '~g~$%s~s~ (%s) 이(가) ~y~%s~s~에 압수되었습니다',
+ ['you_confiscated_weapon'] = '당신은 ~b~%s~s~을 ~b~%s~s~에게서 압수하고 ~o~%s~s~ 총알도 압수했습니다.',
+ ['got_confiscated_weapon'] = '당신의 ~b~%s~s~와 ~o~%s~s~ 총알이 ~y~%s~s~에 의해 압수되었습니다.',
+ ['traffic_offense'] = '교통 위반',
+ ['minor_offense'] = '경범죄',
+ ['average_offense'] = '일반 범죄',
+ ['major_offense'] = '심각한 범죄',
+ ['fine_total'] = '벌금: %s',
+ -- Vehicle Info Menu
+ ['plate'] = '번호판: %s',
+ ['owner_unknown'] = '소유자: 알 수 없는',
+ ['owner'] = '소유자: %s',
+ -- Boss Menu
+ ['open_bossmenu'] = '~INPUT_CONTEXT~를 눌러 메뉴를 엽니다.',
+ ['quantity_invalid'] = '유효하지 않은 수량',
+ ['have_withdrawn'] = '당신은 ~y~%sx~s~ ~b~%s~s~ 뺐다 ',
+ ['have_deposited'] = '당신은 ~y~%sx~s~ ~b~%s~s~ 넣었다',
+ ['quantity'] = '수량',
+ ['inventory'] = '인벤토리',
+ ['police_stock'] = '경찰 자리',
+ -- Misc
+ ['remove_prop'] = '~INPUT_CONTEXT~를 눌러 오브젝트를 삭제하십시오.',
+ ['map_blip'] = '경찰서',
+ ['unrestrained_timer'] = '당신의 수갑이 천천히 풀리는 것을 느낍니다.',
+ -- Notifications
+ ['alert_police'] = '경찰 경보',
+ ['phone_police'] = '경찰',
+}
diff --git a/_resources/esx_policejob/locales/nl.lua b/_resources/esx_policejob/locales/nl.lua
new file mode 100644
index 00000000..26dab1aa
--- /dev/null
+++ b/_resources/esx_policejob/locales/nl.lua
@@ -0,0 +1,151 @@
+Locales['nl'] = {
+ -- Cloackroom
+ ['cloakroom'] = 'Kleedkamer',
+ ['citizen_wear'] = 'Burgerkleding',
+ ['police_wear'] = 'Politiekleding',
+ ['gilet_wear'] = 'Oranje reflecterend vest',
+ ['bullet_wear'] = 'Kogelwerend vest',
+ ['no_outfit'] = 'Er zijn geen passende uniformen voor jou!',
+ ['open_cloackroom'] = 'Druk op ~INPUT_CONTEXT~ om je ~y~kleding~s~ aan te passen.',
+ -- Wapenkamer
+ ['remove_object'] = 'Haal item uit kluis',
+ ['deposit_object'] = 'Leg item in kluis',
+ ['get_weapon'] = 'Haal wapen uit wapenkamer',
+ ['put_weapon'] = 'Leg wapen in wapenkamer',
+ ['buy_weapons'] = 'Koop wapens',
+ ['armory'] = 'Wapenkamer',
+ ['open_armory'] = 'Druk op ~INPUT_CONTEXT~ om de ~y~Wapenkamer~s~ te openen.',
+ ['armory_owned'] = 'In Bezit',
+ ['armory_free'] = 'Gratis',
+ ['armory_item'] = '€%s',
+ ['armory_weapontitle'] = 'Wapenkamer - Koop wapen',
+ ['armory_componenttitle'] = 'Wapenkamer - Weapon attachments',
+ ['armory_bought'] = 'Je hebt een ~y~%s~s~ gekocht voor ~g~€%s~s~.',
+ ['armory_money'] = 'Je kan dit wap niet betalen.',
+ ['armory_hascomponent'] = 'je hebt dit weapon attachment al!',
+ ['get_weapon_menu'] = 'Wapenkamer - Pak wapen',
+ ['put_weapon_menu'] = 'Wapenkamer - Leg wapen weg',
+ -- Vehicles
+ ['vehicle_menu'] = 'Voertuig',
+ ['vehicle_blocked'] = 'Alle spawnpunten zijn geblokkeerd!',
+ ['garage_prompt'] = 'Druk op ~INPUT_CONTEXT~ om de ~y~Garage~s~ te openen.',
+ ['garage_title'] = 'Garage',
+ ['garage_stored'] = 'Beschikbaar',
+ ['garage_notstored'] = 'Niet in garage',
+ ['garage_storing'] = 'We proberen je voertuig weg te halen, zorg dat er niemand langs staat.',
+ ['garage_has_stored'] = 'Het voertuig is opgeslagen in de garage.',
+ ['garage_has_notstored'] = 'Er zijn geen voertuigen in de buurt gevonden.',
+ ['garage_notavailable'] = 'Je voertuig is niet opgeslagen in de garage.',
+ ['garage_blocked'] = 'Er zijn geen beschikbare spawnpunten!',
+ ['garage_empty'] = 'Je hebt geen voertuigen in je garage.',
+ ['garage_released'] = 'Je voertuig is uit de garage gehaald.',
+ ['garage_store_nearby'] = 'Er zijn geen voertuigen in de buurt gevonden.',
+ ['garage_storeditem'] = 'Open garage',
+ ['garage_storeitem'] = 'Zet voertuig in garage',
+ ['garage_buyitem'] = 'Voertuigwinkel',
+ ['garage_notauthorized'] = 'Je bent niet bevoegd dit type voertuigen te halen.',
+ ['helicopter_prompt'] = 'Druk op ~INPUT_CONTEXT~ om de ~y~Helikopter Garage~s~ te openen.',
+ ['shop_item'] = '€%s',
+ ['vehicleshop_title'] = 'Voertuigwinkel',
+ ['vehicleshop_confirm'] = 'Wil je dit voertuig kopen?',
+ ['vehicleshop_bought'] = 'Je hebt een ~y~%s~s~ gekocht voor ~r~€%s~s~.',
+ ['vehicleshop_money'] = 'Je kan dit voertuig niet betalen.',
+ ['vehicleshop_awaiting_model'] = 'Dit voertuig is momenteel aan het ~g~DOWNLOADEN & LADEN~s~, even geduld asjeblieft',
+ ['confirm_no'] = 'Nee',
+ ['confirm_yes'] = 'Ja',
+ -- Service
+ ['service_max'] = 'Je kan niet in dienst gaan, maximale aantal agenten in dienst: %s/%s',
+ ['service_not'] = 'Je bent niet in dienst! Kleed je eerst om.',
+ ['service_anonunce'] = 'Dienst Informatie',
+ ['service_in'] = 'Je bent nu in dienst, welkom!',
+ ['service_in_announce'] = 'Agent ~y~%s~s~ is nu in dienst!',
+ ['service_out'] = 'Je bent nu uit dienst, fijne dag.',
+ ['service_out_announce'] = 'Agent ~y~%s~s~ is nu niet meer in dienst.',
+ -- Action Menu
+ ['citizen_interaction'] = 'Burger Interacties',
+ ['vehicle_interaction'] = 'Voertuig Interacties',
+ ['object_spawner'] = 'Object Interacties',
+
+ ['id_card'] = 'Identiteitsbewijs',
+ ['search'] = 'Fouilleren',
+ ['handcuff'] = 'Boeien / Ontboeien',
+ ['drag'] = 'Meenemen',
+ ['put_in_vehicle'] = 'Zet in voertuig',
+ ['out_the_vehicle'] = 'Haal uit voertuig',
+ ['fine'] = 'Boete opleggen',
+ ['unpaid_bills'] = 'Openstaande boetes bekijken',
+ ['license_check'] = 'Rijbewijzen beheren',
+ ['license_revoke'] = 'Rijbewijs invorderen',
+ ['license_revoked'] = 'Je ~b~%s~s~ is ~y~ingevorderd~s~!',
+ ['licence_you_revoked'] = 'Je hebt een ~b~%s~s~ van ~y~%s~s~ ingevorderd.',
+ ['no_players_nearby'] = 'Geen spelers in de buurt!',
+ ['being_searched'] = 'Je wordt ~y~gefouilleerd~s~ door de ~b~Politie~s~',
+ -- Voertuig Interactie
+ ['vehicle_info'] = 'Voertuig Informatie',
+ ['pick_lock'] = 'Breek voertuig open',
+ ['vehicle_unlocked'] = 'Voertuig ~g~ontgrendeld~s~.',
+ ['no_vehicles_nearby'] = 'Er zijn geen voertuigen in de buurt gevonden.',
+ ['impound'] = 'Neem voertuig in beslag',
+ ['impound_prompt'] = 'Druk op ~INPUT_CONTEXT~ om de ~y~inbeslagname~s~ te annuleren.',
+ ['impound_canceled'] = 'Je hebt de inbeslagname geannuleerd.',
+ ['impound_canceled_moved'] = 'De inbeslagname is geannuleerd omdat het voertuig is bewogen.',
+ ['impound_successful'] = 'Het voertuig is in beslag genomen.',
+ ['search_database'] = 'Kenteken natrekken',
+ ['search_database_title'] = 'Voertuig informatie - zoek op kenteken',
+ ['search_database_error_invalid'] = 'Het ingevoerde kenteken is ~r~ongeldig~s~.',
+ -- Objecten
+ ['traffic_interaction'] = 'Verkeers Interacties',
+ ['cone'] = 'Pion',
+ ['barrier'] = 'Barriere',
+ ['box'] = 'Box',
+ ['fence'] = 'PD Hek',
+ ['cash'] = 'Pallet met geld',
+ -- ID Menu
+ ['name'] = 'Naam: %s',
+ ['job'] = 'Werk: %s',
+ ['sex'] = 'Geslacht: %s',
+ ['dob'] = 'Geboortedatum: %s',
+ ['height'] = 'Lengte: %s',
+ ['bac'] = 'BAC: %s',
+ ['unknown'] = 'onbekend',
+ ['male'] = 'man',
+ ['female'] = 'vrouw',
+ -- Fouilleren
+ ['guns_label'] = '--- Wapens ---',
+ ['inventory_label'] = '--- Inventaris ---',
+ ['license_label'] = ' --- Papieren ---',
+ ['confiscate'] = 'Neem %s in beslag',
+ ['confiscate_weapon'] = 'Neem een %s met %s kogels in beslag',
+ ['confiscate_inv'] = 'Neem %sx %s in beslag',
+ ['confiscate_dirty'] = 'Neem zwartgeld in beslag: €%s',
+ ['you_confiscated'] = 'Je hebt ~y~%sx~s~ ~b~%s~s~ van ~b~%s~s~ in beslag genomen.',
+ ['got_confiscated'] = '~y~%sx~s~ ~b~%s~s~ is in beslag genomen door ~y~%s~s~.',
+ ['you_confiscated_account'] = 'Je hebt ~g~€%s~s~ (%s) van ~b~%s~s~ in beslag genomen.',
+ ['got_confiscated_account'] = '~g~€%s~s~ (%s) is in beslag genomen door ~y~%s~s~.',
+ ['you_confiscated_weapon'] = 'Je hebt een ~b~%s~s~ van ~b~%s~s~ met ~o~%s~s~ kogels in beslag genomen.',
+ ['got_confiscated_weapon'] = 'Je ~b~%s~s~ met ~o~%s~s~ kogels is in beslag genomen door ~y~%s~s~.',
+ ['traffic_offense'] = 'Verkeersovertreding',
+ ['minor_offense'] = 'Kleine overtreding',
+ ['average_offense'] = 'Gemiddelde overtreding',
+ ['major_offense'] = 'Grote overtreding',
+ ['fine_total'] = 'Boete: %s',
+ -- Voertuig Informatie
+ ['plate'] = 'Kenteken: %s',
+ ['owner_unknown'] = 'Eigenaar: Onbekend',
+ ['owner'] = 'Eigenaar: %s',
+ -- Boss Menu
+ ['open_bossmenu'] = 'Druk op ~INPUT_CONTEXT~ om het menu te openen.',
+ ['quantity_invalid'] = 'Ongeldig aantal',
+ ['have_withdrawn'] = 'Je hebt ~y~%sx~s~ ~b~%s~s~ gepakt.',
+ ['have_deposited'] = 'Je hebt ~y~%sx~s~ ~b~%s~s~ weg gelegt.',
+ ['quantity'] = 'Aantal',
+ ['inventory'] = 'Inventaris',
+ ['police_stock'] = 'Politie Voorraad',
+ -- Misc
+ ['remove_prop'] = 'Druk op ~INPUT_CONTEXT~ om dit object te verwijderen.',
+ ['map_blip'] = 'Politiebureau',
+ ['unrestrained_timer'] = 'Je voelt je handboeien langzaam wegglijden.',
+ -- Notifications
+ ['alert_police'] = 'politie alert',
+ ['phone_police'] = 'politie',
+ }
diff --git a/_resources/esx_policejob/locales/pl.lua b/_resources/esx_policejob/locales/pl.lua
new file mode 100644
index 00000000..2f2a0479
--- /dev/null
+++ b/_resources/esx_policejob/locales/pl.lua
@@ -0,0 +1,151 @@
+Locales['pl'] = {
+ -- Cloakroom
+ ['cloakroom'] = 'szatnia',
+ ['citizen_wear'] = 'ubranie Cywilne',
+ ['police_wear'] = 'mundur',
+ ['gilet_wear'] = 'kamizelka odblaskowa',
+ ['bullet_wear'] = 'kamizelka kuloodporna',
+ ['no_outfit'] = 'brak ubrania',
+ ['open_cloackroom'] = 'naciśnij ~INPUT_CONTEXT~ aby zmienić ~y~ubranie~s~.',
+ -- Armory
+ ['remove_object'] = 'weź przedmiot',
+ ['deposit_object'] = 'zdeponuj przedmiot',
+ ['get_weapon'] = 'weź broń',
+ ['put_weapon'] = 'odłóż broń',
+ ['buy_weapons'] = 'kup Broń',
+ ['armory'] = 'zbrojownia',
+ ['open_armory'] = 'naciśnij ~INPUT_CONTEXT~ żeby uzyskać dostęp do zbrojowni',
+ ['armory_owned'] = 'owned',
+ ['armory_free'] = 'free',
+ ['armory_item'] = '$%s',
+ ['armory_weapontitle'] = 'armory - Buy weapon',
+ ['armory_componenttitle'] = 'armory - Weapon attatchments',
+ ['armory_bought'] = 'you bought an ~y~%s~s~ for ~g~$%s~s~',
+ ['armory_money'] = 'you cannot afford that weapon',
+ ['armory_hascomponent'] = 'you have that attatchment equiped!',
+ ['get_weapon_menu'] = 'armory - Withdraw Weapon',
+ ['put_weapon_menu'] = 'armory - Store Weapon',
+ -- Vehicles
+ ['vehicle_menu'] = 'vehicle',
+ ['vehicle_blocked'] = 'all available spawn points are currently blocked!',
+ ['garage_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Vehicle Actions~s~.',
+ ['garage_title'] = 'vehicle Actions',
+ ['garage_stored'] = 'stored',
+ ['garage_notstored'] = 'not in garage',
+ ['garage_storing'] = 'we\'re attempting to remove the vehicle, make sure no players are around it.',
+ ['garage_has_stored'] = 'the vehicle has been stored in your garage',
+ ['garage_has_notstored'] = 'no nearby owned vehicles were found',
+ ['garage_notavailable'] = 'your vehicle is not stored in the garage.',
+ ['garage_blocked'] = 'there\'s no available spawn points!',
+ ['garage_empty'] = 'you dont have any vehicles in your garage.',
+ ['garage_released'] = 'your vehicle has been released from the garage.',
+ ['garage_store_nearby'] = 'there is no nearby vehicles.',
+ ['garage_storeditem'] = 'open garage',
+ ['garage_storeitem'] = 'store vehicle in garage',
+ ['garage_buyitem'] = 'vehicle shop',
+ ['garage_notauthorized'] = 'you\'re not authorized to buy this kind of vehicles.',
+ ['helicopter_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Helicopter Actions~s~.',
+ ['shop_item'] = '$%s',
+ ['vehicleshop_title'] = 'vehicle Shop',
+ ['vehicleshop_confirm'] = 'do you want to buy this vehicle?',
+ ['vehicleshop_bought'] = 'you have bought ~y~%s~s~ for ~r~$%s~s~',
+ ['vehicleshop_money'] = 'you cannot afford that vehicle',
+ ['vehicleshop_awaiting_model'] = 'the vehicle is currently ~g~DOWNLOADING & LOADING~s~ please wait',
+ ['confirm_no'] = 'no',
+ ['confirm_yes'] = 'yes',
+ -- Service
+ ['service_max'] = 'nie możesz wejść do służby, maksymalna liczba oficerów w służbie: %s/%s',
+ ['service_not'] = 'nie rozpoczynasz służby! Najpierw musisz się przebrać.',
+ ['service_anonunce'] = 'informacje o służbie',
+ ['service_in'] = 'rozpoczynasz służbe, Witaj!',
+ ['service_in_announce'] = 'operator ~y~%s~s~ rozpoczyna służbę!',
+ ['service_out'] = 'opuszczasz służbę.',
+ ['service_out_announce'] = 'operator ~y~%s~s~ opuszcza służbe.',
+ -- Action Menu
+ ['citizen_interaction'] = 'interakcja z cywilami',
+ ['vehicle_interaction'] = 'interakcja z pojazdami',
+ ['object_spawner'] = 'przedmioty do postawienia',
+
+ ['id_card'] = 'dowód osobisty',
+ ['search'] = 'przeszukaj',
+ ['handcuff'] = 'zakuj/Rozkuj Kajdanki ',
+ ['drag'] = 'przemieść podejrzanego',
+ ['put_in_vehicle'] = 'wsadź do pojazdu',
+ ['out_the_vehicle'] = 'wyciągnij z pojazdu',
+ ['fine'] = 'mandaty',
+ ['unpaid_bills'] = 'zarządzaj niezapłaconymi rachunkami',
+ ['license_check'] = 'zarządzaj licencjami',
+ ['license_revoke'] = 'unieważnij licencje',
+ ['license_revoked'] = 'twoja licencja ~b~%s~s~ została ~y~unieważniona~s~!',
+ ['licence_you_revoked'] = 'unieważniasz ~b~%s~s~ które należały do ~y~%s~s~',
+ ['no_players_nearby'] = 'brak graczy w pobliżu',
+ ['being_searched'] = 'you are being ~y~searched~s~ by the ~b~Police~s~',
+ -- Vehicle interaction
+ ['vehicle_info'] = 'informacje o pojeździe',
+ ['pick_lock'] = 'odblokuj pojazd',
+ ['vehicle_unlocked'] = 'pojazd ~g~Odblokowany~s~',
+ ['no_vehicles_nearby'] = 'brak pojazdu w pobliżu',
+ ['impound'] = 'zajmij pojazd',
+ ['impound_prompt'] = 'naciśnij ~INPUT_CONTEXT~ żeby unieważnić ~y~zajęcie~s~',
+ ['impound_canceled'] = 'unieważniasz zajęcie',
+ ['impound_canceled_moved'] = 'zajęcie zostało anulowane, ponieważ pojazd przemieścił się',
+ ['impound_successful'] = 'zajmujesz pojazd',
+ ['search_database'] = 'informacje o pojeździe',
+ ['search_database_title'] = 'informacjeo pojeździe - przeszukaj używając numeru rejestracyjnego',
+ ['search_database_error_invalid'] = 'to ~r~nie~s~ jest ~y~poprawny~s~ rnumer rejestracyjny',
+ -- Traffic interaction
+ ['traffic_interaction'] = 'interakcje dla ruchu drogowego',
+ ['cone'] = 'pachołek',
+ ['barrier'] = 'barierka',
+ ['spikestrips'] = 'kolczatka',
+ ['box'] = 'pudła',
+ ['cash'] = 'paleta z pieniędzmi',
+ -- ID Card Menu
+ ['name'] = 'name: %s',
+ ['job'] = 'praca: %s',
+ ['sex'] = 'płeć: %s',
+ ['dob'] = 'data urodzenia: %s',
+ ['height'] = 'wzrost: %s',
+ ['bac'] = 'BAC: %s',
+ ['unknown'] = 'nieznany',
+ ['male'] = 'mężczyzna',
+ ['female'] = 'kobieta',
+ -- Body Search Menu
+ ['guns_label'] = '--- Bronie ---',
+ ['inventory_label'] = '--- Ekwipunek ---',
+ ['license_label'] = ' --- Licenses ---',
+ ['confiscate'] = 'skonfiskuj %s',
+ ['confiscate_weapon'] = 'skonfiskuj %s z %s kulami',
+ ['confiscate_inv'] = 'skonfiskuj %s x %s',
+ ['confiscate_dirty'] = 'skonfiskuj brudne pieniądze: $%s',
+ ['you_confiscated'] = 'skonfiskowałeś ~y~%sx~s~ ~b~%s~s~ od ~b~%s~s~',
+ ['got_confiscated'] = '~y~%sx~s~ ~b~%s~s~ zostały skonfiskowane przez ~y~%s~s~',
+ ['you_confiscated_account'] = 'skonfiskowałeś ~g~%s$~s~ (%s) od ~b~%s~s~',
+ ['got_confiscated_account'] = '~g~%s$~s~ (%s) zostały skonfiskowane przez ~y~%s~s~',
+ ['you_confiscated_weapon'] = 'skonfiskowałeś ~b~%s~s~ od ~b~%s~s~ z ~o~%s~s~ pociskami',
+ ['got_confiscated_weapon'] = 'twój ~b~%s~s~ z ~o~%s~s~ kulami został skonfiskowany przez ~y~%s~s~',
+ ['traffic_offense'] = 'wykroczenia drogowe',
+ ['minor_offense'] = 'niewielkie wykroczenia',
+ ['average_offense'] = 'średnie wykroczenia',
+ ['major_offense'] = 'duże wykroczenia',
+ ['fine_total'] = 'mandat: %s',
+ -- Vehicle Info Menu
+ ['plate'] = 'tablica rejestracyjna: %s',
+ ['owner_unknown'] = 'właściciel: Nieznany',
+ ['owner'] = 'właściciel: %s',
+ -- Boss Menu
+ ['open_bossmenu'] = 'naciśnij ~INPUT_CONTEXT~ aby otworzyć menu',
+ ['quantity_invalid'] = 'nieprawidłowa ilość',
+ ['have_withdrawn'] = 'wyjmujesz z depozytu ~y~%sx~s~ ~b~%s~s~',
+ ['have_deposited'] = 'zdeponowano ~y~%sx~s~ ~b~%s~s~',
+ ['quantity'] = 'ilość',
+ ['inventory'] = 'ekwipunek',
+ ['police_stock'] = 'zapasy policji',
+ -- Misc
+ ['remove_prop'] = 'naciśnij ~INPUT_CONTEXT~ aby usunąć ten obiekt',
+ ['map_blip'] = 'komisariat Policji',
+ ['unrestrained_timer'] = 'czujesz, że twoje kajdanki powoli tracą przyczepność i znikają.',
+ -- Notifications
+ ['alert_police'] = 'ostrzeż policję',
+ ['phone_police'] = 'police',
+}
diff --git a/_resources/esx_policejob/locales/sv.lua b/_resources/esx_policejob/locales/sv.lua
new file mode 100644
index 00000000..ba2c2179
--- /dev/null
+++ b/_resources/esx_policejob/locales/sv.lua
@@ -0,0 +1,151 @@
+Locales['sv'] = {
+ -- Cloakroom
+ ['cloakroom'] = 'omklädningsrum',
+ ['citizen_wear'] = 'civila kläder',
+ ['police_wear'] = 'polisuniform',
+ ['gilet_wear'] = 'reflektiv väst',
+ ['bullet_wear'] = 'skottsäker väst',
+ ['no_outfit'] = 'det finns ingen uniform som passar dig!',
+ ['open_cloackroom'] = 'tryck ~INPUT_CONTEXT~ för att välja ~y~kläder~s~.',
+ -- Armory
+ ['remove_object'] = 'ta ut objekt',
+ ['deposit_object'] = 'lägg in objekt',
+ ['get_weapon'] = 'ta ut vapen',
+ ['put_weapon'] = 'lägg in vapen',
+ ['buy_weapons'] = 'köp vapen',
+ ['armory'] = 'vapenförråd',
+ ['open_armory'] = 'tryck ~INPUT_CONTEXT~ för att komma åt ~y~vapenförrådet~s~.',
+ ['armory_owned'] = 'ägd',
+ ['armory_free'] = 'gratis',
+ ['armory_item'] = '%s SEK',
+ ['armory_weapontitle'] = 'vapenförråd - Köp vapen',
+ ['armory_componenttitle'] = 'vapenförråd - Vapen tillbehör',
+ ['armory_bought'] = 'du köpte ~y~%s~s~ för ~g~%s SEK~s~',
+ ['armory_money'] = 'du har inte råd med det vapnet',
+ ['armory_hascomponent'] = 'du har redan det tillbehöret!',
+ ['get_weapon_menu'] = 'vapenförråd - Ta ut vapen',
+ ['put_weapon_menu'] = 'vapenförråd - Spara vapen',
+ -- Vehicles
+ ['vehicle_menu'] = 'fordon',
+ ['vehicle_blocked'] = 'det finns ingen tillgänglig plats att ställa ut fordonet på!',
+ ['garage_prompt'] = 'tryck ~INPUT_CONTEXT~ för att komma åt ~y~garaget~s~.',
+ ['garage_title'] = 'garage',
+ ['garage_stored'] = 'inställt',
+ ['garage_notstored'] = 'uttaget',
+ ['garage_storing'] = 'vi håller på att ställa in ditt fordon, se till att ingen är i närheten.',
+ ['garage_has_stored'] = 'fordonet har ställts in i garaget',
+ ['garage_has_notstored'] = 'inget ägt fordon finns i närheten',
+ ['garage_notavailable'] = 'ditt fordon är inte inställt i ditt garage.',
+ ['garage_blocked'] = 'det finns ingen tillgänglig plats att ställa ut fordonet på!',
+ ['garage_empty'] = 'du har inga fordon i ditt garage.',
+ ['garage_released'] = 'ditt fordon har tagits ut från garaget.',
+ ['garage_store_nearby'] = 'det finns inget fordon i närheten.',
+ ['garage_storeditem'] = 'öppna garage',
+ ['garage_storeitem'] = 'ställ in fordon',
+ ['garage_buyitem'] = 'fordonshandel',
+ ['garage_notauthorized'] = 'du har inte tillgång till att köpa dessa fordon.',
+ ['helicopter_prompt'] = 'tryck ~INPUT_CONTEXT~ för att komma åt ~y~helikoptergaraget~s~.',
+ ['shop_item'] = '%s SEK',
+ ['vehicleshop_title'] = 'fordonshandel',
+ ['vehicleshop_confirm'] = 'vill du köpa detta fordon?',
+ ['vehicleshop_bought'] = 'du köpte ~y~%s~s~ för ~g~%s SEK~s~',
+ ['vehicleshop_money'] = 'du har inte råd med detta fordon',
+ ['vehicleshop_awaiting_model'] = 'fordonet ~g~LADDAS NED OCH LADDAS IN~s~ var god vänta',
+ ['confirm_no'] = 'nej',
+ ['confirm_yes'] = 'ja',
+ -- Service
+ ['service_max'] = 'du kan inte gå tjänst, poliser i tjänst: %s/%s',
+ ['service_not'] = 'du är inte i tjänst! Byt om för att gå in i tjänst.',
+ ['service_anonunce'] = 'tjänsteinformation',
+ ['service_in'] = 'du deltog i tjänst, välkommen!',
+ ['service_in_announce'] = 'operatör ~y~%s~s~ har deltagit tjänst!',
+ ['service_out'] = 'du har lämnat tjänst.',
+ ['service_out_announce'] = 'operatör ~y~%s~s~ har lämnat deras tjänst.',
+ -- Action Menu
+ ['citizen_interaction'] = 'handlingar mot civila',
+ ['vehicle_interaction'] = 'handlingar på bilar',
+ ['object_spawner'] = 'ta fram ett objekt',
+
+ ['id_card'] = 'ID-Kort',
+ ['search'] = 'sök igenom',
+ ['handcuff'] = 'handbojor',
+ ['drag'] = 'dra',
+ ['put_in_vehicle'] = 'sätt in i fordon',
+ ['out_the_vehicle'] = 'dra ut ur fordon',
+ ['fine'] = 'Ge böter',
+ ['unpaid_bills'] = 'se obetalda räkningar',
+ ['license_check'] = 'se licenser',
+ ['license_revoke'] = 'återkalla licenser',
+ ['license_revoked'] = 'ditt ~b~%s~s~ har blivit ~y~återkallat~s~!',
+ ['licence_you_revoked'] = 'du återkallade ett ~b~%s~s~ som tillhörde ~y~%s~s~',
+ ['no_players_nearby'] = 'det finns ingen i närheten',
+ ['being_searched'] = 'du blir ~y~visiterad~s~ av ~b~Polisen~s~',
+ -- Vehicle interaction
+ ['vehicle_info'] = 'fordon',
+ ['pick_lock'] = 'bryt upp fordon',
+ ['vehicle_unlocked'] = 'fordonet har ~g~låsts upp~s~',
+ ['no_vehicles_nearby'] = 'inga fordon i närheten',
+ ['impound'] = 'bärga fordonet',
+ ['impound_prompt'] = 'tryck ~INPUT_CONTEXT~ för att avbryta ~y~bärgningen~s~',
+ ['impound_canceled'] = 'du avbröt bärgningen',
+ ['impound_canceled_moved'] = 'bärgningen avbröts på grund av att fordonet har rört sig',
+ ['impound_successful'] = 'du har bärgat fordonet',
+ ['search_database'] = 'fordonsuppgifter',
+ ['search_database_title'] = 'fordonsuppgifter - sök med registreringsnummer',
+ ['search_database_error_invalid'] = 'det är ~r~inte~s~ ett ~y~giltigt~s~ registreringsnummer',
+ -- Traffic interaction
+ ['traffic_interaction'] = 'trafiksåtgärder',
+ ['cone'] = 'kon',
+ ['barrier'] = 'barriär',
+ ['spikestrips'] = 'spikmatta',
+ ['box'] = 'låda',
+ ['cash'] = 'låda med pengar',
+ -- ID Card Menu
+ ['name'] = 'namn: %s',
+ ['job'] = 'jobb: %s',
+ ['sex'] = 'kön: %s',
+ ['dob'] = 'födelsedatum: %s',
+ ['height'] = 'längd: %s',
+ ['bac'] = 'alkohol i blodet: %s',
+ ['unknown'] = 'okänt',
+ ['male'] = 'man',
+ ['female'] = 'kvinna',
+ -- Body Search Menu
+ ['guns_label'] = '--- Vapen ---',
+ ['inventory_label'] = '--- Inventory ---',
+ ['license_label'] = ' --- Licenser ---',
+ ['confiscate'] = 'beslagta %s',
+ ['confiscate_weapon'] = 'beslagta %s med %s skott',
+ ['confiscate_inv'] = 'beslagta %sx %s',
+ ['confiscate_dirty'] = 'beslagta svarta pengar: %s SEK',
+ ['you_confiscated'] = 'du beslagtog ~y~%sx~s~ ~b~%s~s~ från ~b~%s~s~',
+ ['got_confiscated'] = '~y~%sx~s~ ~b~%s~s~ beslagtogs av ~y~%s~s~',
+ ['you_confiscated_account'] = 'du beslagtog ~g~%s SEK~s~ (%s) från ~b~%s~s~',
+ ['got_confiscated_account'] = '~g~%s SEK~s~ (%s) beslagtogs av ~y~%s~s~',
+ ['you_confiscated_weapon'] = 'du beslagtog ~b~%s~s~ från ~b~%s~s~ med ~o~%s~s~ skott',
+ ['got_confiscated_weapon'] = 'din ~b~%s~s~ med ~o~%s~s~ skott beslagtogs av ~y~%s~s~',
+ ['traffic_offense'] = 'brott mot trafikregler',
+ ['minor_offense'] = 'mindre lagbrott',
+ ['average_offense'] = 'medel lagbrott',
+ ['major_offense'] = 'grovt lagbrott',
+ ['fine_total'] = 'böter: %s',
+ -- Vehicle Info Menu
+ ['plate'] = 'reg nummer: %s',
+ ['owner_unknown'] = 'ägare: Okänt',
+ ['owner'] = 'ägare: %s',
+ -- Boss Menu
+ ['open_bossmenu'] = 'tryck ~INPUT_CONTEXT~ för att öppna menyn',
+ ['quantity_invalid'] = 'otillgängligt antal',
+ ['have_withdrawn'] = 'du har tagit ut ~y~x%s~s~ ~b~%s~s~',
+ ['have_deposited'] = 'du har lagrat ~y~x%s~s~ ~b~%s~s~',
+ ['quantity'] = 'antal',
+ ['inventory'] = 'förråd',
+ ['police_stock'] = 'polisförråd',
+ -- Misc
+ ['remove_prop'] = 'tryck ~INPUT_CONTEXT~ för att ta bort objektet',
+ ['map_blip'] = 'polisstation',
+ ['unrestrained_timer'] = 'dina handklovar har försvunnit',
+ -- Notifications
+ ['alert_police'] = 'meddela polisen',
+ ['phone_police'] = 'polisen',
+}
diff --git a/_resources/esx_policejob/locales/tr.lua b/_resources/esx_policejob/locales/tr.lua
new file mode 100644
index 00000000..21a0e1a6
--- /dev/null
+++ b/_resources/esx_policejob/locales/tr.lua
@@ -0,0 +1,151 @@
+Locales['tr'] = {
+ -- Cloakroom
+ ['cloakroom'] = 'kıyafet Odası',
+ ['citizen_wear'] = 'sivil kıyafet',
+ ['police_wear'] = 'polis kıyafeti',
+ ['gilet_wear'] = 'turuncu ceket',
+ ['bullet_wear'] = 'kurşun geçirmez yelek',
+ ['no_outfit'] = ' üniforma yok!',
+ ['open_cloackroom'] = '~y~Kıyafetinizi~s~ değiştirmek için ~INPUT_CONTEXT~ tuşuna basın. ',
+ -- Armory
+ ['remove_object'] = 'obje Al',
+ ['deposit_object'] = 'obje Koy',
+ ['get_weapon'] = 'cephanelikten silah al',
+ ['put_weapon'] = 'cephaneliğe silah koy',
+ ['buy_weapons'] = 'silah satın al',
+ ['armory'] = 'cephanelik',
+ ['open_armory'] = '~y~Cephaneliğe~s~ erişmek için ~INPUT_CONTEXT~ tuşuna basın.',
+ ['armory_owned'] = 'sahipsin',
+ ['armory_free'] = 'bedava',
+ ['armory_item'] = '%s TL',
+ ['armory_weapontitle'] = 'cephanelik - Silah al',
+ ['armory_componenttitle'] = 'cephanelik - Silah eklentileri',
+ ['armory_bought'] = ' %s Lira Karşılığında %s satın aldın',
+ ['armory_money'] = 'yeteri kadar paran yok.',
+ ['armory_hascomponent'] = 'bu eklentiye zaten sahipsin !',
+ ['get_weapon_menu'] = 'cephanelik - Silah al',
+ ['put_weapon_menu'] = 'cephanelik - Silah koy',
+ -- Vehicles
+ ['vehicle_menu'] = 'araç',
+ ['vehicle_blocked'] = 'tüm Spawn Noktaları Bloke Edilmiş!',
+ ['garage_prompt'] = '~y~Araç eylemlerine ulaşmak için ~s~ ~INPUT_CONTEXT~ tuşuna basınız.',
+ ['garage_title'] = 'araç eylemleri',
+ ['garage_stored'] = 'garajda',
+ ['garage_notstored'] = 'garajda değil',
+ ['garage_storing'] = 'arac garaja koyuluyor ama, etrafınızda oyuncu olmadığına emin olun .',
+ ['garage_has_stored'] = 'araç garajına koyuldu',
+ ['garage_has_notstored'] = 'yakında sana ait araç yok',
+ ['garage_notavailable'] = 'aracınız garajda değil.',
+ ['garage_blocked'] = 'müsait araç çıkarma noktası yok!',
+ ['garage_empty'] = 'garajında bir araç yok.',
+ ['garage_released'] = 'aracını garajdan çıkardın.',
+ ['garage_store_nearby'] = 'yakında araç yok.',
+ ['garage_storeditem'] = 'garajı Aç',
+ ['garage_storeitem'] = 'aracı garaja koy',
+ ['garage_buyitem'] = 'araç Galerisi',
+ ['garage_notauthorized'] = 'galeriye erişim iznin yok',
+ ['helicopter_prompt'] = '~y~Helikopter eylemlerine~s~ erişmek için ~INPUT_CONTEXT~ tuşuna basınız.',
+ ['shop_item'] = '%s TL',
+ ['vehicleshop_title'] = 'araç galerisi',
+ ['vehicleshop_confirm'] = 'bu aracı satın almak istiyor musun?',
+ ['vehicleshop_bought'] = '%s lira Karşılığında %s Satın aldın ',
+ ['vehicleshop_money'] = 'bu araca paran yetmiyor',
+ ['vehicleshop_awaiting_model'] = 'araç ~g~Yükleniyor~s~ lütfen bekleyiniz',
+ ['confirm_no'] = 'hayır',
+ ['confirm_yes'] = 'evet',
+ -- Service
+ ['service_max'] = 'hizmete Giremezsin,Hizmette yeterli polis var: %s/%s',
+ ['service_not'] = 'hizmete Giremedin! İlk Önce Kıyafetlerini Değiştirmelisin.',
+ ['service_anonunce'] = 'hizmet Bilgisi',
+ ['service_in'] = 'hizmete Giriş Yaptın, Hoşgeldin!',
+ ['service_in_announce'] = 'operatör %s servise giriş yaptı!',
+ ['service_out'] = 'hizmetten Çıktın.',
+ ['service_out_announce'] = 'operatör %s servisten çıkış yaptı.',
+ -- Action Menu
+ ['citizen_interaction'] = 'vatandaş Etkileşimi',
+ ['vehicle_interaction'] = 'araç Etkileşimi',
+ ['object_spawner'] = 'obje Yerleştirici',
+
+ ['id_card'] = 'kimlik Kartı',
+ ['search'] = 'ara',
+ ['handcuff'] = 'kelepçele / Kelepçeyi Çöz',
+ ['drag'] = 'taşı',
+ ['put_in_vehicle'] = 'araca Koy',
+ ['out_the_vehicle'] = 'araçtan Çıkar',
+ ['fine'] = 'ceza',
+ ['unpaid_bills'] = 'ödenmemiş Faturaları Kontrol Et',
+ ['license_check'] = 'lisansları Kontrol Et',
+ ['license_revoke'] = 'lisansa El Koy',
+ ['license_revoked'] = '~b~%s~s~ lisansın ~y~iptal edildi~s~!',
+ ['licence_you_revoked'] = '~b~%s~s~ adlı kullanıcıya ait ~y~%s~s~ adlı lisansına el koydun.',
+ ['no_players_nearby'] = 'yakında oyuncu yok!',
+ ['being_searched'] = 'üstün ~y~searched~s~ - ~b~Polis~s~ tarafından aranıyor',
+ -- Vehicle interaction
+ ['vehicle_info'] = 'araç Bilgisi',
+ ['pick_lock'] = 'aracın kilidini aç',
+ ['vehicle_unlocked'] = 'araç ~g~açıldı~s~',
+ ['no_vehicles_nearby'] = 'yakınlarda araç yok',
+ ['impound'] = 'araca el koy',
+ ['impound_prompt'] = 'el konulan aracı geri bırakmak için ~INPUT_CONTEXT~ tuşuna basın',
+ ['impound_canceled'] = 'el konulma kaldırıldı',
+ ['impound_canceled_moved'] = 'araç hareket ettiği için el koyma iptal edildi',
+ ['impound_successful'] = 'araca el koydun',
+ ['search_database'] = 'araç bilgileri',
+ ['search_database_title'] = 'araç bilgileri - araç kayıt numarasından ara',
+ ['search_database_error_invalid'] = 'bu doğru bir araç kayıt numarası değil',
+ -- Traffic interaction
+ ['traffic_interaction'] = 'traik işlemleri',
+ ['cone'] = 'koni',
+ ['barrier'] = 'bariyer',
+ ['spikestrips'] = 'emniyet şeridi',
+ ['box'] = 'kutu',
+ ['cash'] = 'para kurusu',
+ -- ID Card Menu
+ ['name'] = 'isim: %s',
+ ['job'] = 'meslek: %s',
+ ['sex'] = 'cinsiyet: %s',
+ ['dob'] = 'doğum Tarihi: %s',
+ ['height'] = 'boy: %s',
+ ['bac'] = 'BAC: %s',
+ ['unknown'] = 'bilinmiyor',
+ ['male'] = 'erkek',
+ ['female'] = 'kadın',
+ -- Body Search Menu
+ ['guns_label'] = '--- Silahlar ---',
+ ['inventory_label'] = '--- Envanter ---',
+ ['license_label'] = ' --- Lisanslar ---',
+ ['confiscate'] = 'el koy %s',
+ ['confiscate_weapon'] = 'el koyuldu %s ve %s mermi',
+ ['confiscate_inv'] = 'el koyuldu %sx %s',
+ ['confiscate_dirty'] = 'kara paraya el koyuldu: %s TL',
+ ['you_confiscated'] = '~b~%s~s~ adlı kişiden ~y~%sx~s~ ~b~%s~s~ aldın ',
+ ['got_confiscated'] = '~y~%s~s~ adlı kişi ~y~%sx~s~ ~b~%s~s~ eşyanı aldı',
+ ['you_confiscated_account'] = '~b~%s~s~ adlı oyuncunun ~g~%s TL~s~ (%s) kara parasına el konuldu',
+ ['got_confiscated_account'] = '~g~%s TL~s~ (%s) kara parana el konuldu ~y~%s~s~',
+ ['you_confiscated_weapon'] = '~b~%s~s~ adlı oyuncunun ~b~%s~s~ ve ~o~%s~s~ mermilerine el konuldu',
+ ['got_confiscated_weapon'] = '~b~%s~s~ ve ~o~%s~s~ mermilerine ~y~%s~s~ tarafından el konuldu',
+ ['traffic_offense'] = 'trafik cezaları',
+ ['minor_offense'] = 'küçük suç',
+ ['average_offense'] = 'ortalama suç',
+ ['major_offense'] = 'büyük suç',
+ ['fine_total'] = 'ceza: %s',
+ -- Vehicle Info Menu
+ ['plate'] = 'plaka: %s',
+ ['owner_unknown'] = 'sahibi: Bilinmiyor',
+ ['owner'] = 'sahibi: %s',
+ -- Boss Menu
+ ['open_bossmenu'] = 'menüyü açmak için ~INPUT_CONTEXT~ tuşuna basın',
+ ['quantity_invalid'] = 'miktar hatalı',
+ ['have_withdrawn'] = '~y~%sx~s~ ~b~%s~s~ çekildi',
+ ['have_deposited'] = '~y~%sx~s~ ~b~%s~s~ yatırıldı',
+ ['quantity'] = 'miktar',
+ ['inventory'] = 'envanter',
+ ['police_stock'] = 'polis Stoğu',
+ -- Misc
+ ['remove_prop'] = 'objeyi silmek için ~INPUT_CONTEXT~ tuşuna basın',
+ ['map_blip'] = 'polis Karakolu',
+ ['unrestrained_timer'] = 'ellerinin yavaşça çözüldüğünü hissediyorsun.',
+ -- Notifications
+ ['alert_police'] = 'polis Acil Durum',
+ ['phone_police'] = 'polis',
+ }
diff --git a/_resources/esx_policejob/localization/de_esx_policejob.sql b/_resources/esx_policejob/localization/de_esx_policejob.sql
new file mode 100644
index 00000000..0e7aabb4
--- /dev/null
+++ b/_resources/esx_policejob/localization/de_esx_policejob.sql
@@ -0,0 +1,88 @@
+USE `es_extended`;
+
+INSERT INTO `addon_account` (name, label, shared) VALUES
+ ('society_police','Polizei',1)
+;
+
+INSERT INTO `datastore` (name, label, shared) VALUES
+ ('society_police','Polizei',1)
+;
+
+INSERT INTO `addon_inventory` (name, label, shared) VALUES
+ ('society_police', 'Polizei', 1)
+;
+
+INSERT INTO `jobs` (name, label) VALUES
+ ('police', 'Polizei')
+;
+
+INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES
+ ('police',0,'recruit','Rekrut',20,'{}','{}'),
+ ('police',1,'officer','Officier',40,'{}','{}'),
+ ('police',2,'sergeant','Sergent',60,'{}','{}'),
+ ('police',3,'lieutenant','Lieutenant',85,'{}','{}'),
+ ('police',4,'boss','Commandant',100,'{}','{}')
+;
+
+CREATE TABLE `fine_types` (
+ `id` int NOT NULL AUTO_INCREMENT,
+ `label` varchar(255) DEFAULT NULL,
+ `amount` int DEFAULT NULL,
+ `category` int DEFAULT NULL,
+
+ PRIMARY KEY (`id`)
+);
+
+INSERT INTO `fine_types` VALUES ('1', 'Missbrauchen der Hupe', '30', '0');
+INSERT INTO `fine_types` VALUES ('2', 'Vorfahrtstraße missachtet', '40', '0');
+INSERT INTO `fine_types` VALUES ('3', 'Gegenverkehr', '250', '0');
+INSERT INTO `fine_types` VALUES ('4', 'Unbefugtes Wenden', '250', '0');
+INSERT INTO `fine_types` VALUES ('5', 'Off-Road fahren', '170', '0');
+INSERT INTO `fine_types` VALUES ('6', 'Sicherheitsrichtlinien missachtet', '30', '0');
+INSERT INTO `fine_types` VALUES ('7', 'Gefährliches halten', '150', '0');
+INSERT INTO `fine_types` VALUES ('8', 'Nicht erlaubtes parken', '70', '0');
+INSERT INTO `fine_types` VALUES ('9', 'Nicht respektieren des Rechtsfahrgebotes', '70', '0');
+INSERT INTO `fine_types` VALUES ('10', 'Nicht einhaltender Priorität eines Rettungsfahrzeuges', '90', '0');
+INSERT INTO `fine_types` VALUES ('11', 'Nicht angehalten nach Aufforderung', '105', '0');
+INSERT INTO `fine_types` VALUES ('12', 'Bei Rot über die Ampel', '130', '0');
+INSERT INTO `fine_types` VALUES ('13', 'gefährliches Überholmanöver', '100', '0');
+INSERT INTO `fine_types` VALUES ('14', 'Fahrzeug nicht Verkehrstauglich', '100', '0');
+INSERT INTO `fine_types` VALUES ('15', 'Fahren ohne Lizenz', '1500', '0');
+INSERT INTO `fine_types` VALUES ('16', 'Hit and Run', '800', '0');
+INSERT INTO `fine_types` VALUES ('17', 'zu schnell < 5 kmh', '90', '0');
+INSERT INTO `fine_types` VALUES ('18', 'zu schnell 5-15 kmh', '120', '0');
+INSERT INTO `fine_types` VALUES ('19', 'zu schnell 15-30 kmh', '180', '0');
+INSERT INTO `fine_types` VALUES ('20', 'zu schnell > 30 kmh', '300', '0');
+INSERT INTO `fine_types` VALUES ('21', 'Verkehrsbehinderung', '110', '1');
+INSERT INTO `fine_types` VALUES ('22', 'Nicht Benutzung öffentlicher Straßen', '90', '1');
+INSERT INTO `fine_types` VALUES ('23', 'Störung der öffentlichen Ordnung', '90', '1');
+INSERT INTO `fine_types` VALUES ('24', 'Polizeieinsatz behindern', '130', '1');
+INSERT INTO `fine_types` VALUES ('25', 'Beildigung an Zivilist', '75', '1');
+INSERT INTO `fine_types` VALUES ('26', 'Polizist geringschätzen', '110', '1');
+INSERT INTO `fine_types` VALUES ('27', 'verbale Bedrohung an Zivilist', '90', '1');
+INSERT INTO `fine_types` VALUES ('28', 'verbale Bedrohung an Polizist', '150', '1');
+INSERT INTO `fine_types` VALUES ('29', 'Illegale Demonstration', '250', '1');
+INSERT INTO `fine_types` VALUES ('30', 'versuchte Bestechung', '1500', '1');
+INSERT INTO `fine_types` VALUES ('31', 'Mit Messer in der Stadt bewaffnet', '120', '2');
+INSERT INTO `fine_types` VALUES ('32', 'Mit tötlicher Waffe bewaffnet', '300', '2');
+INSERT INTO `fine_types` VALUES ('33', 'Unbefugter Besitz einer Waffe (Standard-Lizenz)', '600', '2');
+INSERT INTO `fine_types` VALUES ('34', 'Illegale Waffe', '700', '2');
+INSERT INTO `fine_types` VALUES ('35', 'Einbruch/Aufbruch', '300', '2');
+INSERT INTO `fine_types` VALUES ('36', 'Autodiebstahl', '1800', '2');
+INSERT INTO `fine_types` VALUES ('37', 'Drogenverkauf', '1500', '2');
+INSERT INTO `fine_types` VALUES ('38', 'Drogen herstellen', '1500', '2');
+INSERT INTO `fine_types` VALUES ('39', 'Drogenbesitz', '650', '2');
+INSERT INTO `fine_types` VALUES ('40', 'Zivile Geisel genommen', '1500', '2');
+INSERT INTO `fine_types` VALUES ('41', 'Geiselnahme', '2000', '2');
+INSERT INTO `fine_types` VALUES ('42', 'Waghalsiges Lenken', '650', '2');
+INSERT INTO `fine_types` VALUES ('43', 'Ladenraub', '650', '2');
+INSERT INTO `fine_types` VALUES ('44', 'Bankraub', '1500', '2');
+INSERT INTO `fine_types` VALUES ('45', 'Schießen auf Zivilisten', '2000', '3');
+INSERT INTO `fine_types` VALUES ('46', 'Schießen auf Beamten', '2500', '3');
+INSERT INTO `fine_types` VALUES ('47', 'versuchterMord an Zivilisten', '3000', '3');
+INSERT INTO `fine_types` VALUES ('48', 'versuchter Mord an einem Beamten', '5000', '3');
+INSERT INTO `fine_types` VALUES ('49', 'Mord an Zivilisten', '10000', '3');
+INSERT INTO `fine_types` VALUES ('50', 'Mord an Beamten', '30000', '3');
+INSERT INTO `fine_types` VALUES ('51', 'versehentlicher Mord', '1800', '3');
+INSERT INTO `fine_types` VALUES ('52', 'Firmenbetrug', '2000', '2');
+;
diff --git a/_resources/esx_policejob/localization/en_esx_policejob.sql b/_resources/esx_policejob/localization/en_esx_policejob.sql
new file mode 100644
index 00000000..0eec900b
--- /dev/null
+++ b/_resources/esx_policejob/localization/en_esx_policejob.sql
@@ -0,0 +1,89 @@
+USE `es_extended`;
+
+INSERT INTO `addon_account` (name, label, shared) VALUES
+ ('society_police', 'Police', 1)
+;
+
+INSERT INTO `datastore` (name, label, shared) VALUES
+ ('society_police', 'Police', 1)
+;
+
+INSERT INTO `addon_inventory` (name, label, shared) VALUES
+ ('society_police', 'Police', 1)
+;
+
+INSERT INTO `jobs` (name, label) VALUES
+ ('police', 'Police')
+;
+
+INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES
+ ('police',0,'recruit','Recruit',20,'{}','{}'),
+ ('police',1,'officer','Officer',40,'{}','{}'),
+ ('police',2,'sergeant','Sergeant',60,'{}','{}'),
+ ('police',3,'lieutenant','Lieutenant',85,'{}','{}'),
+ ('police',4,'boss','Chief',100,'{}','{}')
+;
+
+CREATE TABLE `fine_types` (
+ `id` int NOT NULL AUTO_INCREMENT,
+ `label` varchar(255) DEFAULT NULL,
+ `amount` int DEFAULT NULL,
+ `category` int DEFAULT NULL,
+
+ PRIMARY KEY (`id`)
+);
+
+INSERT INTO `fine_types` (label, amount, category) VALUES
+ ('Misuse of a horn', 30, 0),
+ ('Illegally Crossing a continuous Line', 40, 0),
+ ('Driving on the wrong side of the road', 250, 0),
+ ('Illegal U-Turn', 250, 0),
+ ('Illegally Driving Off-road', 170, 0),
+ ('Refusing a Lawful Command', 30, 0),
+ ('Illegally Stopping a Vehicle', 150, 0),
+ ('Illegal Parking', 70, 0),
+ ('Failing to Yield to the right', 70, 0),
+ ('Failure to comply with Vehicle Information', 90, 0),
+ ('Failing to stop at a Stop Sign ', 105, 0),
+ ('Failing to stop at a Red Light', 130, 0),
+ ('Illegal Passing', 100, 0),
+ ('Driving an illegal Vehicle', 100, 0),
+ ('Driving without a License', 1500, 0),
+ ('Hit and Run', 800, 0),
+ ('Exceeding Speeds Over < 5 mph', 90, 0),
+ ('Exceeding Speeds Over 5-15 mph', 120, 0),
+ ('Exceeding Speeds Over 15-30 mph', 180, 0),
+ ('Exceeding Speeds Over > 30 mph', 300, 0),
+ ('Impeding traffic flow', 110, 1),
+ ('Public Intoxication', 90, 1),
+ ('Disorderly conduct', 90, 1),
+ ('Obstruction of Justice', 130, 1),
+ ('Insults towards Civilans', 75, 1),
+ ('Disrespecting of an LEO', 110, 1),
+ ('Verbal Threat towards a Civilan', 90, 1),
+ ('Verbal Threat towards an LEO', 150, 1),
+ ('Providing False Information', 250, 1),
+ ('Attempt of Corruption', 1500, 1),
+ ('Brandishing a weapon in city Limits', 120, 2),
+ ('Brandishing a Lethal Weapon in city Limits', 300, 2),
+ ('No Firearms License', 600, 2),
+ ('Possession of an Illegal Weapon', 700, 2),
+ ('Possession of Burglary Tools', 300, 2),
+ ('Grand Theft Auto', 1800, 2),
+ ('Intent to Sell/Distrube of an illegal Substance', 1500, 2),
+ ('Frabrication of an Illegal Substance', 1500, 2),
+ ('Possession of an Illegal Substance ', 650, 2),
+ ('Kidnapping of a Civilan', 1500, 2),
+ ('Kidnapping of an LEO', 2000, 2),
+ ('Robbery', 650, 2),
+ ('Armed Robbery of a Store', 650, 2),
+ ('Armed Robbery of a Bank', 1500, 2),
+ ('Assault on a Civilian', 2000, 3),
+ ('Assault of an LEO', 2500, 3),
+ ('Attempt of Murder of a Civilian', 3000, 3),
+ ('Attempt of Murder of an LEO', 5000, 3),
+ ('Murder of a Civilian', 10000, 3),
+ ('Murder of an LEO', 30000, 3),
+ ('Involuntary manslaughter', 1800, 3),
+ ('Fraud', 2000, 2);
+;
diff --git a/_resources/esx_policejob/localization/es_esx_policejob.sql b/_resources/esx_policejob/localization/es_esx_policejob.sql
new file mode 100644
index 00000000..0b6f45d1
--- /dev/null
+++ b/_resources/esx_policejob/localization/es_esx_policejob.sql
@@ -0,0 +1,89 @@
+USE `es_extended`;
+
+INSERT INTO `addon_account` (name, label, shared) VALUES
+ ('society_police', 'Policía', 1)
+;
+
+INSERT INTO `datastore` (name, label, shared) VALUES
+ ('society_police', 'Policía', 1)
+;
+
+INSERT INTO `addon_inventory` (name, label, shared) VALUES
+ ('society_police', 'Policía', 1)
+;
+
+INSERT INTO `jobs` (name, label) VALUES
+ ('police', 'Policía')
+;
+
+INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES
+ ('police',0,'recruit','Recluta',20,'{}','{}'),
+ ('police',1,'officer','Oficial',40,'{}','{}'),
+ ('police',2,'sergeant','Sargento',60,'{}','{}'),
+ ('police',3,'lieutenant','Teniente',85,'{}','{}'),
+ ('police',4,'boss','Jefe',100,'{}','{}')
+;
+
+CREATE TABLE `fine_types` (
+ `id` int NOT NULL AUTO_INCREMENT,
+ `label` varchar(255) DEFAULT NULL,
+ `amount` int DEFAULT NULL,
+ `category` int DEFAULT NULL,
+
+ PRIMARY KEY (`id`)
+);
+
+INSERT INTO `fine_types` (label, amount, category) VALUES
+ ('Mal uso del claxon', 30, 0),
+ ('Cruzar indebidamente la línea continua', 40, 0),
+ ('Conducir por el lado incorrecto de la carretera', 250, 0),
+ ('Giro indebido', 250, 0),
+ ('Conducir indebidamente fuera de la carretera', 170, 0),
+ ('No hacer caso a una orden de un agente', 30, 0),
+ ('Detener el vehículo de forma incorrecta', 150, 0),
+ ('Aparcar en un lugar no habilitado', 70, 0),
+ ('No ceder al girar a la derecha', 70, 0),
+ ('No cumplir con los datos de tu vehículo', 90, 0),
+ ('No pararse en una señal de STOP', 105, 0),
+ ('No pararse en un semáforo cuando está en rojo', 130, 0),
+ ('Cruzar indebidamente', 100, 0),
+ ('Conducir un coche no permitido', 100, 0),
+ ('Conducir sin carnet de conducción', 1500, 0),
+ ('Chocar y darse a la fuga', 800, 0),
+ ('Exceder la velocidad permitida en 5 km/h', 90, 0),
+ ('Exceder la velocidad permitida entre 5 y 15 km/h', 120, 0),
+ ('Exceder la velocidad permitida entre 15 y 30 km/h', 180, 0),
+ ('Exceder la velocidad permitida más de 30 km/h', 300, 0),
+ ('Generar atasco en una carretera', 110, 1),
+ ('Intoxicación pública', 90, 1),
+ ('Conducta alocada', 90, 1),
+ ('Obstrucción a la justicia', 130, 1),
+ ('Insultos hacia civiles', 75, 1),
+ ('Insultos hacia un agente', 110, 1),
+ ('Amenaza verbar a un civil', 90, 1),
+ ('Amenaza verbal a un agente', 150, 1),
+ ('Dar información falsa', 250, 1),
+ ('Intento de corrupción', 1500, 1),
+ ('Tendencia de armas en los limites de la ciudad', 120, 2),
+ ('Tendencia de armas letales en los limites de la ciudad', 300, 2),
+ ('No tener licencia de armas', 600, 2),
+ ('Posesión de un arma ilegal', 700, 2),
+ ('Posesión de herramientas para robos', 300, 2),
+ ('Desorden público', 1800, 2),
+ ('Intento de venta o distribución de sustancias ilegales', 1500, 2),
+ ('Fabricación de sustancias ilegales', 1500, 2),
+ ('Posesión de sustancias ilegales', 650, 2),
+ ('Secuestro de un civil', 1500, 2),
+ ('Secuestro de un agente', 2000, 2),
+ ('Robo', 650, 2),
+ ('Robo armado a una tienda', 650, 2),
+ ('Robo armado a un banco', 1500, 2),
+ ('Asalto a un civil', 2000, 3),
+ ('Asalto a un agente', 2500, 3),
+ ('Intento de asesinato a un civil', 3000, 3),
+ ('Intento de asesinato a un agente', 5000, 3),
+ ('Asesinato de un civil', 10000, 3),
+ ('Asesinato de un policia', 30000, 3),
+ ('Homicidio involuntario', 1800, 3),
+ ('Fraude', 2000, 2);
+;
diff --git a/_resources/esx_policejob/localization/fi_esx_policejob.sql b/_resources/esx_policejob/localization/fi_esx_policejob.sql
new file mode 100644
index 00000000..3dd9281e
--- /dev/null
+++ b/_resources/esx_policejob/localization/fi_esx_policejob.sql
@@ -0,0 +1,89 @@
+USE `es_extended`;
+
+INSERT INTO `addon_account` (name, label, shared) VALUES
+ ('society_police', 'Poliisi', 1)
+;
+
+INSERT INTO `datastore` (name, label, shared) VALUES
+ ('society_police', 'Poliisi', 1)
+;
+
+INSERT INTO `addon_inventory` (name, label, shared) VALUES
+ ('society_police', 'Poliisi', 1)
+;
+
+INSERT INTO `jobs` (name, label) VALUES
+ ('police', 'Poliisi')
+;
+
+INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES
+ ('police',0,'recruit','Tulokas',20,'{}','{}'),
+ ('police',1,'officer','Konstaapeli',40,'{}','{}'),
+ ('police',2,'sergeant','Ylikonstaapeli',60,'{}','{}'),
+ ('police',3,'lieutenant','Kersantti',85,'{}','{}'),
+ ('police',4,'boss','Komentaja',100,'{}','{}')
+;
+
+CREATE TABLE `fine_types` (
+ `id` int NOT NULL AUTO_INCREMENT,
+ `label` varchar(255) DEFAULT NULL,
+ `amount` int DEFAULT NULL,
+ `category` int DEFAULT NULL,
+
+ PRIMARY KEY (`id`)
+);
+
+INSERT INTO `fine_types` (label, amount, category) VALUES
+ ('Äänimerkin väärinkäyttö', 30, 0),
+ ('Laiton jatkuvan linjan ylitys', 40, 0),
+ ('Ajaminen tien väärällä puolella', 250, 0),
+ ('Laiton U-käännös', 250, 0),
+ ('Laiton maastossa ajaminen', 170, 0),
+ ('Virkavallan käskyn laiminlyönti', 30, 0),
+ ('Laiton pysähtyminen', 150, 0),
+ ('Laiton parkkeeraus', 70, 0),
+ ('Väistöolovelvollisuuden laiminlyönti', 70, 0),
+ ('Väärän ajoneuvontiedon antaminen', 90, 0),
+ ('Stop merkin laiminlyönti', 105, 0),
+ ('Punaisten valojen laiminlyönti', 130, 0),
+ ('Laiton ohitus', 100, 0),
+ ('Laittomalla ajoneuvolla ajaminen', 100, 0),
+ ('Ajokortitta ajo', 1500, 0),
+ ('Yliajo', 800, 0),
+ ('Ylinopeus < 5 kmh', 90, 0),
+ ('Ylinopeus 5-15 kmh', 120, 0),
+ ('Ylinopeus 15-30 kmh', 180, 0),
+ ('Ylinopeus > 30 kmh', 300, 0),
+ ('Liikenteen pysäytys tahallisesti', 110, 1),
+ ('Julkinen päihtyminen', 90, 1),
+ ('Sopimaton käytös', 90, 1),
+ ('Oikeusjärjestelmän estäminen', 130, 1),
+ ('Siviilin loukkaaminen', 75, 1),
+ ('Virkavallan halventaminen', 110, 1),
+ ('Sanallainen uhkaus siviiliä kohtaan', 90, 1),
+ ('Sanallinen uhkaus virkavaltaa kohtaan', 150, 1),
+ ('Virheellisen tiedon antaminen', 250, 1),
+ ('Korruptioyritys', 1500, 1),
+ ('Aseella heiluminen kaupungin sisällä', 120, 2),
+ ('Tappavalla aseella heiluminen kaupungin sisällä', 300, 2),
+ ('Ei aselupaa', 600, 2),
+ ('Laittoman aseen hallusapito', 700, 2),
+ ('Murtotyökalujen hallussapito', 300, 2),
+ ('Autovarkaus', 1800, 2),
+ ('Tarkoitus myydä/levittää laitonta ainetta', 1500, 2),
+ ('Laittoman aineen valmistus', 1500, 2),
+ ('Laittoman aineen hallusapito ', 650, 2),
+ ('Siviilin kidnappaus', 1500, 2),
+ ('Virkavallan kidnappaus', 2000, 2),
+ ('Ryöstö', 650, 2),
+ ('Aseellinen kaupparyöstö', 650, 2),
+ ('Aseellinen pankkiryöstö', 1500, 2),
+ ('Siviiliä kohtaan kohdistunut hyökkäys', 2000, 3),
+ ('Virkavaltaa kohtaan kohdistunut hyökkäys', 2500, 3),
+ ('Siviilin murhanyritys', 3000, 3),
+ ('Virkavallan murhanyirtys', 5000, 3),
+ ('Siviilin murha', 10000, 3),
+ ('Virkavallan murha', 30000, 3),
+ ('Väkivaltainan tappo', 1800, 3),
+ ('Petos', 2000, 2);
+;
diff --git a/_resources/esx_policejob/localization/ko_esx_policejob.sql b/_resources/esx_policejob/localization/ko_esx_policejob.sql
new file mode 100644
index 00000000..8b01a36b
--- /dev/null
+++ b/_resources/esx_policejob/localization/ko_esx_policejob.sql
@@ -0,0 +1,89 @@
+USE `es_extended`;
+
+INSERT INTO `addon_account` (name, label, shared) VALUES
+ ('society_police', '경찰', 1)
+;
+
+INSERT INTO `datastore` (name, label, shared) VALUES
+ ('society_police', '경찰', 1)
+;
+
+INSERT INTO `addon_inventory` (name, label, shared) VALUES
+ ('society_police', '경찰', 1)
+;
+
+INSERT INTO `jobs` (name, label) VALUES
+ ('police', '경찰')
+;
+
+INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES
+ ('police',0,'recruit','순경',20,'{}','{}'),
+ ('police',1,'officer','경장',40,'{}','{}'),
+ ('police',2,'sergeant','경사',60,'{}','{}'),
+ ('police',3,'lieutenant','경위',85,'{}','{}'),
+ ('police',4,'boss','경찰국장',100,'{}','{}')
+;
+
+CREATE TABLE `fine_types` (
+ `id` int NOT NULL AUTO_INCREMENT,
+ `label` varchar(255) DEFAULT NULL,
+ `amount` int DEFAULT NULL,
+ `category` int DEFAULT NULL,
+
+ PRIMARY KEY (`id`)
+);
+
+INSERT INTO `fine_types` (label, amount, category) VALUES
+ ('경적 남용', 30, 0),
+ ('연속으로 라인을 넘음', 40, 0),
+ ('역주행', 250, 0),
+ ('불법 U턴', 250, 0),
+ ('불법적인 오프로드 운전', 170, 0),
+ ('공무원 명령 미준수', 30, 0),
+ ('불법적으로 차량 정지', 150, 0),
+ ('불법 주차', 70, 0),
+ ('오른쪽으로 양보하지 않음', 70, 0),
+ ('등록되지 않은 차량', 90, 0),
+ ('정지선 지키지 않음', 105, 0),
+ ('빨간불에서 멈추지 않음', 130, 0),
+ ('위험한 추월', 100, 0),
+ ('불법 차량 운전', 100, 0),
+ ('무면허 운전', 1500, 0),
+ ('뺑소니', 800, 0),
+ ('5 km 이상 과속', 90, 0),
+ ('5-15 km 과속', 120, 0),
+ ('15-30 km 과속', 180, 0),
+ ('30 km 이상 과속', 300, 0),
+ ('교통방해', 110, 1),
+ ('공공질서 문제', 90, 1),
+ ('무질서한 행동', 90, 1),
+ ('공무집행 방해', 130, 1),
+ ('민간인에 대한 모욕', 75, 1),
+ ('공무원에 대한 모욕', 110, 1),
+ ('민간인에 대한 언어폭력', 90, 1),
+ ('공무원에 대한 언어폭력', 150, 1),
+ ('허위 정보 제공', 250, 1),
+ ('부패 시도', 1500, 1),
+ ('도시에서 무기 사용', 120, 2),
+ ('도시에서 위험한 무기 사용', 300, 2),
+ ('총기 면허 없음', 600, 2),
+ ('불법 무기 소지', 700, 2),
+ ('절도 도구 소지', 300, 2),
+ ('차량 절도', 1800, 2),
+ ('마약 판매/분배', 1500, 2),
+ ('마약 제조', 1500, 2),
+ ('마약 소지 ', 650, 2),
+ ('민간인 납치', 1500, 2),
+ ('공무원 납치', 2000, 2),
+ ('강도', 650, 2),
+ ('상점의 무장 강도', 650, 2),
+ ('은행의 무장 강도', 1500, 2),
+ ('민간인에 대한 폭행', 2000, 3),
+ ('공무원에 대한 폭행', 2500, 3),
+ ('민간인 살인 시도', 3000, 3),
+ ('공무원 살인 시도', 5000, 3),
+ ('민간인 살인', 10000, 3),
+ ('공무원 살인', 30000, 3),
+ ('우발적 살인', 1800, 3),
+ ('사기', 2000, 2);
+;
diff --git a/_resources/esx_policejob/localization/nl_esx_policejob.lua b/_resources/esx_policejob/localization/nl_esx_policejob.lua
new file mode 100644
index 00000000..7862f791
--- /dev/null
+++ b/_resources/esx_policejob/localization/nl_esx_policejob.lua
@@ -0,0 +1,64 @@
+USE `es_extended`;
+
+INSERT INTO `addon_account` (name, label, shared) VALUES
+ ('society_police', 'Politie', 1)
+;
+
+INSERT INTO `datastore` (name, label, shared) VALUES
+ ('society_police', 'Politie', 1)
+;
+
+INSERT INTO `addon_inventory` (name, label, shared) VALUES
+ ('society_police', 'Politie', 1)
+;
+
+INSERT INTO `jobs` (name, label) VALUES
+ ('police', 'Politie')
+;
+
+INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES
+ ('police',0,'aspirant','Aspirant',0,'{}','{}'),
+ ('police',1,'surveillant','Surveillant',0,'{}','{}'),
+ ('police',2,'agent','Agent',0,'{}','{}'),
+ ('police',3,'hoofdagent','Hoofdagent',0,'{}','{}'),
+ ('police',4,'brigadier','Brigadier',0,'{}','{}'),
+ ('police',5,'inspecteur','Inspecteur',0,'{}','{}'),
+ ('police',6,'hoofdinspecteur','Hoofdinspecteur',0,'{}','{}'),
+ ('police',7,'commissaris','Commissaris',0,'{}','{}'),
+ ('police',8,'hoofdcommissaris','Hoofdcommissaris',0,'{}','{}'),
+ ('police',9,'boss','Eerste Hoofdcommissaris',0,'{}','{}')
+;
+
+CREATE TABLE `fine_types` (
+ `id` int NOT NULL AUTO_INCREMENT,
+ `label` varchar(255) DEFAULT NULL,
+ `amount` int DEFAULT NULL,
+ `category` int DEFAULT NULL,
+
+ PRIMARY KEY (`id`)
+);
+
+INSERT INTO `fine_types` (label, amount, category) VALUES
+ ('Onnodig claxoneren', 90, 0),
+ ('Rijden over een doorgetrokken streep', 240, 0),
+ ('Tegen het verkeer in rijden', 140, 0),
+ ('Negeren keerverbod (u-turn)', 140, 0),
+ ('Niet opvolgen aanwijzing van bevoegd ambtenaar', 110, 0),
+ ('Fout parkeren', 95, 0),
+ ('Verkeerd voorsorteren', 240, 0),
+ ('Rijden met een WOK status ', 300, 0),
+ ('Door rood rijden', 240, 0),
+ ('Rijden zonder rijbewijs', 340, 0),
+ ('Snelheid overtreding < 10km', 112, 0),
+ ('Snelheid overtreding 10 - 20km', 202, 0),
+ ('Snelheid overtreding 20 - 50km', 670, 0),
+ ('Snelheid overtreding > 50km', 1000, 0),
+ ('Openbare dronkenschap', 415, 1),
+ ('Wanordelijk gedrag', 500, 1),
+ ('Hulpdiensten hinderen', 700, 1),
+ ('Belediging ambtenaar in functie', 200, 1),
+ ('Bedreiging', 980, 1),
+ ('Illegaal wapen bezit', 2300, 2),
+ ('Illegaal drugs bezit', 400, 2),
+ ('Drugshandel', 3000, 3)
+;
diff --git a/_resources/esx_policejob/localization/pl_esx_policejob.sql b/_resources/esx_policejob/localization/pl_esx_policejob.sql
new file mode 100644
index 00000000..6b915616
--- /dev/null
+++ b/_resources/esx_policejob/localization/pl_esx_policejob.sql
@@ -0,0 +1,89 @@
+USE `es_extended`;
+
+INSERT INTO `addon_account` (name, label, shared) VALUES
+ ('society_police', 'Police', 1)
+;
+
+INSERT INTO `datastore` (name, label, shared) VALUES
+ ('society_police', 'Police', 1)
+;
+
+INSERT INTO `addon_inventory` (name, label, shared) VALUES
+ ('society_police', 'Police', 1)
+;
+
+INSERT INTO `jobs` (name, label) VALUES
+ ('police', 'Police')
+;
+
+INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES
+ ('police',0,'recruit','Posterunkowy',20,'{}','{}'),
+ ('police',1,'officer','Sierżant',40,'{}','{}'),
+ ('police',2,'sergeant','Aspirant',60,'{}','{}'),
+ ('police',3,'lieutenant','Komisarz',85,'{}','{}'),
+ ('police',4,'boss','Generalny Inspektor',100,'{}','{}')
+;
+
+CREATE TABLE `fine_types` (
+ `id` int NOT NULL AUTO_INCREMENT,
+ `label` varchar(255) DEFAULT NULL,
+ `amount` int DEFAULT NULL,
+ `category` int DEFAULT NULL,
+
+ PRIMARY KEY (`id`)
+);
+
+INSERT INTO `fine_types` (label, amount, category) VALUES
+ ('Nadużywanie klaksonu', 30, 0),
+ ('Przekroczenie lini ciągłej', 40, 0),
+ ('Jechanie po złej stronie drogi', 250, 0),
+ ('Nieprawidłowe zawracanie', 250, 0),
+ ('Nielegalna jazda Off-road', 170, 0),
+ ('Niedostosowanie się do poleceń Policji', 30, 0),
+ ('Nieprawidłowe zatrzymanie pojazdu', 150, 0),
+ ('Nieprawidłowe parkownie', 70, 0),
+ ('Niezastosowanie się do ruchu prawostronnego (jazda lewym pasem)', 70, 0),
+ ('Brak informacji o pojeździe', 90, 0),
+ ('Niezastosowanie się do znaku SOTP', 105, 0),
+ ('Niezatrzymanie się na czerwonym świetle', 130, 0),
+ ('Przechodzenie w niedozwolonym miejscu', 100, 0),
+ ('Jazda nielegalnym pojazdem', 100, 0),
+ ('Brak prawa jazdy', 1500, 0),
+ ('Ucieczka z miejsca zdarzenia', 800, 0),
+ ('Przekroczenie prędkości < 5 mph', 90, 0),
+ ('Przekroczenie prędkości 5-15 mph', 120, 0),
+ ('Przekroczenie prędkości 15-30 mph', 180, 0),
+ ('Przekroczenie prędkości > 30 mph', 300, 0),
+ ('Utrudnianie przemieszczania się', 110, 1),
+ ('Publiczne zgorszenie', 90, 1),
+ ('Niepoprawne zachowanie', 90, 1),
+ ('Utrudnianie postępowania', 130, 1),
+ ('Obraza cywilów', 75, 1),
+ ('Obraza graczy', 110, 1),
+ ('Groźby werbalne', 90, 1),
+ ('Przeklinanie na graczy', 150, 1),
+ ('Dostarczanie fałszywych informacji', 250, 1),
+ ('Próba korupcji', 1500, 1),
+ ('Wymachiwanie bronią w mieście', 120, 2),
+ ('Wymachiwanie niebezpieczną bronią w mieście', 300, 2),
+ ('Brak pozwolenia na broń', 600, 2),
+ ('Posiadanie nielegalnej broni', 700, 2),
+ ('Posiadanie narzędzi do włamań', 300, 2),
+ ('Złodziej - recydywista', 1800, 2),
+ ('Rozprowadzanie nielegalnych substancji', 1500, 2),
+ ('Wytwarzanie nielegalnych substancji', 1500, 2),
+ ('Posiadanie zakazanych substancji', 650, 2),
+ ('Porwanie cywila', 1500, 2),
+ ('Porwanie gracza', 2000, 2),
+ ('Rabunek', 650, 2),
+ ('Kradzież z bronią w ręku', 650, 2),
+ ('Napad na Bank', 1500, 2),
+ ('Atak na cywila', 2000, 3),
+ ('Atak na gracza', 2500, 3),
+ ('Próba morderstwa cywila', 3000, 3),
+ ('Próba morderstwa gracza', 5000, 3),
+ ('Zabójstwo cywila z premedytacją', 10000, 3),
+ ('Zabójstwo gracza z premedytacją', 30000, 3),
+ ('Nieumyślne spowodowanie śmierci', 1800, 3),
+ ('Oszustwo', 2000, 2);
+;
diff --git a/_resources/esx_policejob/localization/sv_esx_policejob.sql b/_resources/esx_policejob/localization/sv_esx_policejob.sql
new file mode 100644
index 00000000..3f68feb0
--- /dev/null
+++ b/_resources/esx_policejob/localization/sv_esx_policejob.sql
@@ -0,0 +1,89 @@
+USE `es_extended`;
+
+INSERT INTO `addon_account` (name, label, shared) VALUES
+ ('society_police', 'Polis', 1)
+;
+
+INSERT INTO `datastore` (name, label, shared) VALUES
+ ('society_police', 'Polis', 1)
+;
+
+INSERT INTO `addon_inventory` (name, label, shared) VALUES
+ ('society_police', 'Polis', 1)
+;
+
+INSERT INTO `jobs` (name, label) VALUES
+ ('police', 'Polis')
+;
+
+INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES
+ ('police',0,'recruit','Aspirant',20,'{}','{}'),
+ ('police',1,'officer','Assistent',40,'{}','{}'),
+ ('police',2,'sergeant','Inspektör',60,'{}','{}'),
+ ('police',3,'lieutenant','Kommissarie',85,'{}','{}'),
+ ('police',4,'boss','Rikspolischef',100,'{}','{}')
+;
+
+CREATE TABLE `fine_types` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `label` varchar(255) DEFAULT NULL,
+ `amount` int(11) DEFAULT NULL,
+ `category` int(11) DEFAULT NULL,
+
+ PRIMARY KEY (`id`)
+);
+
+INSERT INTO `fine_types` (label, amount, category) VALUES
+ ('Missbruk av tuta',30,0),
+ ('Köra över heldragen linje',40,0),
+ ('Kört i motsatt riktning i rondell',250,0),
+ ('Olaglig u-sväng',250,0),
+ ('Olovlig körning i terräng',170,0),
+ ('Kört för nära bil framför',30,0),
+ ('Trafikfarlig stopp',150,0),
+ ('Olaglig parkering',70,0),
+ ('Använder inte högerregeln',70,0),
+ ('Aktar sig inte för tjänstefordon i utryckning',90,0),
+ ('Kört förbi stoppskylt',105,0),
+ ('Kört mot rött',130,0),
+ ('Farlig omkörning',100,0),
+ ('Fordon i dåligt skick',100,0),
+ ('Kört utan körkort',1500,0),
+ ('Smitning från olycka',800,0),
+ ('Kört för fort < 5 kmh',90,0),
+ ('Kört för fort 5-15 kmh',120,0),
+ ('Kört för fort 15-30 kmh',180,0),
+ ('Kört för fort > 30 kmh',300,0),
+ ('Blockerar trafiken',110,1),
+ ('Förstört allmän egendom',90,1),
+ ('Olaga diskriminering',90,1),
+ ('förhindrar polisens verksamhet',130,1),
+ ('Hets mot folkgrupp',75,1),
+ ('Dåligt beteende mot tjänsteman',110,1),
+ ('Verbalt hot mot annan person',90,1),
+ ('Verbalt hot mot en tjänsteman',150,1),
+ ('Olaglig protest',250,1),
+ ('Försök till mutning',1500,1),
+ ('Icke livshotande vapen på allmän plats ex. Hammare',120,2),
+ ('Dödligt vapen på allmän plats',300,2),
+ ('Vapen på allmän plats med licens (Licens Fel)',600,2),
+ ('Innehaft olaga vapen',700,2),
+ ('Försökt bryta sig in',300,2),
+ ('Bilstöld',1800,2),
+ ('Försäljning av droger',1500,2),
+ ('Tillverkning av droger',1500,2),
+ ('Innehav av droger',650,2),
+ ('Hålla gisslan/Hålla person mot dess vilja',1500,2),
+ ('Kidnappa en tjänsteman',2000,2),
+ ('Rån',650,2),
+ ('Butiksrån',650,2),
+ ('Bankrån',1500,2),
+ ('Skjutit en person',2000,3),
+ ('Skjutit en tjänsteman',2500,3),
+ ('Mordförsök',3000,3),
+ ('Mordförsök på tjänsteman',6000,3),
+ ('Mord',10000,3),
+ ('Mord på tjänsteman',30000,3),
+ ('Dråp',1800,3),
+ ('Olagliga aktiviteter inom ett företag',2000,2)
+;
diff --git a/_resources/esx_policejob/server/main.lua b/_resources/esx_policejob/server/main.lua
new file mode 100644
index 00000000..509fb366
--- /dev/null
+++ b/_resources/esx_policejob/server/main.lua
@@ -0,0 +1,496 @@
+ESX = nil
+
+TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)
+
+if Config.EnableESXService then
+ if Config.MaxInService ~= -1 then
+ TriggerEvent('esx_service:activateService', 'police', Config.MaxInService)
+ end
+end
+
+TriggerEvent('esx_phone:registerNumber', 'police', _U('alert_police'), true, true)
+TriggerEvent('esx_society:registerSociety', 'police', 'Police', 'society_police', 'society_police', 'society_police', {type = 'public'})
+
+RegisterNetEvent('esx_policejob:confiscatePlayerItem')
+AddEventHandler('esx_policejob:confiscatePlayerItem', function(target, itemType, itemName, amount)
+ local _source = source
+ local sourceXPlayer = ESX.GetPlayerFromId(_source)
+ local targetXPlayer = ESX.GetPlayerFromId(target)
+
+ if sourceXPlayer.job.name ~= 'police' then
+ print(('esx_policejob: %s attempted to confiscate!'):format(sourceXPlayer.identifier))
+ return
+ end
+
+ if itemType == 'item_standard' then
+ local targetItem = targetXPlayer.getInventoryItem(itemName)
+ local sourceItem = sourceXPlayer.getInventoryItem(itemName)
+
+ -- does the target player have enough in their inventory?
+ if targetItem.count > 0 and targetItem.count <= amount then
+
+ -- can the player carry the said amount of x item?
+ if sourceXPlayer.canCarryItem(itemName, sourceItem.count) then
+ targetXPlayer.removeInventoryItem(itemName, amount)
+ sourceXPlayer.addInventoryItem (itemName, amount)
+ sourceXPlayer.showNotification(_U('you_confiscated', amount, sourceItem.label, targetXPlayer.name))
+ targetXPlayer.showNotification(_U('got_confiscated', amount, sourceItem.label, sourceXPlayer.name))
+ else
+ sourceXPlayer.showNotification(_U('quantity_invalid'))
+ end
+ else
+ sourceXPlayer.showNotification(_U('quantity_invalid'))
+ end
+
+ elseif itemType == 'item_account' then
+ local targetAccount = targetXPlayer.getAccount(itemName)
+
+ -- does the target player have enough money?
+ if targetAccount.money >= amount then
+ targetXPlayer.removeAccountMoney(itemName, amount)
+ sourceXPlayer.addAccountMoney (itemName, amount)
+
+ sourceXPlayer.showNotification(_U('you_confiscated_account', amount, itemName, targetXPlayer.name))
+ targetXPlayer.showNotification(_U('got_confiscated_account', amount, itemName, sourceXPlayer.name))
+ else
+ sourceXPlayer.showNotification(_U('quantity_invalid'))
+ end
+
+ elseif itemType == 'item_weapon' then
+ if amount == nil then amount = 0 end
+
+ -- does the target player have weapon?
+ if targetXPlayer.hasWeapon(itemName) then
+ targetXPlayer.removeWeapon(itemName, amount)
+ sourceXPlayer.addWeapon (itemName, amount)
+
+ sourceXPlayer.showNotification(_U('you_confiscated_weapon', ESX.GetWeaponLabel(itemName), targetXPlayer.name, amount))
+ targetXPlayer.showNotification(_U('got_confiscated_weapon', ESX.GetWeaponLabel(itemName), amount, sourceXPlayer.name))
+ else
+ sourceXPlayer.showNotification(_U('quantity_invalid'))
+ end
+ end
+end)
+
+RegisterNetEvent('esx_policejob:handcuff')
+AddEventHandler('esx_policejob:handcuff', function(target)
+ local xPlayer = ESX.GetPlayerFromId(source)
+
+ if xPlayer.job.name == 'police' then
+ TriggerClientEvent('esx_policejob:handcuff', target)
+ else
+ print(('esx_policejob: %s attempted to handcuff a player (not cop)!'):format(xPlayer.identifier))
+ end
+end)
+
+RegisterNetEvent('esx_policejob:drag')
+AddEventHandler('esx_policejob:drag', function(target)
+ local xPlayer = ESX.GetPlayerFromId(source)
+
+ if xPlayer.job.name == 'police' then
+ TriggerClientEvent('esx_policejob:drag', target, source)
+ else
+ print(('esx_policejob: %s attempted to drag (not cop)!'):format(xPlayer.identifier))
+ end
+end)
+
+RegisterNetEvent('esx_policejob:putInVehicle')
+AddEventHandler('esx_policejob:putInVehicle', function(target)
+ local xPlayer = ESX.GetPlayerFromId(source)
+
+ if xPlayer.job.name == 'police' then
+ TriggerClientEvent('esx_policejob:putInVehicle', target)
+ else
+ print(('esx_policejob: %s attempted to put in vehicle (not cop)!'):format(xPlayer.identifier))
+ end
+end)
+
+RegisterNetEvent('esx_policejob:OutVehicle')
+AddEventHandler('esx_policejob:OutVehicle', function(target)
+ local xPlayer = ESX.GetPlayerFromId(source)
+
+ if xPlayer.job.name == 'police' then
+ TriggerClientEvent('esx_policejob:OutVehicle', target)
+ else
+ print(('esx_policejob: %s attempted to drag out from vehicle (not cop)!'):format(xPlayer.identifier))
+ end
+end)
+
+RegisterNetEvent('esx_policejob:getStockItem')
+AddEventHandler('esx_policejob:getStockItem', function(itemName, count)
+ local _source = source
+ local xPlayer = ESX.GetPlayerFromId(_source)
+
+ TriggerEvent('esx_addoninventory:getSharedInventory', 'society_police', function(inventory)
+ local inventoryItem = inventory.getItem(itemName)
+
+ -- is there enough in the society?
+ if count > 0 and inventoryItem.count >= count then
+
+ -- can the player carry the said amount of x item?
+ if xPlayer.canCarryItem(itemName, count) then
+ inventory.removeItem(itemName, count)
+ xPlayer.addInventoryItem(itemName, count)
+ xPlayer.showNotification(_U('have_withdrawn', count, inventoryItem.name))
+ else
+ xPlayer.showNotification(_U('quantity_invalid'))
+ end
+ else
+ xPlayer.showNotification(_U('quantity_invalid'))
+ end
+ end)
+end)
+
+RegisterNetEvent('esx_policejob:putStockItems')
+AddEventHandler('esx_policejob:putStockItems', function(itemName, count)
+ local xPlayer = ESX.GetPlayerFromId(source)
+ local sourceItem = xPlayer.getInventoryItem(itemName)
+
+ TriggerEvent('esx_addoninventory:getSharedInventory', 'society_police', function(inventory)
+ local inventoryItem = inventory.getItem(itemName)
+
+ -- does the player have enough of the item?
+ if sourceItem.count >= count and count > 0 then
+ xPlayer.removeInventoryItem(itemName, count)
+ inventory.addItem(itemName, count)
+ xPlayer.showNotification(_U('have_deposited', count, inventoryItem.name))
+ else
+ xPlayer.showNotification(_U('quantity_invalid'))
+ end
+ end)
+end)
+
+ESX.RegisterServerCallback('esx_policejob:getOtherPlayerData', function(source, cb, target, notify)
+ local xPlayer = ESX.GetPlayerFromId(target)
+
+ if notify then
+ xPlayer.showNotification(_U('being_searched'))
+ end
+
+ if xPlayer then
+ local data = {
+ name = xPlayer.getName(),
+ job = xPlayer.job.label,
+ grade = xPlayer.job.grade_label,
+ inventory = xPlayer.getInventory(),
+ accounts = xPlayer.getAccounts(),
+ weapons = xPlayer.getLoadout()
+ }
+
+ if Config.EnableESXIdentity then
+ data.dob = xPlayer.get('dateofbirth')
+ data.height = xPlayer.get('height')
+
+ if xPlayer.get('sex') == 'm' then data.sex = 'male' else data.sex = 'female' end
+ end
+
+ TriggerEvent('esx_status:getStatus', target, 'drunk', function(status)
+ if status then
+ data.drunk = ESX.Math.Round(status.percent)
+ end
+ end)
+
+ if Config.EnableLicenses then
+ TriggerEvent('esx_license:getLicenses', target, function(licenses)
+ data.licenses = licenses
+ cb(data)
+ end)
+ else
+ cb(data)
+ end
+ end
+end)
+
+ESX.RegisterServerCallback('esx_policejob:getFineList', function(source, cb, category)
+ MySQL.Async.fetchAll('SELECT * FROM fine_types WHERE category = @category', {
+ ['@category'] = category
+ }, function(fines)
+ cb(fines)
+ end)
+end)
+
+ESX.RegisterServerCallback('esx_policejob:getVehicleInfos', function(source, cb, plate)
+ MySQL.Async.fetchAll('SELECT owner FROM owned_vehicles WHERE plate = @plate', {
+ ['@plate'] = plate
+ }, function(result)
+ local retrivedInfo = {plate = plate}
+
+ if result[1] then
+ local xPlayer = ESX.GetPlayerFromIdentifier(result[1].owner)
+
+ -- is the owner online?
+ if xPlayer then
+ retrivedInfo.owner = xPlayer.getName()
+ cb(retrivedInfo)
+ elseif Config.EnableESXIdentity then
+ MySQL.Async.fetchAll('SELECT firstname, lastname FROM users WHERE identifier = @identifier', {
+ ['@identifier'] = result[1].owner
+ }, function(result2)
+ if result2[1] then
+ retrivedInfo.owner = ('%s %s'):format(result2[1].firstname, result2[1].lastname)
+ cb(retrivedInfo)
+ else
+ cb(retrivedInfo)
+ end
+ end)
+ else
+ cb(retrivedInfo)
+ end
+ else
+ cb(retrivedInfo)
+ end
+ end)
+end)
+
+ESX.RegisterServerCallback('esx_policejob:getArmoryWeapons', function(source, cb)
+ TriggerEvent('esx_datastore:getSharedDataStore', 'society_police', function(store)
+ local weapons = store.get('weapons')
+
+ if weapons == nil then
+ weapons = {}
+ end
+
+ cb(weapons)
+ end)
+end)
+
+ESX.RegisterServerCallback('esx_policejob:addArmoryWeapon', function(source, cb, weaponName, removeWeapon)
+ local xPlayer = ESX.GetPlayerFromId(source)
+
+ if removeWeapon then
+ xPlayer.removeWeapon(weaponName)
+ end
+
+ TriggerEvent('esx_datastore:getSharedDataStore', 'society_police', function(store)
+ local weapons = store.get('weapons') or {}
+ local foundWeapon = false
+
+ for i=1, #weapons, 1 do
+ if weapons[i].name == weaponName then
+ weapons[i].count = weapons[i].count + 1
+ foundWeapon = true
+ break
+ end
+ end
+
+ if not foundWeapon then
+ table.insert(weapons, {
+ name = weaponName,
+ count = 1
+ })
+ end
+
+ store.set('weapons', weapons)
+ cb()
+ end)
+end)
+
+ESX.RegisterServerCallback('esx_policejob:removeArmoryWeapon', function(source, cb, weaponName)
+ local xPlayer = ESX.GetPlayerFromId(source)
+ xPlayer.addWeapon(weaponName, 500)
+
+ TriggerEvent('esx_datastore:getSharedDataStore', 'society_police', function(store)
+ local weapons = store.get('weapons') or {}
+
+ local foundWeapon = false
+
+ for i=1, #weapons, 1 do
+ if weapons[i].name == weaponName then
+ weapons[i].count = (weapons[i].count > 0 and weapons[i].count - 1 or 0)
+ foundWeapon = true
+ break
+ end
+ end
+
+ if not foundWeapon then
+ table.insert(weapons, {
+ name = weaponName,
+ count = 0
+ })
+ end
+
+ store.set('weapons', weapons)
+ cb()
+ end)
+end)
+
+ESX.RegisterServerCallback('esx_policejob:buyWeapon', function(source, cb, weaponName, type, componentNum)
+ local xPlayer = ESX.GetPlayerFromId(source)
+ local authorizedWeapons, selectedWeapon = Config.AuthorizedWeapons[xPlayer.job.grade_name]
+
+ for k,v in ipairs(authorizedWeapons) do
+ if v.weapon == weaponName then
+ selectedWeapon = v
+ break
+ end
+ end
+
+ if not selectedWeapon then
+ print(('esx_policejob: %s attempted to buy an invalid weapon.'):format(xPlayer.identifier))
+ cb(false)
+ else
+ -- Weapon
+ if type == 1 then
+ if xPlayer.getMoney() >= selectedWeapon.price then
+ xPlayer.removeMoney(selectedWeapon.price)
+ xPlayer.addWeapon(weaponName, 100)
+
+ cb(true)
+ else
+ cb(false)
+ end
+
+ -- Weapon Component
+ elseif type == 2 then
+ local price = selectedWeapon.components[componentNum]
+ local weaponNum, weapon = ESX.GetWeapon(weaponName)
+ local component = weapon.components[componentNum]
+
+ if component then
+ if xPlayer.getMoney() >= price then
+ xPlayer.removeMoney(price)
+ xPlayer.addWeaponComponent(weaponName, component.name)
+
+ cb(true)
+ else
+ cb(false)
+ end
+ else
+ print(('esx_policejob: %s attempted to buy an invalid weapon component.'):format(xPlayer.identifier))
+ cb(false)
+ end
+ end
+ end
+end)
+
+ESX.RegisterServerCallback('esx_policejob:buyJobVehicle', function(source, cb, vehicleProps, type)
+ local xPlayer = ESX.GetPlayerFromId(source)
+ local price = getPriceFromHash(vehicleProps.model, xPlayer.job.grade_name, type)
+
+ -- vehicle model not found
+ if price == 0 then
+ print(('esx_policejob: %s attempted to exploit the shop! (invalid vehicle model)'):format(xPlayer.identifier))
+ cb(false)
+ else
+ if xPlayer.getMoney() >= price then
+ xPlayer.removeMoney(price)
+
+ MySQL.Async.execute('INSERT INTO owned_vehicles (owner, vehicle, plate, type, job, `stored`) VALUES (@owner, @vehicle, @plate, @type, @job, @stored)', {
+ ['@owner'] = xPlayer.identifier,
+ ['@vehicle'] = json.encode(vehicleProps),
+ ['@plate'] = vehicleProps.plate,
+ ['@type'] = type,
+ ['@job'] = xPlayer.job.name,
+ ['@stored'] = true
+ }, function (rowsChanged)
+ cb(true)
+ end)
+ else
+ cb(false)
+ end
+ end
+end)
+
+ESX.RegisterServerCallback('esx_policejob:storeNearbyVehicle', function(source, cb, nearbyVehicles)
+ local xPlayer = ESX.GetPlayerFromId(source)
+ local foundPlate, foundNum
+
+ for k,v in ipairs(nearbyVehicles) do
+ local result = MySQL.Sync.fetchAll('SELECT plate FROM owned_vehicles WHERE owner = @owner AND plate = @plate AND job = @job', {
+ ['@owner'] = xPlayer.identifier,
+ ['@plate'] = v.plate,
+ ['@job'] = xPlayer.job.name
+ })
+
+ if result[1] then
+ foundPlate, foundNum = result[1].plate, k
+ break
+ end
+ end
+
+ if not foundPlate then
+ cb(false)
+ else
+ MySQL.Async.execute('UPDATE owned_vehicles SET `stored` = true WHERE owner = @owner AND plate = @plate AND job = @job', {
+ ['@owner'] = xPlayer.identifier,
+ ['@plate'] = foundPlate,
+ ['@job'] = xPlayer.job.name
+ }, function (rowsChanged)
+ if rowsChanged == 0 then
+ print(('esx_policejob: %s has exploited the garage!'):format(xPlayer.identifier))
+ cb(false)
+ else
+ cb(true, foundNum)
+ end
+ end)
+ end
+end)
+
+function getPriceFromHash(vehicleHash, jobGrade, type)
+ local vehicles = Config.AuthorizedVehicles[type][jobGrade]
+
+ for k,v in ipairs(vehicles) do
+ if GetHashKey(v.model) == vehicleHash then
+ return v.price
+ end
+ end
+
+ return 0
+end
+
+ESX.RegisterServerCallback('esx_policejob:getStockItems', function(source, cb)
+ TriggerEvent('esx_addoninventory:getSharedInventory', 'society_police', function(inventory)
+ cb(inventory.items)
+ end)
+end)
+
+ESX.RegisterServerCallback('esx_policejob:getPlayerInventory', function(source, cb)
+ local xPlayer = ESX.GetPlayerFromId(source)
+ local items = xPlayer.inventory
+
+ cb({items = items})
+end)
+
+AddEventHandler('playerDropped', function()
+ -- Save the source in case we lose it (which happens a lot)
+ local playerId = source
+
+ -- Did the player ever join?
+ if playerId then
+ local xPlayer = ESX.GetPlayerFromId(playerId)
+
+ -- Is it worth telling all clients to refresh?
+ if xPlayer and xPlayer.job.name == 'police' then
+ Citizen.Wait(5000)
+ TriggerClientEvent('esx_policejob:updateBlip', -1)
+ end
+ end
+end)
+
+RegisterNetEvent('esx_policejob:spawned')
+AddEventHandler('esx_policejob:spawned', function()
+ local xPlayer = ESX.GetPlayerFromId(playerId)
+
+ if xPlayer and xPlayer.job.name == 'police' then
+ Citizen.Wait(5000)
+ TriggerClientEvent('esx_policejob:updateBlip', -1)
+ end
+end)
+
+RegisterNetEvent('esx_policejob:forceBlip')
+AddEventHandler('esx_policejob:forceBlip', function()
+ TriggerClientEvent('esx_policejob:updateBlip', -1)
+end)
+
+AddEventHandler('onResourceStart', function(resource)
+ if resource == GetCurrentResourceName() then
+ Citizen.Wait(5000)
+ TriggerClientEvent('esx_policejob:updateBlip', -1)
+ end
+end)
+
+AddEventHandler('onResourceStop', function(resource)
+ if resource == GetCurrentResourceName() then
+ TriggerEvent('esx_phone:removeNumber', 'police')
+ end
+end)