Animal Control Job Script
Ever wanted to bring some order to the wild side of Los Santos? With the Animal Control Job, players can now step into the boots of an animal control officer! This engaging and highly customizable script lets players capture stray animals across a variety of locations. Whether itโs a coyote in the desert or a stray cat in an urban area, this script provides a fun experience for roleplay servers.
Get it here: gamzkystore.com
Support: Discord
Preview video:
Key features
- Begin your animal control journey by interacting with the NPC at the Animal Ark in Sandy Shores.
- Diverse animal types including boars, cats, coyotes, dogs (various breeds), and hens, each spawn in unique habitats.
- Reward system with configurable payouts for capturing and delivering animals.
- Gameplay involving bait placement to lure animals, capturing them with crates, and transporting them in vehicles.
- Rentable job vehicles with a deposit system and multiple spawn points, returnable upon job completion.
- Realistic props for bait and animal crates.
- Fail-safe mechanics that cancel the job if animals die, disappear, or the player abandons the vehicle.
- Customizable localization for all messages and dialogues.
- Player-friendly features like tracking blips for animals and instructions throughout the job process.
- Protection against cheaters by tracking and validating the progress server-sided.
- Synchronizes with other players.
Resmon
Idle: 0.00ms - When near animal: 0.02ms
How it works
- Start the job: Interact with the NPC to begin your job.
- Rent a vehicle: Pay a deposit and receive your job vehicle.
- Locate the animal: Go to the designated zone and and locate the animal.
- Distract the animal: Use bait to distract the animal before capturing it.
- Capture and return: Secure the animal in a crate and transport it back safely.
- Complete the task: Return the vehicle and receive your reward.
The script is made for ESX and QBCore, but thanks to the bridge functions you can easily adapt this to any other framework!
Config file
Config = {
start = {
blip = {
sprite = 141,
color = 26,
scale = 1.2,
label = 'Animal Control Job',
},
ped = {
coords = vector4(562.26, 2741.43, 41.87, 186.60),
model = `a_m_y_beachvesp_01`,
scenario = 'WORLD_HUMAN_CLIPBOARD',
voiceName = 'S_M_M_TRUCKER_01_WHITE_FULL_01',
greetLines = { 'GENERIC_HI', 'GENERIC_HOWS_IT_GOING' },
failedLines = { 'GENERIC_WHATEVER' },
}
},
animal = {
entityBlip = true, -- If true, a blip will be created for the animal entity so its easier to track down the animal.
blip = {
sprite = 141,
color = 26,
scale = 1.0,
label = 'Animal Control Job',
},
},
vehicle = {
depositMoney = 1000, -- The amount of money the player has to deposit to rent the vehicle. Set to 0 to disable.
model = `bison`, -- The model of the job vehicle.
deliverPoint = vector3(561.09, 2727.07, 41.60), -- The coordinates where the player will deliver the vehicle after the job is done.
warpPlayer = true, -- Warp player into vehicle when spawning
spawnPoints = {
vector4(559.65, 2719.41, 41.60, 3.15),
vector4(562.70, 2719.88, 41.60, 3.43),
vector4(565.76, 2720.20, 41.60, 5.01),
vector4(568.86, 2720.27, 41.60, 4.13),
vector4(571.89, 2720.40, 41.60, 4.09),
vector4(574.98, 2720.91, 41.60, 4.85),
vector4(578.06, 2720.86, 41.60, 1.81),
vector4(581.14, 2721.12, 41.60, 3.97),
vector4(584.40, 2721.39, 41.60, 3.63),
}
},
crate = {
model = `sf_prop_sf_crate_animal_01a`, -- The model of the animal crate.
position = vector3(-0.15, 0.6, 0.0),
rotation = vector3(0.0, 90.0, -30.0),
attachBone = 24818, -- The bone to attach the crate to.
freezeWhenDropped = true, -- If the crate should be frozen when dropped.
disabledKeys = { -- The keys which are disabled when holding the crate.
21, -- Sprint
23, -- Enter vehicle
24, -- Attack
25, -- Aim
},
},
}
Config.Animals = {
['boar'] = {
modelHash = `a_c_boar`,
label = 'Boar',
habitats = { 'countryside', 'forest' }, -- The habitats the animal can be found in
reward = 5000, -- The reward the player will receive for catching and returning the animal
baitModel = `apa_mp_h_acc_fruitbowl_02`, -- The model used for the bait prop
lureDistance = 5.0, -- Distance the animal will detect the bait
requiresBait = true, -- If true, players can only catch the animal if they are distracted by a bait
},
['cat'] = {
modelHash = `a_c_cat_01`,
label = 'Cat',
habitats = { 'urban', 'residential' },
reward = 5000,
baitModel = `v_ret_247_tuna`,
lureDistance = 7.5,
requiresBait = true,
},
-- Rest of animals left out for readability... (There are 13 animals in total)
}
Config.Dialogues = {
['boar'] = {
start = {
'A boar is loose in [zone]. It has wandered out of its habitat.',
'Use food as bait to distract it and make the capture easier.'
},
approach = 'The boar is nearby. Stay calm and use bait to keep it occupied.',
capture = 'You secured the boar! Bring it back safely for relocation.',
completion = 'The boar is back where it belongs. Great job on this task!'
},
['cat'] = {
start = {
'A cat is roaming in [zone]. It may have wandered far from home.',
'Cats are cautious. Use food to gain its trust and lure it closer.'
},
approach = 'The cat is watching you. Use bait to distract it.',
capture = 'You secured the cat! Bring it back to base for care.',
completion = 'The cat is safe back at base. Well done!'
},
-- Rest of dialogues left out for readability...
}
Config.Animations = {
['place'] = {
dict = 'pickup_object',
anim = 'putdown_low',
time = 1000,
},
['pickup'] = {
dict = 'random@domestic',
anim = 'pickup_low',
time = 1000,
},
}
Config.Habitats = {
-- Urban Area
['urban'] = {
label = 'Urban Area',
zones = {
{ coords = vector3(220.00, -803.00, 30.72), size = 50.0 },
{ coords = vector3(-300.01, -899.99, 31.08), size = 40.0 },
}
},
-- Residential Area
['residential'] = {
label = 'Residential Area',
zones = {
{ coords = vector3(-20.00, -1444.99, 30.61), size = 60.0 },
{ coords = vector3(180.06, -1486.36, 28.14), size = 55.0 },
{ coords = vector3(-220.0, -1600.0, 34.0), size = 50.0 }
}
},
-- Rest of zones left out for readability...
}
Config.Locales = {
['animal_blip_label'] = 'Catch: %s',
['catch_animal'] = 'Catch animal',
['confirm_cancel_job'] =
'You have no animal in your vehicle. By delivering the vehicle, you will cancel the job. Press [E] to confirm.',
['distract_animal'] = 'You need to distract the animal before you can catch it.',
['failed_animal_dead'] = 'The job was canceled because the animal is dead. Return your vehicle and start a new job.',
['failed_animal_nonexistent'] =
'The job was canceled because the animal does not exist anymore. Return your vehicle and start a new job.',
['failed_too_far'] =
'The job was canceled because the animal is too far away. Return your vehicle and start a new job.',
['failed_vehicle_nonexistent'] =
'The job was canceled because the vehicle does not exist anymore. Return to base and start a new job.',
['job_canceled'] = 'The job was canceled because you delivered your vehicle without an animal in it.',
['not_enough_money'] = 'You need $%s to pay the deposit for renting the vehicle.',
['paid_deposit'] = 'You paid a deposit of $%s to rent the vehicle.',
['pickup_bait'] = 'Pick up bait',
['pickup_crate'] = 'Pick up crate',
['place_bait'] = 'Place bait',
['put_crate_in_vehicle'] = 'Put crate in vehicle',
['received_deposit'] = 'You received your deposit of $%s back.',
['received_reward'] = 'You received $%s as reward for completing the job.',
['return_to_start'] = 'Return your vehicle with the animal to complete the job.',
['return_vehicle_complete'] = 'Return vehicle (Complete job)',
['return_vehicle'] = 'Return vehicle (Cancel job)',
['spawn_not_clear'] = 'There are no available spawn points for your job vehicle.',
['start_job_text'] = 'Start job',
}
-- Labels for GTA 5 zones
Config.ZoneLabels = {
['AIRP'] = 'Los Santos International Airport',
['ALAMO'] = 'Alamo Sea',
['ALTA'] = 'Alta',
-- Rest of zones left out for readability...
}
Client bridge
ESX = nil
QBCore = nil
if (GetResourceState('es_extended') == 'started') then
ESX = exports['es_extended']:getSharedObject()
elseif (GetResourceState('qb-core') == 'started') then
QBCore = exports['qb-core']:GetCoreObject()
end
Functions = {}
Functions.Notify = function(message)
if ESX then
ESX.ShowNotification(message, 'info', 5000)
elseif QBCore then
QBCore.Functions.Notify(message, 'primary', 5000)
end
end
-- Used to check if the player can use any of the target interactions
Functions.CanInteract = function()
local playerPed = PlayerPedId()
if IsPedDeadOrDying(playerPed, true) then
return false
end
if IsPedInAnyVehicle(playerPed, false) then
return false
end
return true
end
Functions.AddTarget = function(targetType, target, icon, label, distance, canInteract, onSelect)
if (GetResourceState('ox_target') ~= 'started') then
return print('ox_target is not installed, adjust cl_bridge.lua to the target-script you are using.')
end
if (targetType == 'localentity') then
exports.ox_target:addLocalEntity(target, { {
icon = icon,
label = label,
distance = distance,
canInteract = canInteract,
onSelect = onSelect
} })
elseif (targetType == 'entity') then
exports.ox_target:addEntity(target, { {
icon = icon,
label = label,
distance = distance,
canInteract = canInteract,
onSelect = onSelect
} })
end
end
Functions.PlayPedNotification = function(ped, sender, message)
if not DoesEntityExist(ped) then
return
end
local mugshotHandle, mugshotTxd = GetPedMugshot(ped)
BeginTextCommandThefeedPost('STRING')
AddTextComponentSubstringPlayerName(message)
EndTextCommandThefeedPostMessagetext(mugshotTxd, mugshotTxd, false, 0, sender, '')
EndTextCommandThefeedPostTicker(false, false)
UnregisterPedheadshot(mugshotHandle)
end
Server bridge
ESX = nil
QBCore = nil
if (GetResourceState('es_extended') == 'started') then
ESX = exports['es_extended']:getSharedObject()
elseif (GetResourceState('qb-core') == 'started') then
QBCore = exports['qb-core']:GetCoreObject()
end
Functions = {}
Functions.AddMoney = function(playerId, amount)
if ESX then
local xPlayer = ESX.GetPlayerFromId(playerId)
xPlayer.addAccountMoney('bank', amount)
elseif QBCore then
local Player = QBCore.Functions.GetPlayer(playerId)
Player.Functions.AddMoney('bank', amount)
end
end
Functions.RemoveMoney = function(playerId, amount)
if ESX then
local xPlayer = ESX.GetPlayerFromId(playerId)
xPlayer.removeAccountMoney('bank', amount)
elseif QBCore then
local Player = QBCore.Functions.GetPlayer(playerId)
Player.Functions.RemoveMoney('bank', amount)
end
end
Functions.HasMoney = function(playerId, amount)
if ESX then
local xPlayer = ESX.GetPlayerFromId(playerId)
local bankBalance = xPlayer.getAccount('bank').money
return (bankBalance >= amount)
elseif QBCore then
local Player = QBCore.Functions.GetPlayer(playerId)
local bankBalance = Player.PlayerData.money.bank
return (bankBalance >= amount)
end
end
AddEventHandler('gs_animalcontrol:OnJobStarted', function(data)
local playerId = data.playerId
local jobData = data.jobData
end)
AddEventHandler('gs_animalcontrol:OnAnimalSpawned', function(data)
local playerId = data.playerId
local netId = data.netId -- The network id of the animal
end)
AddEventHandler('gs_animalcontrol:OnJobVehicleSpawned', function(data)
local playerId = data.playerId
local netId = data.netId -- The network id of the vehicle
end)
AddEventHandler('gs_animalcontrol:OnAnimalInVehicle', function(data)
local playerId = data.playerId
end)
AddEventHandler('gs_animalcontrol:OnJobFinished', function(data)
local success = data.success
end)
| Code is accessible | No, but there is a fully unencrypted version. |
| Subscription-based | No |
| Lines (approximately) | 2036 |
| Requirements | ox_lib |
| Support | Yes |
