From 52a855cc8be4674a689e53befdbff23b3e903e22 Mon Sep 17 00:00:00 2001
From: bitpredator <67551273+bitpredator@users.noreply.github.com>
Date: Tue, 27 Aug 2024 11:34:49 +0200
Subject: [PATCH] delete: removed obsolete esx_uteknark1
---
.../[esx_addons]/esx_uteknark1/LICENSE | 674 ------------------
.../[esx_addons]/esx_uteknark1/README.md | 8 -
.../esx_uteknark1/cl_uteknark.lua | 503 -------------
.../[esx_addons]/esx_uteknark1/config.lua | 55 --
.../esx_uteknark1/esx_uteknark.sql | 10 -
.../[esx_addons]/esx_uteknark1/fxmanifest.lua | 28 -
.../esx_uteknark1/lib/cropstate.lua | 233 ------
.../[esx_addons]/esx_uteknark1/lib/debug.lua | 103 ---
.../[esx_addons]/esx_uteknark1/lib/growth.lua | 93 ---
.../[esx_addons]/esx_uteknark1/lib/octree.lua | 390 ----------
.../[esx_addons]/esx_uteknark1/locales/cz.lua | 27 -
.../[esx_addons]/esx_uteknark1/locales/it.lua | 27 -
.../[esx_addons]/esx_uteknark1/locales/sv.lua | 27 -
.../esx_uteknark1/sv_uteknark.lua | 420 -----------
14 files changed, 2598 deletions(-)
delete mode 100644 server-data/resources/[esx_addons]/esx_uteknark1/LICENSE
delete mode 100644 server-data/resources/[esx_addons]/esx_uteknark1/README.md
delete mode 100644 server-data/resources/[esx_addons]/esx_uteknark1/cl_uteknark.lua
delete mode 100644 server-data/resources/[esx_addons]/esx_uteknark1/config.lua
delete mode 100644 server-data/resources/[esx_addons]/esx_uteknark1/esx_uteknark.sql
delete mode 100644 server-data/resources/[esx_addons]/esx_uteknark1/fxmanifest.lua
delete mode 100644 server-data/resources/[esx_addons]/esx_uteknark1/lib/cropstate.lua
delete mode 100644 server-data/resources/[esx_addons]/esx_uteknark1/lib/debug.lua
delete mode 100644 server-data/resources/[esx_addons]/esx_uteknark1/lib/growth.lua
delete mode 100644 server-data/resources/[esx_addons]/esx_uteknark1/lib/octree.lua
delete mode 100644 server-data/resources/[esx_addons]/esx_uteknark1/locales/cz.lua
delete mode 100644 server-data/resources/[esx_addons]/esx_uteknark1/locales/it.lua
delete mode 100644 server-data/resources/[esx_addons]/esx_uteknark1/locales/sv.lua
delete mode 100644 server-data/resources/[esx_addons]/esx_uteknark1/sv_uteknark.lua
diff --git a/server-data/resources/[esx_addons]/esx_uteknark1/LICENSE b/server-data/resources/[esx_addons]/esx_uteknark1/LICENSE
deleted file mode 100644
index a10cf2b1b..000000000
--- a/server-data/resources/[esx_addons]/esx_uteknark1/LICENSE
+++ /dev/null
@@ -1,674 +0,0 @@
- 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.
-
-
- Copyright (C) 2023-2024 bitpredator
-
- 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:
-
- esx_uteknark Copyright (C) 2023-2024 bitpredator
- 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
-.
diff --git a/server-data/resources/[esx_addons]/esx_uteknark1/README.md b/server-data/resources/[esx_addons]/esx_uteknark1/README.md
deleted file mode 100644
index 2f88a9bfa..000000000
--- a/server-data/resources/[esx_addons]/esx_uteknark1/README.md
+++ /dev/null
@@ -1,8 +0,0 @@
-# Legal
-Copyright (C) 2019-2024
-
-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/server-data/resources/[esx_addons]/esx_uteknark1/cl_uteknark.lua b/server-data/resources/[esx_addons]/esx_uteknark1/cl_uteknark.lua
deleted file mode 100644
index 55148bebf..000000000
--- a/server-data/resources/[esx_addons]/esx_uteknark1/cl_uteknark.lua
+++ /dev/null
@@ -1,503 +0,0 @@
-local table = table
-local plantingTargetOffset = vector3(0, 2, -3)
-local plantingSpaceAbove = vector3(0, 0, Config.Distance.Above)
-local rayFlagsLocation = 17
-local rayFlagsObstruction = 273
-local activePlants = {}
-
-local registerStrings = {
- "status_active",
- "status_passive",
-}
-
-for _, entry in ipairs(registerStrings) do
- AddTextEntry("uteknark_" .. entry, _U(entry))
-end
-
-function interactHelp(stage, action)
- BeginTextCommandDisplayHelp("uteknark_status_active")
- AddTextComponentInteger(stage)
- AddTextComponentInteger(#Growth)
- AddTextComponentSubstringPlayerName(action)
- EndTextCommandDisplayHelp(0, false, false, 1)
-end
-function passiveHelp(stage, status)
- BeginTextCommandDisplayHelp("uteknark_status_passive")
- AddTextComponentInteger(stage)
- AddTextComponentInteger(#Growth)
- AddTextComponentSubstringPlayerName(status)
- EndTextCommandDisplayHelp(0, false, false, 1)
-end
-
-function makeToast(subject, message)
- local dict = "bkr_prop_weed"
- local icon = "prop_cannabis_leaf_dprop_cannabis_leaf_a"
- if not HasStreamedTextureDictLoaded(dict) then
- RequestStreamedTextureDict(dict)
- while not HasStreamedTextureDictLoaded(dict) do
- Wait(0)
- end
- end
-
- -- BeginTextCommandThefeedPost("STRING")
- SetNotificationTextEntry("STRING")
- AddTextComponentSubstringPlayerName(message)
- --EndTextCommandThefeedPostMessagetext(
- SetNotificationMessage(
- dict, -- texture dict
- icon, -- texture name
- true, -- fade
- 0, -- icon type
- "Pestovani", -- Sender
- subject
- )
- --EndTextCommandThefeedPostTicker(
- DrawNotification(
- false, -- important
- false -- has tokens
- )
- SetStreamedTextureDictAsNoLongerNeeded(icon)
-end
-
-function serverlog(...)
- TriggerServerEvent("esx_uteknark1:log", ...)
-end
-
-RegisterNetEvent("esx_uteknark1:make_toast")
-AddEventHandler("esx_uteknark1:make_toast", function(subject, message)
- makeToast(subject, message)
-end)
-
-function flatEnough(surfaceNormal)
- local x = math.abs(surfaceNormal.x)
- local y = math.abs(surfaceNormal.y)
- local z = math.abs(surfaceNormal.z)
- return (x <= Config.MaxGroundAngle and y <= Config.MaxGroundAngle and z >= 1.0 - Config.MaxGroundAngle)
-end
-
-function getPlantingLocation(visible)
- -- TODO: Refactor this *monster*, plx!
- local ped = PlayerPedId()
-
- if IsPedInAnyVehicle(ped) then
- return false, "planting_in_vehicle" -- The rest can all nil out
- end
-
- local playerCoord = GetEntityCoords(ped)
- local target = GetOffsetFromEntityInWorldCoords(ped, plantingTargetOffset)
- local testRay = StartShapeTestRay(playerCoord, target, rayFlagsLocation, ped, 7) -- This 7 is entirely cargo cult. No idea what it does.
- local _, hit, hitLocation, surfaceNormal, material, _ = GetShapeTestResultEx(testRay)
-
- if hit == 1 then
- debug("Material:", material)
- debug("Hit location:", hitLocation)
- debug("Surface normal:", surfaceNormal)
-
- if Config.Soil[material] then
- debug("Soil quality:", Config.Soil[material])
- if flatEnough(surfaceNormal) then
- local plantDistance = #(playerCoord - hitLocation)
- debug(plantDistance)
- if plantDistance <= Config.Distance.Interact then
- local hits = cropstate.octree:searchSphere(hitLocation, Config.Distance.Space)
- if #hits > 0 then
- debug("Found another plant too close")
- if visible then
- for _, hit in ipairs(hits) do
- DrawLine(hitLocation, hit.bounds.location, 255, 0, 255, 100)
- end
- DebugSphere(hitLocation, 0.1, 255, 0, 255, 100)
- DrawLine(playerCoord, hitLocation, 255, 0, 255, 100)
- end
- return false, "planting_too_close", hitLocation, surfaceNormal, material
- else
- if visible then
- DebugSphere(hitLocation, 0.1, 0, 255, 0, 100)
- DrawLine(playerCoord, hitLocation, 0, 255, 0, 100)
- end
- local aboveTarget = hitLocation + plantingSpaceAbove
- local aboveRay = StartShapeTestRay(hitLocation, aboveTarget, rayFlagsObstruction, ped, 7)
- local _, hitAbove, hitAbovePoint = GetShapeTestResult(aboveRay)
- if hitAbove == 1 then
- if visible then
- debug("Obstructed above")
- DrawLine(hitLocation, hitAbovePoint, 255, 0, 0, 100)
- DebugSphere(hitAbovePoint, 0.1, 255, 0, 0, 100)
- end
- return false, "planting_obstructed", hitLocation, surfaceNormal, material
- else
- if visible then
- DrawLine(hitLocation, aboveTarget, 0, 255, 0, 100)
- DebugSphere(hitAbovePoint, 0.1, 255, 0, 0, 100)
- debug("~g~planting OK")
- end
- return true, "planting_ok", hitLocation, surfaceNormal, material
- end
- end
- else
- if visible then
- DebugSphere(hitLocation, 0.1, 0, 128, 0, 100)
- DrawLine(playerCoord, hitLocation, 0, 128, 0, 100)
- debug("Target too far away")
- end
- return false, "planting_too_far", hitLocation, surfaceNormal, material
- end
- else
- if visible then
- DebugSphere(hitLocation, 0.1, 0, 0, 255, 100)
- DrawLine(playerCoord, hitLocation, 0, 0, 255, 100)
- debug("Location too steep")
- end
- return false, "planting_too_steep", hitLocation, surfaceNormal, material
- end
- else
- if visible then
- debug("Not plantable soil")
- DebugSphere(hitLocation, 0.1, 255, 255, 0, 100)
- DrawLine(playerCoord, hitLocation, 255, 255, 0, 100)
- end
- return false, "planting_not_suitable_soil", hitLocation, surfaceNormal, material
- end
- else
- if visible then
- debug("Ground not found")
- DrawLine(playerCoord, target, 255, 0, 0, 255)
- end
- return false, "planting_too_steep", hitLocation, surfaceNormal, material
- end
-end
-
-function GetHeadingFromPoints(a, b)
- if not a or not b then
- return 0.0
- end
- if a.x == b.x and a.y == b.y then
- return 0.0
- end
- if #(a - b) < 1 then
- return 0.0
- end
-
- local theta = math.atan(b.x - a.x, a.y - b.y)
- if theta < 0.0 then
- theta = theta + (math.pi * 2)
- end
- return math.deg(theta) + 180 % 360
-end
-
-local inScenario = false
-local WEAPON_UNARMED = `WEAPON_UNARMED`
-local lastAction = 0
-function RunScenario(name, facing)
- local playerPed = PlayerPedId()
- ClearPedTasks(playerPed)
- SetCurrentPedWeapon(playerPed, WEAPON_UNARMED)
- if facing then
- local heading = GetHeadingFromPoints(GetEntityCoords(playerPed), facing)
- SetEntityHeading(playerPed, heading)
- Wait(0) -- So it syncs before we start the scenario!
- end
- TaskStartScenarioInPlace(playerPed, name, 0, true)
- inScenario = true
-end
-
-RegisterNetEvent("esx_uteknark1:do")
-AddEventHandler("esx_uteknark1:do", function(scenarioName, location)
- if Config.Scenario[scenarioName] then
- print("Got order for scenario " .. scenarioName)
- CreateThread(function()
- local begin = GetGameTimer()
- RunScenario(Config.Scenario[scenarioName], location)
- while GetGameTimer() <= begin + Config.ScenarioTime do
- Wait(0)
- end
- if inScenario then
- ClearPedTasks(PlayerPedId())
- end
- inScenario = false
- print("Scenario " .. scenarioName .. " ends")
- end)
- else
- print("Got ordered to do invalid scenario " .. scenarioName)
- end
-end)
-
-RegisterNetEvent("esx_uteknark1:attempt_plant")
-AddEventHandler("esx_uteknark1:attempt_plant", function()
- local plantable, message, location, _, soil = getPlantingLocation()
- if plantable then
- TriggerServerEvent("esx_uteknark1:success_plant", location, soil)
- lastAction = GetGameTimer()
- else
- makeToast(_U("planting_text"), _U(message))
- end
-end)
-
-function DrawIndicator(location, color)
- local range = 1.0
- DrawMarker(
- 6, -- type (6 is a vertical and 3D ring)
- location,
- 0.0,
- 0.0,
- 0.0, -- direction (?)
- -90.0,
- 0.0,
- 0.0, -- rotation (90 degrees because the right is really vertical)
- range,
- range,
- range, -- scale
- color[1],
- color[2],
- color[3],
- color[4],
- false, -- bob
- false, -- face camera
- 2, -- dunno, lol, 100% cargo cult
- false, -- rotates
- 0,
- 0, -- texture
- false -- Projects/draws on entities
- )
-end
-
-CreateThread(function()
- local drawDistance = Config.Distance.Draw
- drawDistance = drawDistance * 1.01 -- So they don't fight about it, culling is at a slightly longer range
- while true do
- local now = GetGameTimer()
- local playerPed = PlayerPedId()
-
- if inScenario then
- debug("In scenario", inScenario)
- end
-
- if #activePlants > 0 then
- debug(#activePlants, "active plants")
- local myLocation = GetEntityCoords(playerPed)
- local closestDistance
- local closestPlant
- local closestIndex
- for i, plant in ipairs(activePlants) do
- local distance = #(plant.at - myLocation)
- if not DoesEntityExist(plant.object) then
- table.remove(activePlants, i)
- elseif distance > drawDistance then
- DeleteObject(plant.object)
- plant.node.data.object = nil
- table.remove(activePlants, i)
- elseif not closestDistance or distance < closestDistance then
- closestDistance = distance
- closestPlant = plant
- closestIndex = i
- end
- end
- if closestDistance and not IsPedInAnyVehicle(playerPed) then
- debug("Closest plant at", closestDistance, "meters")
- if closestDistance <= Config.Distance.Interact then
- local stage = Growth[closestPlant.stage]
- debug("Closest plant has ID", closestPlant.id)
- debug("Closest pant is stage", closestPlant.stage)
- DrawIndicator(closestPlant.at + stage.marker.offset, stage.marker.color)
- debug("Within intraction distance!")
- DisableControlAction(0, 44, true) -- Disable INPUT_COVER, as it's used to destroy plants
- if now >= lastAction + Config.ActionTime then
- if IsDisabledControlJustPressed(0, 44) then
- lastAction = now
- table.remove(activePlants, closestIndex)
- DeleteObject(closestPlant.object)
- TriggerServerEvent("esx_uteknark1:remove", closestPlant.id, myLocation)
- else
- if stage.interact then
- interactHelp(closestPlant.stage, _U(stage.label))
- if IsControlJustPressed(0, 38) then
- lastAction = now
- TriggerServerEvent("esx_uteknark1:frob", closestPlant.id, myLocation)
- end
- else
- passiveHelp(closestPlant.stage, _U(stage.label))
- end
- end
- end
- end
- end
- Wait(0)
- else
- Wait(500)
- end
- end
-end)
-
-CreateThread(function()
- local drawDistance = Config.Distance.Draw
- while true do
- local here = GetEntityCoords(PlayerPedId())
- cropstate.octree:searchSphereAsync(here, drawDistance, function(entry)
- if not entry.data.object and not entry.data.deleted then
- local stage = entry.data.stage or 1
- local model = Growth[stage].model
- if not model or not IsModelValid(model) then
- Citizen.Trace(tostring(model) .. " is not a valid model!\n")
- model = `prop_mp_cone_01`
- end
- if not HasModelLoaded(model) then
- RequestModel(model)
- local begin = GetGameTimer()
- while not HasModelLoaded(model) and GetGameTimer() < begin + 2500 do
- Wait(0)
- end
- end
- if not HasModelLoaded(model) then
- Citizen.Trace("Failed to load model for growth stage " .. stage .. ", but will retry shortly!\n")
- Wait(2500)
- else
- local offset = Growth[stage].offset or vector3(0, 0, 0)
- local weed = CreateObject(model, entry.bounds.location + offset, false, false, false)
- local heading = math.random(0, 359) * 1.0
- SetEntityHeading(weed, heading)
- FreezeEntityPosition(weed, true)
- SetEntityCollision(weed, false, true)
- if Config.SetLOD then
- SetEntityLodDist(weed, math.floor(drawDistance))
- end
- table.insert(activePlants, { node = entry, object = weed, at = entry.bounds.location, stage = stage, id = entry.data.id })
- entry.data.object = weed
- SetModelAsNoLongerNeeded(model)
- end
- end
- end, true)
- Wait(1500)
- end
-end)
-
-function deleteActivePlants()
- for _, plant in ipairs(activePlants) do
- if DoesEntityExist(plant.object) then
- DeleteObject(plant.object)
- end
- end
- activePlants = {}
-end
-
-AddEventHandler("onResourceStop", function(resourceName)
- if resourceName == GetCurrentResourceName() then
- deleteActivePlants()
- if inScenario then
- ClearPedTasksImmediately(PlayerPedId())
- end
- end
-end)
-
-RegisterNetEvent("esx_uteknark1:toggle_debug")
-AddEventHandler("esx_uteknark1:toggle_debug", function()
- if not debug.active then
- serverlog("enabled debugging")
- debug.active = true
- else
- serverlog("disabled debugging")
- debug.active = false
- end
-end)
-
-RegisterNetEvent("esx_uteknark1:pyromaniac")
-AddEventHandler("esx_uteknark1:pyromaniac", function(location)
- if Config.Burn.Enabled then
- local myLocation = GetEntityCoords(PlayerPedId())
- if not location then
- location = myLocation + vector3(0, 0, -1) -- Because the ped location is one meter off the ground.
- end
- if #(location - myLocation) <= Config.Distance.Draw then
- CreateThread(function()
- local begin = GetGameTimer()
- if not HasNamedPtfxAssetLoaded(Config.Burn.Effect) then
- RequestNamedPtfxAsset(Config.Burn.Collection)
- while not HasNamedPtfxAssetLoaded(Config.Burn.Collection) and GetGameTimer() <= begin + Config.Burn.Duration do
- Wait(0)
- end
- if not HasNamedPtfxAssetLoaded(Config.Burn.Collection) then
- print("UteKnark failed to load particle effects asset " .. Config.Burn.Collection)
- end
- end
- UseParticleFxAsset(Config.Burn.Collection)
- local handle = StartParticleFxLoopedAtCoord(Config.Burn.Effect, location + Config.Burn.Offset, Config.Burn.Rotation, Config.Burn.Scale * 1.0, false, false, false)
- while GetGameTimer() <= begin + Config.Burn.Duration do
- Wait(0)
- end
- StopParticleFxLooped(handle, 0)
- RemoveNamedPtfxAsset(Config.Burn.Collection)
- end)
- end
- end
-end)
-
-CreateThread(function()
- local ready = false
- while true do
- if ready then
- if debug.active then
- local message = getPlantingLocation(true)
- if message then
- debug("Planting message:", _U(message))
- end
- debug:flush()
- end
- Wait(0)
- else
- if NetworkIsSessionStarted() then
- ready = true
- cropstate:bulkData()
- else
- Wait(100)
- end
- end
- end
-end)
-
-RegisterNetEvent("esx_uteknark1:groundmat")
-AddEventHandler("esx_uteknark1:groundmat", function()
- local material = getPlantingLocation(true)
- TriggerEvent("chat:addMessage", { args = { "Ground material", material } })
- serverlog("Ground material:", material)
-
- if Config.Soil[material] then
- local quality = Config.Soil[material]
- TriggerEvent("chat:addMessage", { args = { "Soil quality", quality } })
- serverlog("Soil quality:", quality)
- else
- TriggerEvent("chat:addMessage", { args = { "Material not whitelisted" } })
- serverlog("Material not whitelisted")
- end
-end)
-
-RegisterNetEvent("esx_uteknark1:test_forest")
-AddEventHandler("esx_uteknark1:test_forest", function(count, randomStage)
- local origin = GetEntityCoords(PlayerPedId())
-
- TriggerEvent("chat:addMessage", { args = { "UteKnark", "Target forest size: " .. count } })
- local column = math.ceil(math.sqrt(count))
- TriggerEvent("chat:addMessage", { args = { "UteKnark", "Column size: " .. column } })
-
- local offset = (column * Config.Distance.Space) / 2
- offset = vector3(-offset, -offset, 5)
- local cursor = origin + offset
- local planted = 0
- local forest = {}
- while planted < count do
- local found, Z = GetGroundZFor_3dCoord(cursor.x, cursor.y, cursor.z, false)
- if found then
- local stage = (planted % #Growth) + 1
- if randomStage then
- stage = math.random(#Growth)
- end
- table.insert(forest, { location = vector3(cursor.x, cursor.y, Z), stage = stage })
- end
- cursor = cursor + vector3(0, Config.Distance.Space, 0)
- planted = planted + 1
- if planted % column == 0 then
- Wait(0)
- cursor = cursor + vector3(Config.Distance.Space, -(Config.Distance.Space * column), 0)
- end
- end
- TriggerEvent("chat:addMessage", { args = { "UteKnark", "Actual viable locations: " .. #forest } })
- TriggerServerEvent("esx_uteknark1:test_forest", forest)
-end)
diff --git a/server-data/resources/[esx_addons]/esx_uteknark1/config.lua b/server-data/resources/[esx_addons]/esx_uteknark1/config.lua
deleted file mode 100644
index 19166abf0..000000000
--- a/server-data/resources/[esx_addons]/esx_uteknark1/config.lua
+++ /dev/null
@@ -1,55 +0,0 @@
-Config = {
- Locale = "it",
- Distance = { -- All distances in meters
- Draw = 150.0, -- How close to a plant do you need to be to see it?
- Interact = 1.5, -- How close do you need to be to interact?
- Space = 1.2, -- How far apart do the plants need to be planted?
- Above = 5.0, -- How much clear space above the planting space do you need to plant?
- },
- SetLOD = false, -- Should plant object LOD be messed with? (Might cause plant invisibility on very low settings!)
- ActionTime = 10000, -- How many milliseconds does an action take (planting, destroying, harvesting, tending)
- ScenarioTime = 3000, -- How long should the scenario/animations run?
- MaxGroundAngle = 0.6, -- How tilted can the ground be and still hold plants?
- Items = { -- What items are used?
- Seed = "coke_seed", -- Used to plant the weed
- Tend = nil, -- Optional item to progress growth cycle
- Product = "coke", -- What item is given when you harvest?
- },
- Scenario = {
- Plant = "WORLD_HUMAN_GARDENER_PLANT",
- Frob = "PROP_HUMAN_BUM_BIN",
- Destroy = "WORLD_HUMAN_STAND_FIRE",
- },
- Burn = { -- Burn effect when destroying a plant
- Enabled = true, -- Is the burn effect even enabled?
- Collection = "scr_mp_house", -- "Particle effect asset" in RAGE
- Effect = "scr_mp_int_fireplace_sml", -- Which specific effect in that asset?
- Scale = 1.5, -- Some are big, some are small, so adjusting to your needs makes sense
- Rotation = vector3(0, 0, 0), -- Because some effects point in unexpected directions
- Offset = vector3(0, 0, 0.2), -- The distance from the plant root location
- Duration = 20000, -- How long should it burn, in milliseconds?
- },
- Yield = { 5, 10 }, -- How many Items.Product does each plant yield? {5,10} means "from 5 to 10, inclusive"
- YieldSeed = { 0, 1 }, -- Same as Yield, except for the amount of seeds you get back
- TimeMultiplier = 1.0, -- Multiplier for the growth/tend times
- Soil = {
- -- What soil types can you grow on, and what are their multiplers/divisors? Higher is better.
- -- 0.5 means growing takes twice the time and you have half as much time to tend or harvest
- [2409420175] = 1.0,
- -- [951832588] = 0.5,
- [3008270349] = 0.8,
- [3833216577] = 1.0,
- [223086562] = 1.1,
- [1333033863] = 0.9,
- [4170197704] = 1.0,
- [3594309083] = 0.8,
- [2461440131] = 0.8,
- [1109728704] = 1.5,
- [2352068586] = 1.1,
- [1144315879] = 0.9,
- [581794674] = 1.1,
- [2128369009] = 0.8,
- [-461750719] = 1.0,
- [-1286696947] = 1.0,
- },
-}
diff --git a/server-data/resources/[esx_addons]/esx_uteknark1/esx_uteknark.sql b/server-data/resources/[esx_addons]/esx_uteknark1/esx_uteknark.sql
deleted file mode 100644
index c5e591012..000000000
--- a/server-data/resources/[esx_addons]/esx_uteknark1/esx_uteknark.sql
+++ /dev/null
@@ -1,10 +0,0 @@
-CREATE TABLE `uteknark1` (
- `id` INT(10) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
- `stage` INT(3) UNSIGNED NOT NULL DEFAULT 1,
- `time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
- `x` FLOAT(10) NOT NULL,
- `y` FLOAT(10) NOT NULL,
- `z` FLOAT(10) NOT NULL,
- `soil` BIGINT(20) NOT NULL,
- INDEX (`stage`, `time`)
-);
diff --git a/server-data/resources/[esx_addons]/esx_uteknark1/fxmanifest.lua b/server-data/resources/[esx_addons]/esx_uteknark1/fxmanifest.lua
deleted file mode 100644
index fafcdbaaf..000000000
--- a/server-data/resources/[esx_addons]/esx_uteknark1/fxmanifest.lua
+++ /dev/null
@@ -1,28 +0,0 @@
-fx_version("adamant")
-game("gta5")
-lua54("yes")
-version("1.0.1")
-description("ESX UteKnark by DemmyDemon - bitpredator rebuild")
-
-shared_scripts({
- "@es_extended/locale.lua",
- "locales/*.lua",
- "config.lua",
- "lib/*.lua",
- "@es_extended/imports.lua",
-})
-
-client_scripts({
- "lib/debug.lua",
- "cl_uteknark.lua",
-})
-
-server_scripts({
- "@mysql-async/lib/MySQL.lua",
- "sv_uteknark.lua",
-})
-
-dependencies({
- "es_extended",
- "mysql-async",
-})
diff --git a/server-data/resources/[esx_addons]/esx_uteknark1/lib/cropstate.lua b/server-data/resources/[esx_addons]/esx_uteknark1/lib/cropstate.lua
deleted file mode 100644
index 4005ff1e2..000000000
--- a/server-data/resources/[esx_addons]/esx_uteknark1/lib/cropstate.lua
+++ /dev/null
@@ -1,233 +0,0 @@
-local onServer = IsDuplicityVersion()
-local cropstateMethods = {
- plant = function(instance, location, soil, stage)
- if onServer then
- stage = stage or 1
- MySQL.Async.insert("INSERT INTO `uteknark1` (`x`, `y`, `z`, `soil`, `stage`) VALUES (@x, @y, @z, @soil, @stage);", {
- ["@x"] = location.x,
- ["@y"] = location.y,
- ["@z"] = location.z,
- ["@soil"] = soil,
- ["@stage"] = stage,
- }, function(id)
- instance:import(id, location, stage, os.time(), soil)
- TriggerClientEvent("esx_uteknark1:planted", -1, id, location, stage)
- verbose("Plant", id, "was planted.")
- end)
- else
- Citizen.Trace("Attempt to cropstate:plant on client. Not going to work.\n")
- end
- end,
- load = function(instance, callback)
- if onServer then
- verbose("Loading...")
- MySQL.Async.fetchAll("SELECT `id`, `stage`, UNIX_TIMESTAMP(`time`) AS `time`, `x`, `y`, `z`, `soil` FROM `uteknark1`;", {}, function(rows)
- CreateThread(function()
- for rownum, row in ipairs(rows) do
- instance:import(row.id, vector3(row.x, row.y, row.z), row.stage, row.time, row.soil)
- if rownum % 50 == 0 then
- Wait(0)
- end
- end
- if callback then
- callback(#rows)
- end
- instance.loaded = true
- verbose("Load complete")
- end)
- end)
- else
- Citizen.Trace("Attempt to cropstate:load on client. Not going to work\n")
- end
- end,
- import = function(instance, id, location, stage, time, soil)
- local success, object = instance.octree:insert(location, 0.01, { id = id, stage = stage, time = time, soil = soil })
- if not success then
- Citizen.Trace(string.format("Uteknark failed to import plant with ID %i into octree\n", id))
- end
- instance.index[id] = object
- end,
- update = function(instance, id, stage)
- local plant = instance.index[id]
- plant.data.stage = stage
- if onServer then
- plant.data.time = os.time()
- MySQL.Async.execute("UPDATE `uteknark1` SET `stage` = @stage WHERE `id` = @id LIMIT 1;", {
- ["@id"] = id,
- ["@stage"] = stage,
- }, function(_)
- TriggerClientEvent("esx_uteknark1:update", -1, id, stage)
- verbose("Set plant", id, "to stage", stage)
- end)
- elseif plant.data.object then
- if DoesEntityExist(plant.data.object) then
- DeleteObject(plant.data.object)
- end
- plant.data.object = nil
- end
- end,
- remove = function(instance, id, withPyro)
- local object = instance.index[id]
- local location = object.bounds.location
- object.data.deleted = true
- if object.node then
- -- NOTE: In rare cases the node is being re-assigned while a remove is happening.
- -- This cases `node` to be nil here, crashing the script.
- -- Technically this is a memory leak because the object will then exist in the reflowed node.
- -- It's not a real problem, however, as it's exceedingly rare and not even a whole kilobyte.
- -- The object will still get deleted, and is not propagated to clients, so it's just a data ghost.
- object.node:remove(object.oindex)
- end
- instance.index[id] = nil
- if onServer then
- MySQL.Async.execute("DELETE FROM `uteknark1` WHERE `id` = @id LIMIT 1;", { ["@id"] = id }, function()
- TriggerClientEvent("esx_uteknark1:removePlant", -1, id)
- if withPyro then
- TriggerClientEvent("esx_uteknark1:pyromaniac", -1, location)
- end
- verbose("Removed plant", id)
- end)
- else
- if object.data.object then
- if DoesEntityExist(object.data.object) then
- DeleteObject(object.data.object)
- end
- object.data.object = nil
- end
- end
- end,
- bulkData = function(instance, target)
- if onServer then
- verbose("Preparing bulk plant data for player", target)
- target = target or -1
- while not instance.loaded do
- Wait(1000)
- end
- local forest = {}
- for id, plant in pairs(instance.index) do
- if type(id) == "number" then -- Because there is a key called `hashtable`!
- table.insert(forest, { id = id, location = plant.bounds.location, stage = plant.data.stage })
- end
- end
- TriggerClientEvent("esx_uteknark1:bulk_data", target, forest)
- else
- TriggerServerEvent("esx_uteknark1:request_data")
- end
- end,
-}
-
-local cropstateMeta = {
- __newindex = function()
- -- Do I even need this?
- end,
- __index = function(instance, key)
- return instance._methods[key]
- end,
-}
-
-cropstate = {
- index = {
- hashtable = true, -- To *force* lua to make it a hashtable rather than an array.
- },
- octree = pOctree(vector3(0, 1500, 0), vector3(12000, 13000, 2000)),
- loaded = false,
- _methods = cropstateMethods,
-}
-
-setmetatable(cropstate, cropstateMeta)
-
-if onServer then
- RegisterNetEvent("esx_uteknark1:request_data")
- AddEventHandler("esx_uteknark1:request_data", function()
- cropstate:bulkData(source)
- end)
-
- RegisterNetEvent("esx_uteknark1:remove")
- AddEventHandler("esx_uteknark1:remove", function(plantID, nearLocation)
- local src = source
- local plant = cropstate.index[plantID]
- if plant then
- local plantLocation = plant.bounds.location
- local distance = #(nearLocation - plantLocation)
- if distance <= Config.Distance.Interact then
- cropstate:remove(plantID, true)
- makeToast(src, _U("interact_text"), _U("interact_destroyed"))
- doScenario(src, "Destroy", plantLocation)
- else
- Citizen.Trace(GetPlayerName(src) .. " (" .. src .. ") is too far away from " .. plantID .. " to remove it (" .. distance("m)\n"))
- end
- else
- Citizen.Trace(GetPlayerName(src) .. " (" .. src .. ") tried to remove plant " .. plantID .. ": That plant does not exist!\n")
- TriggerClientEvent("esx_uteknark1:remove", src, plantID)
- end
- end)
-
- RegisterNetEvent("esx_uteknark1:frob")
- AddEventHandler("esx_uteknark1:frob", function(plantID, nearLocation)
- local src = source
- local plant = cropstate.index[plantID]
- if plant then
- local plantLocation = plant.bounds.location
- local distance = #(nearLocation - plantLocation)
- if distance <= Config.Distance.Interact then
- local stageData = Growth[plant.data.stage]
- if stageData.interact then
- if stageData.yield then
- local yield = math.random(Config.Yield[1], Config.Yield[2])
- local seeds = math.random(Config.YieldSeed[1], Config.YieldSeed[2])
- if GiveItem(src, Config.Items.Product, yield) then
- cropstate:remove(plantID)
- doScenario(src, "Frob", plantLocation)
- if seeds > 0 and GiveItem(src, Config.Items.Seed, seeds) then
- makeToast(src, _U("interact_text"), _U("interact_harvested", yield, seeds))
- else
- makeToast(src, _U("interact_text"), _U("interact_harvested", yield, 0))
- end
- else
- makeToast(src, _U("interact_text"), _U("interact_full", yield))
- end
- else
- if #Growth > plant.data.stage then
- if not Config.Items.Tend or TakeItem(src, Config.Items.Tend) then
- makeToast(src, _U("interact_text"), _U("interact_tended"))
- cropstate:update(plantID, plant.data.stage + 1)
- doScenario(src, "Frob", plantLocation)
- else
- makeToast(src, _U("interact_text"), _U("interact_missing_item"))
- end
- end
- end
- else
- Citizen.Trace(GetPlayerName(src) .. " (" .. src .. ") tried to frob plant " .. plantID .. ": That plant is in a non-frobbable stage!\n")
- end
- else
- Citizen.Trace(GetPlayerName(src) .. " (" .. src .. ") is too far away from " .. plantID .. " to frob it (" .. distance("m)\n"))
- end
- else
- Citizen.Trace(GetPlayerName(src) .. " (" .. src .. ") tried to frob plant " .. plantID .. ": That plant does not exist!\n")
- end
- end)
-else
- RegisterNetEvent("esx_uteknark1:bulk_data")
- AddEventHandler("esx_uteknark1:bulk_data", function(forest)
- for _, plant in ipairs(forest) do
- cropstate:import(plant.id, plant.location, plant.stage)
- end
- cropstate.loaded = true
- end)
-
- RegisterNetEvent("esx_uteknark1:planted")
- AddEventHandler("esx_uteknark1:planted", function(id, location, stage)
- cropstate:import(id, location, stage)
- end)
-
- RegisterNetEvent("esx_uteknark1:update")
- AddEventHandler("esx_uteknark1:update", function(plantID, stage)
- cropstate:update(plantID, stage)
- end)
-
- RegisterNetEvent("esx_uteknark1:removePlant")
- AddEventHandler("esx_uteknark1:removePlant", function(plantID)
- cropstate:remove(plantID)
- end)
-end
diff --git a/server-data/resources/[esx_addons]/esx_uteknark1/lib/debug.lua b/server-data/resources/[esx_addons]/esx_uteknark1/lib/debug.lua
deleted file mode 100644
index 84a4d4904..000000000
--- a/server-data/resources/[esx_addons]/esx_uteknark1/lib/debug.lua
+++ /dev/null
@@ -1,103 +0,0 @@
-local ENABLED = false
-local table = table
-
-local function drawDebugLine(instance, line)
- BeginTextCommandDisplayText("STRING")
- SetTextCentre(false)
- SetTextJustification(1)
- SetTextScale(instance.scale, instance.scale)
- SetTextFont(instance.font)
- SetTextOutline()
- AddTextComponentSubstringPlayerName(line)
- DrawText(instance.x, instance.y)
- instance.y = instance.y + instance.lineHeight
-end
-
-local debugMethods = {
- add = function(instance, ...)
- local numElements = select("#", ...)
- local elements = { ... }
- local line = ""
- for i = 1, numElements do
- local element = tostring(elements[i])
- if i ~= 1 then
- line = line .. " "
- end
- line = line .. element
- end
- table.insert(instance.buffer, line)
- while #instance.buffer > 25 do
- table.remove(instance.buffer, 1)
- end
- end,
- flush = function(instance)
- if instance.active then
- drawDebugLine(instance, instance.header)
- for _, debugEntry in ipairs(instance.buffer) do
- drawDebugLine(instance, debugEntry)
- end
-
- instance.y = instance.reset
- end
- instance.buffer = {}
- end,
-}
-
-local debugMeta = {
- __call = function(instance, ...)
- instance:add(...)
- end,
- __newindex = function()
- -- Just drop. Ignore. Go away.
- end,
- __index = function(instance, key)
- return instance._methods[key]
- end,
-}
-
-debug = {
- active = ENABLED,
- header = "~y~[Debugging " .. GetCurrentResourceName() .. "]",
- x = 0.02,
- y = 0.33,
- reset = 0.33,
- lineHeight = 0.015,
- font = 0,
- scale = 0.25,
- spacing = 0.2,
- buffer = {},
- _methods = debugMethods,
-}
-setmetatable(debug, debugMeta)
-
-function DebugSphere(where, scale, r, g, b, a)
- scale = scale or 1.0
- r = r or 255
- b = b or 255
- g = g or 255
- a = a or 128
- DrawMarker(
- 28, -- type
- where, -- location
- 0.0,
- 0.0,
- 0.0, -- direction (?)
- 0.0,
- 0.0,
- 0.0, -- rotation
- scale,
- scale,
- scale, -- scale
- r,
- g,
- b,
- a, -- color
- false, -- bob
- false, -- face camera
- 2, -- dunno, lol, 100% cargo cult
- false, -- rotates
- 0,
- 0, -- texture
- false -- Projects/draws on entities
- )
-end
diff --git a/server-data/resources/[esx_addons]/esx_uteknark1/lib/growth.lua b/server-data/resources/[esx_addons]/esx_uteknark1/lib/growth.lua
deleted file mode 100644
index b68d8623e..000000000
--- a/server-data/resources/[esx_addons]/esx_uteknark1/lib/growth.lua
+++ /dev/null
@@ -1,93 +0,0 @@
---[[ PLANT GROWTH STAGES
-
-Each plant starts out at stage 1 and starting consumes
-one Config.Items.Seed immediately, and the first timer starts running.
-Interacting with the plant at this time destroys it.
-
-When the time is up, it progresses to the next stage, which is
-a mode='tend' stage. Interaction at this stage consumes one
-Config.Items.Tend, or is free if the Tend Object is not specified.
-Interaction is possible at any time. Failure to interact before the
-time runs out causes the plant to die.
-
-This continuses for all grow/tend cycles until a mode='yield' cycle
-is arrived at. Interacting with the plant at this time will yield
-between Config.Yield[1] and Config.Yield[2] of Config.Items.Product
-and between Config.YieldSeed[1] and Config.YieldSeed[2] seeds.
-By default this means between 5 and 10 weed_pooch, and between 0
-and 1 weed_seed
-
---]]
-
-local Colors = {
- Growing = { 0, 255, 128, 128 },
- Tend = { 255, 255, 128, 128 },
- Harvest = { 255, 128, 128, 128 },
-}
-
-Growth = {
- { -- 1
- label = "growth_seedling",
- model = `prop_plant_01a`,
- offset = vector3(0, 0, -1),
- time = 1, -- One minute
- marker = {
- offset = vector3(0, 0, 0.05),
- color = Colors.Growing,
- },
- },
- { -- 2
- label = "growth_tend",
- model = `prop_plant_01a`,
- offset = vector3(0, 0, -0.8),
- interact = true,
- time = 20, -- Twenty minutes
- marker = {
- offset = vector3(0, 0, 0.3),
- color = Colors.Tend,
- },
- },
- { -- 3
- label = "growth_growing",
- model = `prop_plant_01a`,
- offset = vector3(0, 0, -0.6),
- time = 480, -- 480 minutes is 8 hours
- marker = {
- offset = vector3(0, 0, 0.55),
- color = Colors.Growing,
- },
- },
- { -- 4
- label = "growth_tend",
- model = `prop_plant_01a`,
- offset = vector3(0, 0, -0.4),
- interact = true,
- time = 960, -- 960 minutes is 16 hours
- marker = {
- offset = vector3(0, 0, 0.8),
- color = Colors.Tend,
- },
- },
- { -- 5
- label = "growth_growing",
- model = `prop_plant_01a`,
- offset = vector3(0, 0, -0.6),
- time = 480, -- 480 minutes is 8 hours
- marker = {
- offset = vector3(0, 0, 1.05),
- color = Colors.Growing,
- },
- },
- { -- 6
- label = "growth_yield",
- model = `prop_plant_01a`,
- offset = vector3(0, 0, 0),
- interact = true,
- yield = true,
- time = 960, -- 960 minutes is 16 hours
- marker = {
- offset = vector3(0, 0, 1.8),
- color = Colors.Harvest,
- },
- },
-}
diff --git a/server-data/resources/[esx_addons]/esx_uteknark1/lib/octree.lua b/server-data/resources/[esx_addons]/esx_uteknark1/lib/octree.lua
deleted file mode 100644
index e9305bbf8..000000000
--- a/server-data/resources/[esx_addons]/esx_uteknark1/lib/octree.lua
+++ /dev/null
@@ -1,390 +0,0 @@
-local table = table
-local vector3 = vector3
-local AXIS = { "x", "y", "z" }
-local MAX_OBJECTS = 5
-local MAX_LEVELS = 50
-
-local function intersects(box, item)
- local intersect = { x = false, y = false, z = false }
- ---[[
- for _, axis in ipairs(AXIS) do
- if item.max[axis] > box.min[axis] and item.min[axis] < box.max[axis] then
- intersect[axis] = true
- end
- end
- return intersect.x and intersect.y and intersect.z, intersect
-end
-
-function canFit(box, item)
- local fit = { x = false, y = false, z = false }
- for _, axis in ipairs(AXIS) do
- if item.max[axis] <= box.max[axis] and item.min[axis] >= box.min[axis] then
- fit[axis] = true
- end
- end
- return fit.x and fit.y and fit.z, fit
-end
-
-local function crossProduct(A, B)
- return vector3(
- A.y * B.z - A.z * B.y, -- X
- A.z * B.x - A.x * B.z, -- Y
- A.x * B.y - A.y * B.x -- Z
- )
-end
-
-local function dotProduct(A, B)
- return A.x * B.x + A.y * B.y + A.z * B.z
-end
-
-local function modulus(A)
- return math.sqrt(dotProduct(A, A))
-end
-
-local function lineDistance(A, B, C)
- local AB = B - A
- local AC = C - A
- local modab = modulus(AB)
-
- local dotProductACAB = dotProduct(AC, AB)
- if dotProductACAB <= 0.0 then
- return modulus(AC) --,0.0
- end
-
- local BC = C - B
- local dotProductBCAB = dotProduct(BC, AB)
- if dotProductBCAB >= 0.0 then
- return modulus(BC) --,1.0
- end
-
- local cpabac = crossProduct(AB, AC)
- local modcpabac = modulus(cpabac)
- return modcpabac / modab
-end
-
-function pointInside(box, point)
- local inside = { x = false, y = false, z = false }
- for _, axis in ipairs(AXIS) do
- if point[axis] >= box.min[axis] and point[axis] <= box.max[axis] then
- inside[axis] = true
- end
- end
- return inside.x and inside.y and inside.z, inside
-end
-
-local boundsMeta = {
- __newindex = function()
- -- Drop. Ignore. Go away.
- end,
- __index = function(instance, key)
- return instance._methods[key]
- end,
-}
-local boundsMethods = {
- volume = function(instance)
- local width = instance.max.x - instance.min.x
- local breadth = intance.max.y - instance.min.y
- local height = instance.max.z - instance.min.z
- return width * breadth * height
- end,
- canFit = function(instance, location, dimensions)
- if getmetatable(location) == boundsMeta then
- return canFit(instance, location)
- else
- local _ = pBoxBounds(location, dimensions)
- return canFit(instance, location)
- end
- end,
- intersects = function(instance, location, dimensions)
- if getmetatable(location) == boundsMeta then
- return intersects(instance, location)
- else
- local item = pBoxBounds(location, dimensions)
- return intersects(instance, item)
- end
- end,
- inside = function(instance, point)
- if #(instance.location - point) <= instance.radius then
- return pointInside(instance, point)
- end
- return false
- end,
- draw = function(instance, r, g, b, a)
- r = r or 255
- g = g or 0
- b = b or 0
- a = a or 128
- -- Upper layer
- DrawLine(instance.max.x, instance.max.y, instance.max.z, instance.min.x, instance.max.y, instance.max.z, r, g, b, a)
- DrawLine(instance.min.x, instance.max.y, instance.max.z, instance.min.x, instance.min.y, instance.max.z, r, g, b, a)
- DrawLine(instance.min.x, instance.min.y, instance.max.z, instance.max.x, instance.min.y, instance.max.z, r, g, b, a)
- DrawLine(instance.max.x, instance.min.y, instance.max.z, instance.max.x, instance.max.y, instance.max.z, r, g, b, a)
-
- -- Lower layer
- DrawLine(instance.max.x, instance.max.y, instance.min.z, instance.min.x, instance.max.y, instance.min.z, r, g, b, a)
- DrawLine(instance.min.x, instance.max.y, instance.min.z, instance.min.x, instance.min.y, instance.min.z, r, g, b, a)
- DrawLine(instance.min.x, instance.min.y, instance.min.z, instance.max.x, instance.min.y, instance.min.z, r, g, b, a)
- DrawLine(instance.max.x, instance.min.y, instance.min.z, instance.max.x, instance.max.y, instance.min.z, r, g, b, a)
-
- -- Connectors
- DrawLine(instance.max.x, instance.max.y, instance.max.z, instance.max.x, instance.max.y, instance.min.z, r, g, b, a)
- DrawLine(instance.min.x, instance.max.y, instance.max.z, instance.min.x, instance.max.y, instance.min.z, r, g, b, a)
- DrawLine(instance.min.x, instance.min.y, instance.max.z, instance.min.x, instance.min.y, instance.min.z, r, g, b, a)
- DrawLine(instance.max.x, instance.min.y, instance.max.z, instance.max.x, instance.min.y, instance.min.z, r, g, b, a)
- --DrawBox(instance.min,instance.max,r,g,b,math.floor(a/2))
- end,
-}
-
-function pBoxBounds(location, dimensions)
- if type(dimensions) == "number" then -- Assume it's a cube
- dimensions = vector3(dimensions, dimensions, dimensions)
- end
- local half = dimensions / 2
- local bounds = {
- location = location,
- dimensions = dimensions,
- max = vector3(location.x + half.x, location.y + half.y, location.z + half.z),
- min = vector3(location.x - half.x, location.y - half.y, location.z - half.z),
- _methods = boundsMethods,
- }
- bounds.radius = #(bounds.max - bounds.min) / 2
- return setmetatable(bounds, boundsMeta)
-end
-
-local nodeMethods = {
- canFit = function(instance, location, dimensions)
- local box = instance.bounds
- if getmetatable(location) == boundsMeta then
- return canFit(box, location)
- end
- local item = pBoxBounds(location, dimensions)
- return canFit(box, item)
- end,
- intersects = function(instance, location, dimensions)
- local box = instance.bounds
- if getmetatable(location) == boundsMeta then
- return intersects(box, location)
- end
- local item = pBoxBounds(location, dimensions)
- return intersects(box, item)
- end,
- selectNode = function(instance, item)
- if instance._data.nodes then
- for _, node in ipairs(instance._data.nodes) do
- if node:canFit(item) then
- return node
- end
- end
- end
- end,
- split = function(instance)
- if not instance._data.nodes then
- --pPushText('Splitting '..instance.level..' ('..GetGameTimer()..')')
- instance._data.nodes = {}
- local dim = instance._data.bounds.dimensions
- local pos = instance._data.bounds.location
- local quarter = dim / 4
- local half = dim / 2
- local nextLevel = instance._data.level + 1
- table.insert(instance._data.nodes, pOctree(vector3(pos.x + quarter.x, pos.y + quarter.x, pos.z + quarter.z), half, nextLevel))
- table.insert(instance._data.nodes, pOctree(vector3(pos.x - quarter.x, pos.y + quarter.x, pos.z + quarter.z), half, nextLevel))
- table.insert(instance._data.nodes, pOctree(vector3(pos.x + quarter.x, pos.y - quarter.x, pos.z + quarter.z), half, nextLevel))
- table.insert(instance._data.nodes, pOctree(vector3(pos.x - quarter.x, pos.y - quarter.x, pos.z + quarter.z), half, nextLevel))
-
- table.insert(instance._data.nodes, pOctree(vector3(pos.x + quarter.x, pos.y + quarter.x, pos.z - quarter.z), half, nextLevel))
- table.insert(instance._data.nodes, pOctree(vector3(pos.x - quarter.x, pos.y + quarter.x, pos.z - quarter.z), half, nextLevel))
- table.insert(instance._data.nodes, pOctree(vector3(pos.x + quarter.x, pos.y - quarter.x, pos.z - quarter.z), half, nextLevel))
- table.insert(instance._data.nodes, pOctree(vector3(pos.x - quarter.x, pos.y - quarter.x, pos.z - quarter.z), half, nextLevel))
- end
- end,
- insert = function(instance, location, dimensions, data)
- data = data or {}
- if type(location) ~= "vector3" then
- error("First argument to :insert must be a vector3 for location, got " .. tyoe(location), 2)
- end
- if type(dimensions) == "number" then -- Presume cube
- dimensions = vector3(dimensions, dimensions, dimensions)
- elseif type(dimensions) ~= "vector3" then
- error("Second argument to :insert must be either a number (if cube) or a vector3 for dimetions, got " .. type(dimensions), 2)
- end
- local object = {
- data = data,
- bounds = pBoxBounds(location, dimensions),
- }
- if instance:canFit(object.bounds) then
- local node = instance:selectNode(object.bounds)
- if node then
- return node:insert(location, dimensions, data)
- end
-
- object.node = instance
- object.oindex = #instance._data.objects + 1
- table.insert(instance._data.objects, object)
- completeSuccess = true
-
- if #instance._data.objects > MAX_OBJECTS and instance._data.level < MAX_LEVELS then
- local limboObjects = instance._data.objects
- instance._data.objects = {}
- if not instance._data.nodes then
- instance:split()
- end
- for _, lobject in ipairs(limboObjects) do
- local newNode = instance:selectNode(lobject.bounds)
- if newNode then
- if not newNode:insert(lobject.bounds.location, lobject.bounds.dimensions, lobject.data) then
- completeSuccess = false
- end
- else
- lobject.oindex = #instance._data.objects + 1
- table.insert(instance._data.objects, lobject)
- end
- end
- end
- return completeSuccess, object
- else
- error("Object inserted by :insert does not fit in node at level " .. instance._data.level, 2)
- end
- end,
- remove = function(instance, index)
- if instance._data.objects[index] then
- local removed = instance._data.objects[index]
- removed.node = nil
- removed.oindex = nil
- table.remove(instance._data.objects, index)
- for i, object in ipairs(instance._data.objects) do
- object.oindex = i
- end
- return removed
- end
- end,
- all = function(instance, funcref)
- if type(funcref) == "function" then
- for _, item in ipairs(instance._data.objects) do
- funcref(item)
- end
- if instance._data.nodes then
- for _, node in ipairs(instance._data.nodes) do
- node:all(funcref)
- end
- end
- end
- end,
- searchBox = function(instance, location, dimensions, hits)
- hits = hits or {}
- local searchBox
- dimensions = dimensions or vector3(1, 1, 1)
- if getmetatable(location) == boundsMeta then
- searchBox = location
- else
- searchBox = pBoxBounds(location, dimensions)
- end
- if instance._data.bounds:intersects(searchBox) then
- for _, object in ipairs(instance._data.objects) do
- if object.bounds:intersects(searchBox) then
- table.insert(hits, object)
- end
- end
- if instance._data.nodes then
- for _, node in ipairs(instance._data.nodes) do
- node:searchBox(searchBox, dimensions, hits)
- end
- end
- end
- return hits
- end,
- searchSphereAsync = function(instance, location, radius, callback, slowMode)
- CreateThread(function()
- local distance = #(location - instance._data.bounds.location)
- if distance <= radius + instance._data.bounds.radius then
- for _, object in pairs(instance._data.objects) do
- local objectDistance = #(location - object.bounds.location)
- if objectDistance <= radius + object.bounds.radius then
- callback(object)
- end
- end
- if instance._data.nodes then
- for _, node in ipairs(instance._data.nodes) do
- if slowMode then
- Wait(0)
- end
- node:searchSphereAsync(location, radius, callback, slowMode)
- end
- end
- end
- end)
- end,
- searchSphere = function(instance, location, radius, hits)
- hits = hits or {}
- local distance = #(location - instance._data.bounds.location)
- if distance <= radius + instance._data.bounds.radius then
- for _, object in pairs(instance._data.objects) do
- local objectDistance = #(location - object.bounds.location)
- if objectDistance <= radius + object.bounds.radius then
- table.insert(hits, object)
- end
- end
- if instance._data.nodes then
- for _, node in ipairs(instance._data.nodes) do
- node:searchSphere(location, radius, hits)
- end
- end
- end
- return hits
- end,
- searchRay = function(instance, from, to, thickness, hits)
- thickness = thickness or 0
- hits = hits or {}
- local distance = lineDistance(from, to, instance._data.bounds.location)
- local intersectRange = thickness + instance._data.bounds.radius
- if distance <= intersectRange then
- for _, object in ipairs(instance._data.objects) do
- local objDistance = lineDistance(from, to, object.bounds.location)
- local objIntersectRange = thickness + object.bounds.radius
- if objDistance <= objIntersectRange then
- table.insert(hits, object)
- end
- end
- if instance._data.nodes then
- for _, node in ipairs(instance._data.nodes) do
- node:searchRay(from, to, thickness, hits)
- end
- end
- end
- return hits
- end,
-}
-local octreeNodeMeta = {
- __index = function(instance, key)
- if instance._methods[key] then
- return instance._methods[key]
- else
- return instance._data[key]
- end
- end,
- __newindex = function(instance, key, value)
- if instance._data[key] then
- instance._data[key] = value
- end
- end,
-}
-local function newNode(location, dimensions, level)
- level = level or 0
- if type(dimensions) == "number" then -- Presume it's a cube
- dimensions = vector3(dimensions, dimensions, dimensions)
- end
- local new = {
- _data = {
- location = location or vector3(0, 0, 0),
- dimensions = dimensions or vector3(1, 1, 1),
- objects = {},
- level = level,
- },
- _methods = nodeMethods,
- }
- new._data.bounds = pBoxBounds(new._data.location, new._data.dimensions)
- return setmetatable(new, octreeNodeMeta)
-end
-
-function pOctree(location, dimensions, startLevel)
- return newNode(location, dimensions, startLevel)
-end
diff --git a/server-data/resources/[esx_addons]/esx_uteknark1/locales/cz.lua b/server-data/resources/[esx_addons]/esx_uteknark1/locales/cz.lua
deleted file mode 100644
index e21ef7bad..000000000
--- a/server-data/resources/[esx_addons]/esx_uteknark1/locales/cz.lua
+++ /dev/null
@@ -1,27 +0,0 @@
-Locales["cz"] = {
- planting_text = "Zasazuji",
- planting_ok = "Uspesne zasazena",
- planting_in_vehicle = "Nemuzes zasazovat roslitu v aute.",
- planting_too_steep = "Příliš strmí terén",
- planting_too_far = "Musite trochu dal od sebe sázet.",
- planting_not_suitable_soil = "Na tomto terene vase rostlina nevyroste",
- planting_too_close = "Rostlina potrebuje vice prostoru",
- planting_obstructed = "Najdete misto, kde je vice slunce.",
- planting_no_seed = "Nemate zadne sazenice",
- planting_failed = "~r~Nejaky problem nastal pri sazeni",
- planting_too_fast = "Zasazuje prilis rychle za sebou",
- status_active = "Faze ~1~/~1~~n~~INPUT_PICKUP~ ~a~~n~~INPUT_COVER~ Znicení",
- status_passive = "Faze ~1~/~1~~n~~a~~n~~INPUT_COVER~ Znicit",
- growth_seedling = "Momentalne zasazena~n~Bude potrebovat sklidit brzo.",
- growth_tend = "Zahnojit rostlinu",
- growth_growing = "Rostlina si vede, a roste v poradku.",
- growth_yield = "Sklidit",
- command_invalid = "Invakudbá: %s",
- command_empty = "Verze %s",
- interact_text = "Interakce",
- interact_tended = "Rostlina zahnojena",
- interact_destroyed = "Rostlina znicena",
- interact_harvested = "Roslitna sklidena: %i finalni produkt, %i seminka",
- interact_full = "Nemuzes toho vic unest",
- interact_missing_item = "Chybi ti něco vice.",
-}
diff --git a/server-data/resources/[esx_addons]/esx_uteknark1/locales/it.lua b/server-data/resources/[esx_addons]/esx_uteknark1/locales/it.lua
deleted file mode 100644
index a2a62d14f..000000000
--- a/server-data/resources/[esx_addons]/esx_uteknark1/locales/it.lua
+++ /dev/null
@@ -1,27 +0,0 @@
-Locales["it"] = {
- planting_text = "piantare",
- planting_ok = "semina riuscita!",
- planting_in_vehicle = "Gettare i semi dalla finestra, o cosa?",
- planting_too_steep = "Troppo ripido!",
- planting_too_far = "Un po' più vicino, forse?",
- planting_not_suitable_soil = "Crescerà troppo male qui.",
- planting_too_close = "Troppo vicino a un'altra pianta!",
- planting_obstructed = "Trova un posto con più luce",
- planting_no_seed = "Non hai semi",
- planting_failed = "~r~Figli..! È successo qualcosa di brutto durante la semina!",
- planting_too_fast = "rilassati, aspetta!",
- status_active = "in crescita ~1~/~1~~n~~INPUT_PICKUP~ ~a~~n~~INPUT_COVER~ Distruggere",
- status_passive = "in crescita ~1~/~1~~n~~a~~n~~INPUT_COVER~ Distruggere",
- growth_seedling = "Piantato di recente.~n~Necessita di cure rapide!",
- growth_tend = "Prenditi cura della pianta",
- growth_growing = "Crescere e sta bene.",
- growth_yield = "Raccolto",
- command_invalid = "comando non valido: %s",
- command_empty = "Versione %s",
- interact_text = "Interazione delle piante",
- interact_tended = "Pianta curata",
- interact_destroyed = "pianta distrutta",
- interact_harvested = "Pianta raccolta: %i erba, %i semi",
- interact_full = "Non hai spazio per %i altra erba!",
- interact_missing_item = "Non hai ciò di cui hai bisogno per prenderti cura di questa pianta!",
-}
diff --git a/server-data/resources/[esx_addons]/esx_uteknark1/locales/sv.lua b/server-data/resources/[esx_addons]/esx_uteknark1/locales/sv.lua
deleted file mode 100644
index ff14cb3a1..000000000
--- a/server-data/resources/[esx_addons]/esx_uteknark1/locales/sv.lua
+++ /dev/null
@@ -1,27 +0,0 @@
-Locales["sv"] = {
- planting_text = "Plantering",
- planting_ok = "Lyckad plantering!",
- planting_in_vehicle = "Slänga frön ur fönstret, eller vad?",
- planting_too_steep = "För brant, kompis!",
- planting_too_far = "Lite närmre, kanske?",
- planting_not_suitable_soil = "Här kommer det växa för dåligt.",
- planting_too_close = "För nära en annan växt!",
- planting_obstructed = "Hitta någonstans med mera ljus",
- planting_no_seed = "Du har inga frön",
- planting_failed = "~r~Jävlar! Något skit hände under planteringen!",
- planting_too_fast = "Chilla, brorsan! Vänta lite!",
- status_active = "Steg ~1~/~1~~n~~INPUT_PICKUP~ ~a~~n~~INPUT_COVER~ Förstör",
- status_passive = "Steg ~1~/~1~~n~~a~~n~~INPUT_COVER~ Förstör",
- growth_seedling = "Nyligen planterat.~n~Behöver vårtd snart!",
- growth_tend = "Vårda växten",
- growth_growing = "Växer och mår bra.",
- growth_yield = "Skörda",
- command_invalid = "Ogiltigt direktiv: %s",
- command_empty = "Versjon %s",
- interact_text = "Växtinteraktion",
- interact_tended = "Växt vårdad",
- interact_destroyed = "Växt förstörd",
- interact_harvested = "Växt skördad: %i gräs, %i frön",
- interact_full = "Du har inte plats med %i mer gräs!",
- interact_missing_item = "Du har inte det du behöver för att vårda denna växten!",
-}
diff --git a/server-data/resources/[esx_addons]/esx_uteknark1/sv_uteknark.lua b/server-data/resources/[esx_addons]/esx_uteknark1/sv_uteknark.lua
deleted file mode 100644
index bb720a28b..000000000
--- a/server-data/resources/[esx_addons]/esx_uteknark1/sv_uteknark.lua
+++ /dev/null
@@ -1,420 +0,0 @@
-local oneSyncEnabled = GetConvar("onesync_enabled", false)
-local VERBOSE = false
-local lastPlant = {}
-local tickTimes = {}
-local tickPlantCount = 0
-local VERSION = "1.1.4"
-
-AddEventHandler("playerDropped", function()
- lastPlant[source] = nil
-end)
-
-function log(...)
- local numElements = select("#", ...)
- local elements = { ... }
- local line = ""
- local prefix = "[" .. os.date("%H:%M:%S") .. "] "
- suffix = "\n"
- local resourceName = "<" .. GetCurrentResourceName() .. ">"
-
- for i = 1, numElements do
- local entry = elements[i]
- line = line .. " " .. tostring(entry)
- end
- Citizen.Trace(prefix .. resourceName .. line .. suffix)
-end
-
-function verbose(...)
- if VERBOSE then
- log(...)
- end
-end
-
-if not oneSyncEnabled then
- log("OneSync not available: Will have to trust client for locations!")
-end
-
-function HasItem(who, what, count)
- count = count or 1
- if ESX == nil then
- log("HasItem: No ESX Object!")
- return false
- end
- local xPlayer = ESX.GetPlayerFromId(who)
- if xPlayer == nil then
- log("HasItem: Failed to resolve xPlayer from", who)
- return false
- end
- local itemspec = xPlayer.getInventoryItem(what)
- if itemspec then
- if itemspec.count >= count then
- return true
- else
- return false
- end
- else
- log("HasItem: Failed to get item data for item", what)
- return false
- end
-end
-
-function TakeItem(who, what, count)
- count = count or 1
- if ESX == nil then
- log("TakeItem: No ESX Object!")
- return false
- end
- local xPlayer = ESX.GetPlayerFromId(who)
- if xPlayer == nil then
- log("TakeItem: Failed to resolve xPlayer from", who)
- return false
- end
- local itemspec = xPlayer.getInventoryItem(what)
- if itemspec then
- if itemspec.count >= count then
- xPlayer.removeInventoryItem(what, count)
- return true
- else
- return false
- end
- else
- log("TakeItem: Failed to get item data for item", what)
- return false
- end
-end
-
-function GiveItem(who, what, count)
- count = count or 1
- if ESX == nil then
- log("GiveItem: No ESX Object!")
- return false
- end
- local xPlayer = ESX.GetPlayerFromId(who)
- if xPlayer == nil then
- log("GiveItem: Failed to resolve xPlayer from", who)
- return false
- end
- local itemspec = xPlayer.getInventoryItem(what)
- if itemspec then
- if not itemspec.limit or itemspec.limit == -1 or itemspec.count + count <= itemspec.limit then
- xPlayer.addInventoryItem(what, count)
- return true
- else
- return false
- end
- else
- log("GiveItem: Failed to get item data for item", what)
- return false
- end
-end
-
-function makeToast(target, subject, message)
- TriggerClientEvent("esx_uteknark1:make_toast", target, subject, message)
-end
-function inChat(target, message)
- if target == 0 then
- log(message)
- else
- TriggerClientEvent("chat:addMessage", target, { args = { "UteKnark", message } })
- end
-end
-
-function plantSeed(location, soil)
- local hits = cropstate.octree:searchSphere(location, Config.Distance.Space)
- if #hits > 0 then
- return false
- end
-
- verbose("Planting at", location, "in soil", soil)
- cropstate:plant(location, soil)
- return true
-end
-
-function doScenario(who, what, where)
- verbose("Telling", who, "to", what, "at", where)
- TriggerClientEvent("esx_uteknark1:do", who, what, where)
-end
-
-RegisterNetEvent("esx_uteknark1:success_plant")
-AddEventHandler("esx_uteknark1:success_plant", function(location, soil)
- local src = source
- if oneSyncEnabled and false then -- "and false" because something is weird in my OneSync stuff
- local ped = GetPlayerPed(src)
- --log('ped:',ped)
- local pedLocation = GetEntityCoords(ped)
- --log('pedLocation:',pedLocation)
- --log('location:', location)
- local distance = #(pedLocation - location)
- if distance > Config.Distance.Interact then
- if distance > 10 then
- log(GetPlayerName(src), "attempted planting at", distance .. "m - Cheating?")
- end
- makeToast(src, _U("planting_text"), _U("planting_too_far"))
- return
- end
- end
- if soil and Config.Soil[soil] then
- local hits = cropstate.octree:searchSphere(location, Config.Distance.Space)
- if #hits == 0 then
- if TakeItem(src, Config.Items.Seed) then
- if plantSeed(location, soil) then
- makeToast(src, _U("planting_text"), _U("planting_ok"))
- doScenario(src, "Plant", location)
- else
- GiveItem(src, Config.Items.Seed)
- makeToast(src, _U("planting_text"), _U("planting_failed"))
- end
- else
- makeToast(src, _U("planting_text"), _U("planting_no_seed"))
- end
- else
- makeToast(src, _U("planting_text"), _U("planting_too_close"))
- end
- else
- makeToast(src, _U("planting_text"), _U("planting_not_suitable_soil"))
- end
-end)
-
-RegisterNetEvent("esx_uteknark1:log")
-AddEventHandler("esx_uteknark1:log", function(...)
- local src = source
- log(src, GetPlayerName(src), ...)
-end)
-
-RegisterNetEvent("esx_uteknark1:test_forest")
-AddEventHandler("esx_uteknark1:test_forest", function(forest)
- local src = source
-
- if IsPlayerAceAllowed(src, "command.uteknark") then
- local soil
- for candidate, quality in pairs(Config.Soil) do
- soil = candidate
- if quality >= 1.0 then
- break
- end
- end
-
- log(GetPlayerName(src), "(" .. src .. ") is magically planting a forest of", #forest, "plants")
- for i, tree in ipairs(forest) do
- cropstate:plant(tree.location, soil, tree.stage)
- if i % 25 == 0 then
- Wait(0)
- end
- end
- else
- log("OY!", GetPlayerName(src), "with ID", src, "tried to spawn a test forest, BUT IS NOT ALLOWED!")
- end
-end)
-
-function keyCount(tbl)
- local count = 0
- if type(tbl) == "table" then
- for _, value in pairs(tbl) do
- count = count + 1
- end
- end
- return count
-end
-
-CreateThread(function()
- local ESXTries = 60
- local itemsLoaded = false
- while not itemsLoaded and ESXTries > 0 do
- ESX = exports["es_extended"]:getSharedObject()
- if keyCount(ESX.Items) > 0 then
- itemsLoaded = true
- for forWhat, itemName in pairs(Config.Items) do
- if ESX.Items[itemName] then
- log(forWhat, "item in configuration (" .. itemName .. ") found in ESX: Good!")
- else
- log("WARNING:", forWhat, "item in cofiguration (" .. itemName .. ") does not exist!")
- end
- end
- ESX.RegisterUsableItem(Config.Items.Seed, function(source)
- local now = os.time()
- local last = lastPlant[source] or 0
- if now > last + (Config.ActionTime / 1000) then
- if HasItem(source, Config.Items.Seed) then
- TriggerClientEvent("esx_uteknark1:attempt_plant", source)
- lastPlant[source] = now
- else
- makeToast(source, _U("planting_text"), _U("planting_no_seed"))
- end
- else
- makeToast(source, _U("planting_text"), _U("planting_too_fast"))
- end
- end)
- end
- Wait(1000)
- ESXTries = ESXTries - 1
- end
- if not ESX then
- log("CRITICAL ERROR: Could not obtain ESX object!\n")
- end
-end)
-
-CreateThread(function()
- local databaseReady = false
- while not databaseReady do
- Wait(500)
- local state = GetResourceState("mysql-async")
- if state == "started" then
- Wait(500)
- cropstate:load(function(plantCount)
- if plantCount == 1 then
- log("Uteknark loaded a single plant!")
- else
- log("Uteknark loaded", plantCount, "plants")
- end
- end)
- databaseReady = true
- end
- end
-
- while true do
- Wait(0)
- local now = os.time()
- local begin = GetGameTimer()
- local plantsHandled = 0
- for id, plant in pairs(cropstate.index) do
- if type(id) == "number" then -- Because of the whole "hashtable = true" thing
- local stageData = Growth[plant.data.stage]
- local growthTime = (stageData.time * 60 * Config.TimeMultiplier)
- local soilQuality = Config.Soil[plant.data.soil] or 1.0
-
- if stageData.interact then
- local relevantTime = plant.data.time + ((growthTime / soilQuality) * Config.TimeMultiplier)
- if now >= relevantTime then
- verbose("Plant", id, "has died: No interaction in time")
- cropstate:remove(id)
- end
- else
- local relevantTime = plant.data.time + ((growthTime * soilQuality) * Config.TimeMultiplier)
- if now >= relevantTime then
- if plant.data.stage < #Growth then
- verbose("Plant", id, "has grown to stage", plant.data.stage + 1)
- cropstate:update(id, plant.data.stage + 1)
- else
- verbose("Plant", id, "has died: Ran out of stages")
- cropstate:remove(id)
- end
- end
- end
-
- plantsHandled = plantsHandled + 1
- if plantsHandled % 10 == 0 then
- Wait(0)
- end
- end
- end
-
- tickPlantCount = plantsHandled
- local tickTime = GetGameTimer() - begin
- table.insert(tickTimes, tickTime)
- while #tickTimes > 20 do
- table.remove(tickTimes, 1)
- end
- end
-end)
-
-local commands = {
- debug = function(source)
- if source == 0 then
- log("Client debugging on the console? Nope.")
- else
- TriggerClientEvent("esx_uteknark1:toggle_debug", source)
- end
- end,
- stage = function(source, args)
- if args[1] and string.match(args[1], "^%d+$") then
- local plant = tonumber(args[1])
- if cropstate.index[plant] then
- if args[2] and string.match(args[2], "^%d+$") then
- local stage = tonumber(args[2])
- if stage > 0 and stage <= #Growth then
- log(source, GetPlayerName(source), "set plant", plant, "to stage", stage)
- cropstate:update(plant, stage)
- else
- inChat(source, string.format("%i is an invalid stage", stage))
- end
- else
- inChat(source, "What stage?")
- end
- else
- inChat(source, string.format("Plant %i does not exist!", plant))
- end
- else
- inChat(source, "What plant, you say?")
- end
- end,
- forest = function(source, args)
- if source == 0 then
- log("Forests can't grow in a console, buddy!")
- else
- local count = #Growth * #Growth
- if args[1] and string.match(args[1], "%d+$") then
- count = tonumber(args[1])
- end
-
- local randomStage = false
- if args[2] then
- randomStage = true
- end
-
- TriggerClientEvent("esx_uteknark1:test_forest", source, count, randomStage)
- end
- end,
- stats = function(source)
- if cropstate.loaded then
- local totalTime = 0
- for _, time in ipairs(tickTimes) do
- totalTime = totalTime + time
- end
- local tickTimeAverage = totalTime / #tickTimes
- inChat(source, string.format("Tick time average: %.1fms", tickTimeAverage))
- inChat(source, string.format("Plant count: %i", tickPlantCount))
- else
- inChat(source, "Not loaded yet")
- end
- end,
- groundmat = function(source)
- if source == 0 then
- log("Console. The ground material is CONSOLE.")
- else
- TriggerClientEvent("esx_uteknark1:groundmat", source)
- end
- end,
- pyro = function(source)
- if source == 0 then
- log("You can't really test particle effects on the console.")
- else
- TriggerClientEvent("esx_uteknark1:pyromaniac", source)
- end
- end,
-}
-
-RegisterCommand("uteknark", function(source, args)
- if #args > 0 then
- local directive = string.lower(args[1])
- if commands[directive] then
- if #args > 1 then
- local newArgs = {}
- for i, entry in ipairs(args) do
- if i > 1 then
- table.insert(newArgs, entry)
- end
- end
- args = newArgs
- else
- args = {}
- end
- commands[directive](source, args)
- elseif source == 0 then
- log("Invalid directive: " .. directive)
- else
- inChat(source, _U("command_invalid", directive))
- end
- else
- inChat(source, _U("command_empty", VERSION))
- end
-end, true)