├── LICENSE ├── README.md ├── client └── main.lua ├── config ├── config.lua └── translations.lua ├── fxmanifest.lua └── server └── main.lua /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![217894339-62bf504a-ed86-4989-85a9-dfc18c3cafa0 (1)](https://user-images.githubusercontent.com/55330408/218249938-77209084-6464-468e-9fce-d2c30a275862.png) 2 | 3 | # CScripts Garden Cleaner 4 | 5 | For all support questions, ask in our [Discord](https://discord.gg/2kcXW3gRzg) support chat. 6 | 7 | ## Dependencies 8 | 9 | - [QBCore](https://github.com/qbcore-framework/qb-core) or [ESX](https://github.com/esx-framework/esx_core) 10 | - [oxmysql](https://github.com/overextended/oxmysql) 11 | - Any third eye script 12 | 13 | # Installation 14 | * Download ZIP 15 | * Drag and drop resource into your server files 16 | * Start resource through server.cfg 17 | * Restart your server. 18 | 19 | # Preview 20 | www.youtube.com/watch?v=baBViNtHwUM 21 | -------------------------------------------------------------------------------- /client/main.lua: -------------------------------------------------------------------------------- 1 | local HasJobStarted = false 2 | local HasJob = true 3 | local SetRandomLocation 4 | local CarParked = false 5 | local POINTS_DONE_IN_JOB = 0 6 | local haveBinBag = false 7 | local JobsToDo 8 | local NumberToDo = 0 9 | local geeky 10 | local PropsBlips = {} 11 | local ClothesOn = false 12 | local blip 13 | local QBCore = nil 14 | local ESX = nil 15 | local blipSY 16 | local Player 17 | 18 | if GetFrameWork() == 'ESX' then 19 | ESX = exports['es_extended']:getSharedObject() 20 | elseif GetFrameWork() == 'QBCORE' then 21 | QBCore = exports['qb-core']:GetCoreObject() 22 | end 23 | 24 | Citizen.CreateThread(function() 25 | SpawnStartingPed() 26 | local Blip_Name = Config.Languages[Config.Lang]["BLIP_NAME"] 27 | blip = AddBlipForCoord(Config.Job.StartJob.Coords.x, Config.Job.StartJob.Coords.y, Config.Job.StartJob.Coords.z) 28 | SetBlipSprite(blip, Config.Job.StartJob.blip.SetBlipSprite) 29 | SetBlipDisplay(blip, Config.Job.StartJob.blip.SetBlipDisplay) 30 | SetBlipScale(blip, Config.Job.StartJob.blip.SetBlipScale) 31 | SetBlipColour(blip, Config.Job.StartJob.blip.SetBlipColour ) 32 | SetBlipAsShortRange(blip, Config.Job.StartJob.blip.SetBlipAsShortRange ) 33 | BeginTextCommandSetBlipName("STRING") 34 | AddTextComponentString(Blip_Name) 35 | EndTextCommandSetBlipName(blip) 36 | end) 37 | 38 | --MAIN CODE-- 39 | 40 | CreateThread(function() 41 | while true do 42 | Citizen.Wait(1000) 43 | if not Config.Jobs then 44 | HasJob = true 45 | elseif GetFrameWork() == "ESX" and ESX.GetPlayerData().job.name == Config.Jobs then 46 | HasJob = true 47 | elseif GetFrameWork() == "QBCORE" and QBCore.Functions.GetPlayerData().job.name == Config.Jobs then 48 | HasJob = true 49 | else 50 | HasJob = false 51 | end 52 | end 53 | end) 54 | 55 | CreateThread(function() 56 | while true do 57 | sleep = 1000 58 | 59 | if HasJob and HasJobStarted then 60 | sleep = 0 61 | -- JOB UPDATES -- 62 | JobsToDo = #Config.JobWork[SetRandomLocation].BinBags + #Config.JobWork[SetRandomLocation].Charvest + #Config.JobWork[SetRandomLocation].LeafBlower 63 | NumberToDo = JobsToDo-POINTS_DONE_IN_JOB 64 | print(JobsToDo) 65 | print(Config.JobWork[SetRandomLocation].PayForOnePoint) 66 | -- END OF JOB UPDATES -- 67 | 68 | local playerCoords = GetEntityCoords(PlayerPedId()) 69 | local distance = #(playerCoords - Config.Job.CarControl.Coords) 70 | if distance < Config.Job.CarControl.DrawDistance+1 and IsPedInAnyVehicle(PlayerPedId()) then 71 | if distance < Config.Job.CarControl.DrawDistance-2 then 72 | DrawMarker(23, Config.Job.CarControl.Coords, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 3.5, 3.5, 3.0, 136, 8, 8, 100, false, true, 2, false, nil, nil, false) 73 | DrawText3Ds(Config.Job.CarControl.Coords, Config.Languages[Config.Lang]["TAKE_IN_CAR"]) 74 | if IsControlJustReleased(0,46) then 75 | local vehicle = GetVehiclePedIsIn(PlayerPedId(), false) 76 | DeleteVehicle(vehicle) 77 | DeleteWaypoint(); 78 | if NumberToDo == 0 then 79 | Notify(Config.Languages[Config.Lang]["JOB_FINISH_GIVE_ME_THE_FUCKING_MONEY"]..''..tonumber(JobsToDo)*tonumber(Config.JobWork[SetRandomLocation].PayForOnePoint)) 80 | TriggerServerEvent("cs_gardencleaner:givemoney", JobsToDo, SetRandomLocation) 81 | end 82 | CarParked = false 83 | HasJobStarted = false 84 | SetRandomLocation = nil 85 | POINTS_DONE_IN_JOB = 0 86 | haveBinBag = false 87 | JobsToDo = 0 88 | NumberToDo = 0 89 | geeky = nil 90 | 91 | if Config.SpawnBack then 92 | SetEntityCoords(GetPlayerPed(-1), Config.Job.StartJob.Coords.x, Config.Job.StartJob.Coords.y, Config.Job.StartJob.Coords.z, false, false, false, true) 93 | end 94 | end 95 | else 96 | DrawMarker(23, Config.Job.CarControl.Coords, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 3.5, 3.5, 3.0, 255, 255, 255, 100, false, true, 2, false, nil, nil, false) 97 | end 98 | else 99 | sleep = 1500 100 | end 101 | end 102 | Citizen.Wait(sleep) 103 | end 104 | end) 105 | 106 | CreateThread(function() 107 | while true do 108 | sleep = 1000 109 | if HasJob and HasJobStarted then 110 | sleep = 0 111 | local playerCoords = GetEntityCoords(PlayerPedId()) 112 | local distance = #(playerCoords - Config.JobWork[SetRandomLocation].ParkCarAt) 113 | if distance < Config.Job.CarControl.DrawDistance+1 and IsPedInAnyVehicle(PlayerPedId()) and not CarParked then 114 | if distance < Config.Job.CarControl.DrawDistance-2 then 115 | DrawMarker(23, Config.JobWork[SetRandomLocation].ParkCarAt, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 3.5, 3.5, 3.0, 136, 8, 8, 100, false, true, 2, false, nil, nil, false) 116 | DrawText3Ds(Config.JobWork[SetRandomLocation].ParkCarAt, Config.Languages[Config.Lang]["PARK_THE_CAR"]) 117 | if IsControlJustReleased(0,46) then 118 | Notify(Config.Languages[Config.Lang]["TALK_MIKE_INPLACE"]) 119 | CarParked = true 120 | SpawnCharvest() 121 | SpawnBinBags() 122 | SpawnLeafs() 123 | RemoveBlip(blipSY) 124 | end 125 | else 126 | DrawMarker(23, Config.JobWork[SetRandomLocation].ParkCarAt, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 3.5, 3.5, 3.0, 255, 255, 255, 100, false, true, 2, false, nil, nil, false) 127 | end 128 | else 129 | sleep = 1500 130 | end 131 | end 132 | Citizen.Wait(sleep) 133 | end 134 | end) 135 | 136 | RegisterNetEvent('cs_gardencleaner:startjob') 137 | AddEventHandler('cs_gardencleaner:startjob', function() 138 | if HasJobStarted and not CarParked then 139 | HasJobStarted = false 140 | SetRandomLocation = nil 141 | CarParked = false 142 | POINTS_DONE_IN_JOB = 0 143 | haveBinBag = false 144 | JobsToDo = 0 145 | NumberToDo = 0 146 | geeky = nil 147 | RemoveBlip(blipSY) 148 | elseif not HasJobStarted then 149 | HasJobStarted = true 150 | local RandomLocal = math.random(1,#Config.JobWork) 151 | SpawnCar() 152 | SetNewWaypoint(Config.JobWork[RandomLocal].ParkCarAt.x, Config.JobWork[RandomLocal].ParkCarAt.y); 153 | SetRandomLocation = RandomLocal 154 | Notify(Config.Languages[Config.Lang]["TALK_MIKE_GOTOPLACE"]) 155 | local Blip_Name = Config.Languages[Config.Lang]["BLIP_HOUSE"] 156 | blipSY = AddBlipForCoord(Config.JobWork[SetRandomLocation].ParkCarAt.x, Config.JobWork[SetRandomLocation].ParkCarAt.y, Config.JobWork[SetRandomLocation].ParkCarAt.z) 157 | SetBlipSprite(blipSY, Config.JobWork[SetRandomLocation].Blip.SetBlipSprite) 158 | SetBlipDisplay(blipSY, Config.JobWork[SetRandomLocation].Blip.SetBlipDisplay) 159 | SetBlipScale(blipSY, Config.JobWork[SetRandomLocation].Blip.SetBlipScale) 160 | SetBlipColour(blipSY, Config.JobWork[SetRandomLocation].Blip.SetBlipColour ) 161 | SetBlipAsShortRange(blipSY, Config.JobWork[SetRandomLocation].Blip.SetBlipAsShortRange ) 162 | BeginTextCommandSetBlipName("STRING") 163 | AddTextComponentString(Blip_Name) 164 | EndTextCommandSetBlipName(blipSY) 165 | else 166 | Notify(Config.Languages[Config.Lang]["INFO_FIRST_FINISH_JOB"]) 167 | end 168 | end) 169 | 170 | RegisterNetEvent('cs_gardencleaner:charvest') 171 | AddEventHandler('cs_gardencleaner:charvest', function(data) 172 | ClearPedTasks(GetPlayerPed(-1)) 173 | TaskStartScenarioInPlace(GetPlayerPed(-1), "world_human_gardener_plant", 0, true) 174 | Citizen.Wait(5000) 175 | DeleteEntity(data.entity) 176 | ClearPedTasks(GetPlayerPed(-1)) 177 | POINTS_DONE_IN_JOB = POINTS_DONE_IN_JOB+1 178 | Notify(Config.Languages[Config.Lang]["INFO_DONE"]..' '..POINTS_DONE_IN_JOB.."/"..JobsToDo) 179 | RemoveBlip(PropsBlips[data.entity]) 180 | if NumberToDo == 0 then 181 | Notify(Config.Languages[Config.Lang]["INFO_DONE_JOB"]..''..JobsToDo*Config.JobWork[SetRandomLocation].PayForOnePoint) 182 | end 183 | end) 184 | 185 | RegisterNetEvent('cs_gardencleaner:LeafBlower') 186 | AddEventHandler('cs_gardencleaner:LeafBlower', function(data) 187 | ClearPedTasks(GetPlayerPed(-1)) 188 | TaskStartScenarioInPlace(GetPlayerPed(-1), "WORLD_HUMAN_GARDENER_LEAF_BLOWER", 0, true) 189 | FreezeEntityPosition(GetPlayerPed(-1), true); 190 | Wait(17000) 191 | DeleteEntity(data.entity) 192 | ClearPedTasks(GetPlayerPed(-1)) 193 | FreezeEntityPosition(GetPlayerPed(-1), false); 194 | ClearAreaOfObjects(GetEntityCoords(GetPlayerPed(-1)), 2.0, 0) 195 | POINTS_DONE_IN_JOB = POINTS_DONE_IN_JOB+1 196 | Notify(Config.Languages[Config.Lang]["INFO_DONE"]..' '..POINTS_DONE_IN_JOB.."/"..JobsToDo) 197 | RemoveBlip(PropsBlips[data.entity]) 198 | if NumberToDo == 0 then 199 | Notify(Config.Languages[Config.Lang]["INFO_DONE_JOB"]..''..JobsToDo*Config.JobWork[SetRandomLocation].PayForOnePoint) 200 | end 201 | end) 202 | 203 | RegisterNetEvent('cs_gardencleaner:collecttrash') 204 | AddEventHandler('cs_gardencleaner:collecttrash', function(data) 205 | ClearPedTasks(GetPlayerPed(-1)) 206 | 207 | if not HasAnimDictLoaded("anim@move_m@trash") then 208 | RequestAnimDict("anim@move_m@trash") 209 | end 210 | while not HasAnimDictLoaded("anim@move_m@trash") do 211 | Citizen.Wait(0) 212 | end 213 | 214 | TaskPlayAnim(GetPlayerPed(-1), 'anim@move_m@trash', 'pickup', 1.0, -1.0,-1,2,0,0, 0,0) 215 | Citizen.Wait(1000) 216 | DeleteEntity(data.entity) 217 | ClearPedTasks(GetPlayerPed(-1)) 218 | haveBinBag = true 219 | RemoveBlip(PropsBlips[data.entity]) 220 | if not HasAnimDictLoaded("anim@heists@narcotics@trash") then 221 | RequestAnimDict("anim@heists@narcotics@trash") 222 | end 223 | while not HasAnimDictLoaded("anim@heists@narcotics@trash") do 224 | Citizen.Wait(0) 225 | end 226 | local boneindex = GetPedBoneIndex(PlayerPedId(-1), 57005) 227 | geeky = CreateObject(GetHashKey("hei_prop_heist_binbag"), 0, 0, 0, true, true, true) 228 | AttachEntityToEntity(geeky, PlayerPedId(-1), boneindex, 0.12, 0.0, 0.00, 25.0, 270.0, 180.0, true, true, false, true, 1, true) 229 | TaskPlayAnim(PlayerPedId(-1), 'anim@heists@narcotics@trash', 'walk', 1.0, -1.0,-1,49,0,0, 0,0) 230 | TriggerEvent("mt:missiontext", Config.Languages[Config.Lang]["INFO_BIN"]) 231 | end) 232 | 233 | RegisterNetEvent('cs_gardencleaner:bin') 234 | AddEventHandler('cs_gardencleaner:bin', function(data) 235 | haveBinBag = false 236 | POINTS_DONE_IN_JOB = POINTS_DONE_IN_JOB+1 237 | ClearPedTasksImmediately(GetPlayerPed(-1)) 238 | TaskPlayAnim(GetPlayerPed(-1), 'anim@heists@narcotics@trash', 'throw_b', 1.0, -1.0,-1,2,0,0, 0,0) 239 | Citizen.Wait(700) 240 | DeleteObject(geeky) 241 | Citizen.Wait(2000) 242 | ClearPedTasksImmediately(GetPlayerPed(-1)) 243 | Notify(Config.Languages[Config.Lang]["INFO_DONE"]..' '..POINTS_DONE_IN_JOB.."/"..JobsToDo) 244 | if NumberToDo == 0 then 245 | Notify(Config.Languages[Config.Lang]["INFO_DONE_JOB"]..''..JobsToDo*Config.JobWork[SetRandomLocation].PayForOnePoint) 246 | end 247 | end) 248 | 249 | RegisterNetEvent("mt:missiontext") 250 | AddEventHandler("mt:missiontext", function(text) 251 | ClearPrints() 252 | SetTextEntry_2("STRING") 253 | AddTextComponentString(text) 254 | DrawSubtitleTimed(5000, 1) 255 | end) 256 | 257 | RegisterNetEvent("cs_gardencleaner:putonclothes") 258 | AddEventHandler("cs_gardencleaner:putonclothes", function() 259 | if ClothesOn then 260 | ChangeClothes() 261 | else 262 | ChangeClothes('work') 263 | end 264 | end) 265 | 266 | 267 | --- FUNCTIONS --- 268 | function SpawnStartingPed() 269 | local model = Config.Job.StartJob.Ped 270 | RequestModel(model) 271 | while not HasModelLoaded(model) do 272 | Citizen.Wait(50) 273 | end 274 | spawnedPed = CreatePed(0, model, Config.Job.StartJob.Coords.x, Config.Job.StartJob.Coords.y, Config.Job.StartJob.Coords.z, Config.Job.StartJob.Coords.w, false, true) 275 | FreezeEntityPosition(spawnedPed, true) 276 | SetBlockingOfNonTemporaryEvents(spawnedPed, true) 277 | SetEntityInvincible(spawnedPed, true) 278 | 279 | exports[Config.TargetName]:AddTargetModel({GetHashKey('prop_dumpster_01a'), GetHashKey('prop_dumpster_02b'), GetHashKey('prop_dumpster_02a'), GetHashKey('prop_bin_08a')}, { 280 | options = { 281 | { 282 | event = "cs_gardencleaner:bin", 283 | icon = Config.StartJobEmote, 284 | label = Config.Languages[Config.Lang]["TARGET_PUTINBIN"], 285 | canInteract = function(entity) 286 | if haveBinBag then 287 | return true 288 | end 289 | return false 290 | end 291 | }, 292 | }, 293 | distance = 2.5 294 | }) 295 | 296 | if not Config.job then 297 | exports[Config.TargetName]:AddTargetEntity(spawnedPed, { 298 | options = { 299 | { 300 | event = "cs_gardencleaner:startjob", 301 | icon = Config.StartJobEmote, 302 | label = Config.Languages[Config.Lang]["TARGET_STARTJOB"], 303 | }, 304 | { 305 | event = "cs_gardencleaner:putonclothes", 306 | icon = Config.ClothesJobEmote, 307 | label = Config.Languages[Config.Lang]["TARGET_PUTONCLOTHES"], 308 | }, 309 | }, 310 | distance = 2.5 311 | }) 312 | else 313 | exports[Config.TargetName]:AddTargetEntity(spawnedPed, { 314 | options = { 315 | { 316 | event = "cs_gardencleaner:startjob", 317 | icon = Config.StartJobEmote, 318 | label = Config.Languages[Config.Lang]["TARGET_STARTJOB"], 319 | job = Config.Job 320 | }, 321 | { 322 | event = "cs_gardencleaner:putonclothes", 323 | icon = Config.ClothesJobEmote, 324 | label = Config.Languages[Config.Lang]["TARGET_PUTONCLOTHES"], 325 | job = Config.Job 326 | }, 327 | }, 328 | distance = 2.5 329 | }) 330 | end 331 | end 332 | 333 | function SpawnCar() 334 | if GetFrameWork() == 'ESX' then 335 | ESX.Game.SpawnVehicle(Config.JobCar, Config.Job.CarControl.Coords, Config.Job.CarControl.heading, function(callback_vehicle) 336 | SetVehicleFixed(callback_vehicle) 337 | SetVehicleDeformationFixed(callback_vehicle) 338 | SetVehicleEngineOn(callback_vehicle, true, true) 339 | SetCarFuel(callback_vehicle) 340 | TaskWarpPedIntoVehicle(GetPlayerPed(-1), callback_vehicle, -1) 341 | end) 342 | elseif GetFrameWork() == 'QBCORE' and not Config.FixCarSpawnQB then 343 | QBCore.Functions.TriggerCallback('QBCore:Server:SpawnVehicle', function(netId) 344 | local veh = NetToVeh(netId) 345 | SetEntityHeading(veh, Config.Job.CarControl.heading) 346 | SetVehicleFixed(veh) 347 | SetVehicleDeformationFixed(veh) 348 | SetVehicleEngineOn(veh, true, true) 349 | SetCarFuel(veh) 350 | TaskWarpPedIntoVehicle(GetPlayerPed(-1), veh, -1) 351 | TriggerEvent("vehiclekeys:client:SetOwner", QBCore.Functions.GetPlate(veh)) 352 | end, Config.JobCar, Config.Job.CarControl.Coords, true) 353 | elseif GetFrameWork() == 'QBCORE' and Config.FixCarSpawnQB then 354 | QBCore.Functions.SpawnVehicle(Config.JobCar, function(veh) 355 | SetEntityHeading(veh, Config.Job.CarControl.heading) 356 | SetVehicleFixed(veh) 357 | SetVehicleDeformationFixed(veh) 358 | SetVehicleEngineOn(veh, true, true) 359 | SetCarFuel(veh) 360 | TaskWarpPedIntoVehicle(GetPlayerPed(-1), veh, -1) 361 | TriggerEvent("vehiclekeys:client:SetOwner", QBCore.Functions.GetPlate(veh)) 362 | SetVehicleEngineOn(veh, true, true) 363 | end, Config.Job.CarControl.Coords, true) 364 | end 365 | end 366 | 367 | function DrawText3Ds(coords, text) 368 | local onScreen,_x,_y=World3dToScreen2d(coords.x,coords.y,coords.z) 369 | local px,py,pz=table.unpack(GetGameplayCamCoords()) 370 | SetTextScale(0.32, 0.32) 371 | SetTextFont(4) 372 | SetTextProportional(1) 373 | SetTextColour(255, 255, 255, 255) 374 | SetTextEntry("STRING") 375 | SetTextCentre(1) 376 | AddTextComponentString(text) 377 | DrawText(_x,_y) 378 | local factor = (string.len(text)) / 500 379 | DrawRect(_x,_y+0.0125, 0.030+ factor, 0.03, 0, 0, 0, 150) 380 | end 381 | 382 | function SpawnLeafs() 383 | local playerPos = GetEntityCoords(GetPlayerPed(-1), true) 384 | for i=1, #Config.JobWork[SetRandomLocation].LeafBlower do 385 | local model = GetHashKey('prop_veg_crop_04_leaf') 386 | RequestModel(model) 387 | while (not HasModelLoaded(model)) do 388 | Wait(1) 389 | end 390 | local p = CreateObject(model, Config.JobWork[SetRandomLocation].LeafBlower[i].x, Config.JobWork[SetRandomLocation].LeafBlower[i].y, Config.JobWork[SetRandomLocation].LeafBlower[i].z-1.80, true, true, true) 391 | SetModelAsNoLongerNeeded(model) 392 | SetEntityAsMissionEntity(p, true, true); 393 | FreezeEntityPosition(p, true) 394 | SetEntityInvincible(p, true) 395 | 396 | PropsBlips[p] = AddBlipForCoord(Config.JobWork[SetRandomLocation].LeafBlower[i].x, Config.JobWork[SetRandomLocation].LeafBlower[i].y, Config.JobWork[SetRandomLocation].LeafBlower[i].z) 397 | SetBlipSprite(PropsBlips[p], 1) 398 | SetBlipDisplay(PropsBlips[p], 4) 399 | SetBlipScale(PropsBlips[p], 0.4) 400 | SetBlipColour(PropsBlips[p], 5) 401 | SetBlipAsShortRange(PropsBlips[p], true) 402 | BeginTextCommandSetBlipName("STRING") 403 | AddTextComponentString('LeafBlower') 404 | EndTextCommandSetBlipName(PropsBlips[p]) 405 | 406 | exports[Config.TargetName]:AddTargetEntity(p, { 407 | options = { 408 | { 409 | event = "cs_gardencleaner:LeafBlower", 410 | icon = Config.StartJobEmote, 411 | label = Config.Languages[Config.Lang]["TARGET_START_LEAFS"], 412 | canInteract = function(entity) 413 | if not haveBinBag and HasJobStarted then 414 | return true 415 | end 416 | return false 417 | end 418 | }, 419 | }, 420 | distance = 2.5 421 | }) 422 | end 423 | end 424 | function SpawnCharvest() 425 | local playerPos = GetEntityCoords(GetPlayerPed(-1), true) 426 | for i=1, #Config.JobWork[SetRandomLocation].Charvest do 427 | local model = GetHashKey('prop_plant_01b') 428 | RequestModel(model) 429 | while (not HasModelLoaded(model)) do 430 | Wait(1) 431 | end 432 | local p = CreateObject(model, Config.JobWork[SetRandomLocation].Charvest[i].x, Config.JobWork[SetRandomLocation].Charvest[i].y, Config.JobWork[SetRandomLocation].Charvest[i].z-1.30, true, true, true) 433 | SetModelAsNoLongerNeeded(model) 434 | SetEntityAsMissionEntity(p, true, true); 435 | FreezeEntityPosition(p, true) 436 | SetEntityInvincible(p, true) 437 | 438 | PropsBlips[p] = AddBlipForCoord(Config.JobWork[SetRandomLocation].Charvest[i].x, Config.JobWork[SetRandomLocation].Charvest[i].y, Config.JobWork[SetRandomLocation].Charvest[i].z) 439 | SetBlipSprite(PropsBlips[p], 1) 440 | SetBlipDisplay(PropsBlips[p], 4) 441 | SetBlipScale(PropsBlips[p], 0.4) 442 | SetBlipColour(PropsBlips[p], 5) 443 | SetBlipAsShortRange(PropsBlips[p], true) 444 | BeginTextCommandSetBlipName("STRING") 445 | AddTextComponentString('Charvest') 446 | EndTextCommandSetBlipName(PropsBlips[p]) 447 | 448 | exports[Config.TargetName]:AddTargetEntity(p, { 449 | options = { 450 | { 451 | event = "cs_gardencleaner:charvest", 452 | icon = Config.StartJobEmote, 453 | label = Config.Languages[Config.Lang]["TARGET_START_CHARVEST"], 454 | canInteract = function(entity) 455 | if not haveBinBag and HasJobStarted then 456 | return true 457 | end 458 | return false 459 | end 460 | }, 461 | }, 462 | distance = 2.5 463 | }) 464 | end 465 | end 466 | function SpawnBinBags() 467 | local playerPos = GetEntityCoords(GetPlayerPed(-1), true) 468 | for i=1, #Config.JobWork[SetRandomLocation].BinBags do 469 | local model = GetHashKey('prop_rub_binbag_sd_02') 470 | RequestModel(model) 471 | while (not HasModelLoaded(model)) do 472 | Wait(1) 473 | end 474 | local p = CreateObject(model, Config.JobWork[SetRandomLocation].BinBags[i].x, Config.JobWork[SetRandomLocation].BinBags[i].y, Config.JobWork[SetRandomLocation].BinBags[i].z-0.99, true, true, true) 475 | SetModelAsNoLongerNeeded(model) 476 | FreezeEntityPosition(p, true) 477 | SetEntityAsMissionEntity(p, true, true); 478 | SetEntityInvincible(p, true) 479 | 480 | PropsBlips[p] = AddBlipForCoord(Config.JobWork[SetRandomLocation].BinBags[i].x, Config.JobWork[SetRandomLocation].BinBags[i].y, Config.JobWork[SetRandomLocation].BinBags[i].z) 481 | SetBlipSprite(PropsBlips[p], 1) 482 | SetBlipDisplay(PropsBlips[p], 4) 483 | SetBlipScale(PropsBlips[p], 0.4) 484 | SetBlipColour(PropsBlips[p], 5) 485 | SetBlipAsShortRange(PropsBlips[p], true) 486 | BeginTextCommandSetBlipName("STRING") 487 | AddTextComponentString('Bin Bag') 488 | EndTextCommandSetBlipName(PropsBlips[p]) 489 | 490 | exports[Config.TargetName]:AddTargetEntity(p, { 491 | options = { 492 | { 493 | event = "cs_gardencleaner:collecttrash", 494 | icon = Config.StartJobEmote, 495 | label = Config.Languages[Config.Lang]["TARGET_START_BINBAGS"], 496 | canInteract = function(entity) 497 | if not haveBinBag and HasJobStarted then 498 | return true 499 | end 500 | return false 501 | end 502 | }, 503 | }, 504 | distance = 2.5 505 | }) 506 | end 507 | end 508 | 509 | function ChangeClothes(type) 510 | if type == "work" then 511 | local gender 512 | if GetFrameWork() == 'ESX' then 513 | TriggerEvent('skinchanger:getSkin', function(skin) 514 | gender = skin.sex 515 | end) 516 | elseif GetFrameWork() == 'QBCORE' then 517 | local Player = QBCore.Functions.GetPlayerData() 518 | gender = Player.charinfo.gender 519 | end 520 | local PlayerPed = PlayerPedId() 521 | ClothesOn = true 522 | if gender == 0 then 523 | for k,v in pairs(Config.Clothes.male.components) do 524 | SetPedComponentVariation(PlayerPed, v["component_id"], v["drawable"], v["texture"], 0) 525 | end 526 | else 527 | for k,v in pairs(Config.Clothes.female.components) do 528 | SetPedComponentVariation(PlayerPed, v["component_id"], v["drawable"], v["texture"], 0) 529 | end 530 | end 531 | else 532 | ClothesOn = false 533 | if GetFrameWork() == 'ESX' then 534 | ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin) 535 | TriggerEvent('skinchanger:loadSkin', skin) 536 | end) 537 | elseif GetFrameWork() == 'QBCORE' then 538 | TriggerServerEvent('qb-clothes:loadPlayerSkin') 539 | end 540 | end 541 | end 542 | -------------------------------------------------------------------------------- /config/config.lua: -------------------------------------------------------------------------------- 1 | Config = {} 2 | 3 | Config.Lang = 'en' 4 | Config.FrameWork = 'QBCORE' -- Only supports ESX and QBCORE 5 | Config.Jobs = false -- Put false for no job lock 6 | Config.FixCarSpawnQB = false -- Set this to true if car is not spawning 7 | Config.SpawnBack = true -- Spawns player next to the ped when gives back the car 8 | 9 | --- Vehicle --- 10 | Config.UsingFuel = false 11 | Config.JobCar = 'speedo4' 12 | 13 | --- TARGET --- 14 | Config.TargetName = 'qtarget' 15 | Config.StartJobEmote = 'fa-solid fa-handshake-simple' 16 | Config.ClothesJobEmote = 'fa-solid fa-shirt' 17 | 18 | --- JOB SETTINGS --- 19 | Config.PaymentType = "cash" --Name of payment type like `Bank, Cash, Money and etc` [ONLY FOR QBCORE] 20 | Config.Job = { 21 | StartJob = { -- Ped Location 22 | Coords = vector4(-1087.1871, -1277.4829, 5.8424-0.99, 207.8397), 23 | Ped = 'a_f_m_bevhills_02', 24 | blip = { 25 | SetBlipSprite = 354, 26 | SetBlipDisplay = 4, 27 | SetBlipScale = 0.8, 28 | SetBlipColour = 5, 29 | SetBlipAsShortRange = true, 30 | } 31 | }, 32 | CarControl = { --Spawn/Detete Car 33 | Coords = vector3(-1109.0658, -1291.9574, 5.3421-0.89), 34 | heading = 207.2277, 35 | DrawDistance = 4.0 36 | } 37 | } 38 | 39 | Config.Clothes = { 40 | male = { 41 | components = {{["component_id"] = 0, ["texture"] = 0, ["drawable"] = 0},{["component_id"] = 1, ["texture"] = 0, ["drawable"] = 0},{["component_id"] = 3, ["texture"] = 0, ["drawable"] = 30},{["component_id"] = 4, ["texture"] = 0, ["drawable"] = 36},{["component_id"] = 5, ["texture"] = 0, ["drawable"] = 0},{["component_id"] = 6, ["texture"] = 1, ["drawable"] = 56},{["component_id"] = 7, ["texture"] = 0, ["drawable"] = 0},{["component_id"] = 8, ["texture"] = 1, ["drawable"] = 59},{["component_id"] = 9, ["texture"] = 0, ["drawable"] = 0},{["component_id"] = 10, ["texture"] = 0, ["drawable"] = 0},{["component_id"] = 11, ["texture"] = 0, ["drawable"] = 56},}, 42 | }, 43 | female = { 44 | components = {{["component_id"] = 0, ["texture"] = 0, ["drawable"] = 0},{["component_id"] = 1, ["texture"] = 0, ["drawable"] = 0},{["component_id"] = 3, ["texture"] = 0, ["drawable"] = 57},{["component_id"] = 4, ["texture"] = 0, ["drawable"] = 35},{["component_id"] = 5, ["texture"] = 0, ["drawable"] = 0},{["component_id"] = 6, ["texture"] = 1, ["drawable"] = 59},{["component_id"] = 7, ["texture"] = 0, ["drawable"] = 0},{["component_id"] = 8, ["texture"] = 1, ["drawable"] = 36},{["component_id"] = 9, ["texture"] = 0, ["drawable"] = 0},{["component_id"] = 10, ["texture"] = 0, ["drawable"] = 0},{["component_id"] = 11, ["texture"] = 1, ["drawable"] = 49},}, 45 | } 46 | } 47 | 48 | Config.JobWork = { 49 | [1] = { 50 | PayForOnePoint = '1', 51 | ParkCarAt = vector3(-1603.0819, -364.4330, 45.6417-0.99), 52 | Blip = { 53 | SetBlipSprite = 354, 54 | SetBlipDisplay = 4, 55 | SetBlipScale = 0.8, 56 | SetBlipColour = 5, 57 | SetBlipAsShortRange = true, 58 | }, 59 | BinBags = { 60 | [1] = vector3(-1604.6487, -344.0188, 49.2116), 61 | [2] = vector3(-1605.6732, -345.4971, 49.2128), 62 | }, 63 | Charvest = { 64 | [1] = vector3(-1606.8596, -371.7873, 46.4499), 65 | [2] = vector3(-1608.4360, -370.1949, 46.4269), 66 | }, 67 | LeafBlower = { 68 | [1] = vector3(-1606.19, -342.46, 49.21), 69 | [2] = vector3(-1606.98, -333.51, 49.22), 70 | }, 71 | }, 72 | } 73 | 74 | --- FUNCTIONS --- 75 | function GetFrameWork() 76 | return Config.FrameWork 77 | end 78 | 79 | local QBCore = nil 80 | local ESX = nil 81 | if GetFrameWork() == 'ESX' then 82 | Citizen.CreateThread(function() 83 | while ESX == nil do 84 | TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) 85 | Citizen.Wait(0) 86 | end 87 | end) 88 | elseif GetFrameWork() == 'QBCORE' then 89 | QBCore = exports['qb-core']:GetCoreObject() 90 | end 91 | function SetCarFuel(callback_vehicle) 92 | if Config.UsingFuel then 93 | exports['LegacyFuel']:SetFuel(callback_vehicle, '100') 94 | end 95 | end 96 | function Notify(message) 97 | if GetFrameWork() == 'ESX' then 98 | ESX.ShowNotification(message, false, false, w) 99 | elseif GetFrameWork() == 'QBCORE' then 100 | QBCore.Functions.Notify(message, "primary") 101 | end 102 | end 103 | -------------------------------------------------------------------------------- /config/translations.lua: -------------------------------------------------------------------------------- 1 | --████████╗██████╗░░█████╗░███╗░░██╗░██████╗██╗░░░░░░█████╗░████████╗██╗░█████╗░███╗░░██╗░██████╗ 2 | --╚══██╔══╝██╔══██╗██╔══██╗████╗░██║██╔════╝██║░░░░░██╔══██╗╚══██╔══╝██║██╔══██╗████╗░██║██╔════╝ 3 | --░░░██║░░░██████╔╝███████║██╔██╗██║╚█████╗░██║░░░░░███████║░░░██║░░░██║██║░░██║██╔██╗██║╚█████╗░ 4 | --░░░██║░░░██╔══██╗██╔══██║██║╚████║░╚═══██╗██║░░░░░██╔══██║░░░██║░░░██║██║░░██║██║╚████║░╚═══██╗ 5 | --░░░██║░░░██║░░██║██║░░██║██║░╚███║██████╔╝███████╗██║░░██║░░░██║░░░██║╚█████╔╝██║░╚███║██████╔╝ 6 | --░░░╚═╝░░░╚═╝░░╚═╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝░░░╚═╝░░░╚═╝░╚════╝░╚═╝░░╚══╝╚═════╝░ 7 | 8 | Config.Languages = { --You can modify your language or even create new languages ​​here. 9 | ['en'] = { 10 | ["BLIP_NAME"] = "Garden Cleaner Job", 11 | ["BLIP_HOUSE"] = "House To Clean", 12 | ["TARGET_STARTJOB"] = "Start/Finish Job", 13 | ["TARGET_PUTONCLOTHES"] = "Put clothes on", 14 | ["TAKE_OUT_CAR"] = "[E] To take out a car", 15 | ["TAKE_IN_CAR"] = "[E] To give the car back", 16 | ["PARK_THE_CAR"] = "[E] To park the car", 17 | ["TARGET_START_CHARVEST"] = "Pull out the plants", 18 | ["TARGET_START_BINBAGS"] = "Pick up the bin bags", 19 | ["TARGET_PUTINBIN"] = "Put bag in the bin", 20 | ["TARGET_START_LEAFS"] = "Blow the leafs away", 21 | ["INFO_DONE"] = "Done: ", 22 | ["INFO_FIRST_FINISH_JOB"] = "To stop the job you have to finish it!", 23 | ["INFO_BIN"] = "Find the near bin and throw it away", 24 | ["INFO_DONE_JOB"] = "Job done! Go back to your car and drive back to the company", 25 | ["JOB_FINISH_GIVE_ME_THE_FUCKING_MONEY"] = "You earned: $", 26 | -- TALK -- 27 | ['TALK_MIKE_GOTOPLACE'] = "[Mike] Hey, go to the palce marked on your map, there i will tell you more", 28 | ['TALK_MIKE_INPLACE'] = "[Mike] Oh you there now! Go to the yellow markers and interact with them!", 29 | } 30 | } -------------------------------------------------------------------------------- /fxmanifest.lua: -------------------------------------------------------------------------------- 1 | fx_version 'adamant' 2 | game 'gta5' 3 | lua54 'yes' 4 | version '1.0.2' 5 | 6 | server_scripts({ 7 | 'config/config.lua', 8 | 'server/main.lua', 9 | 'config/translations.lua', 10 | }) 11 | 12 | client_scripts({ 13 | 'config/config.lua', 14 | 'client/main.lua', 15 | 'config/translations.lua', 16 | }) -------------------------------------------------------------------------------- /server/main.lua: -------------------------------------------------------------------------------- 1 | local QBCore = nil 2 | local ESX = nil 3 | 4 | if GetFrameWork() == 'ESX' then 5 | ESX = exports['es_extended']:getSharedObject() 6 | elseif GetFrameWork() == 'QBCORE' then 7 | QBCore = exports['qb-core']:GetCoreObject() 8 | end 9 | 10 | RegisterNetEvent('cs_gardencleaner:givemoney') 11 | AddEventHandler('cs_gardencleaner:givemoney', function(JobsToDo, SetRandomLocation) 12 | if GetFrameWork() == 'ESX' then 13 | local xPlayer = ESX.GetPlayerFromId(source) 14 | xPlayer.addMoney(JobsToDo*Config.JobWork[SetRandomLocation].PayForOnePoint) 15 | elseif GetFrameWork() == 'QBCORE' then 16 | local Player = QBCore.Functions.GetPlayer(source) 17 | Player.Functions.AddMoney(Config.PaymentType, JobsToDo*Config.JobWork[SetRandomLocation].PayForOnePoint) 18 | end 19 | end) 20 | --------------------------------------------------------------------------------