├── README.md ├── bridge ├── client │ ├── esx.lua │ ├── ox.lua │ └── qb.lua └── server │ ├── esx.lua │ ├── ox.lua │ └── qb.lua ├── client ├── cl_main.lua └── utils.lua ├── configs ├── client.lua ├── server.lua └── shared.lua ├── fxmanifest.lua └── server └── sv_main.lua /README.md: -------------------------------------------------------------------------------- 1 |
5 | 6 | # Features: 7 | - QB / QBX / OX / ESX Support 8 | - Rob local NPCs 9 | - Secure checks preventing spam, robbing animals, robbing spawned peds from resources, etc 10 | - Sets 'robbed' statebag on peds once they are robbed / run away / fight back, preventing them from being robbed again 11 | - Required cop count, or zero 12 | - Min / max payouts 13 | - Blacklisted jobs 14 | - Set jobs can not rob locals 15 | - Random Chances 16 | - Chance police are called when NPC is robbed 17 | - Chance ped has NO cash on them when robbed 18 | - Chance the ped decides to flee or beat your ass before or after robbing them, rather than surrendering 19 | - If ped fights back, random chance they have a weapon, random weapon is chosen from the config 20 | - Chance to receive items from peds pocket 21 | - Animations 22 | - Ped puts hands up, then surrenders 23 | - Player does a 'robbing' animation 24 | - Ped does animation to get up and flee 25 | - Easy configurations 26 | - Open function for adding money 27 | - Open function for adding items (use any inventory) 28 | - Open function for any dispatch 29 | 30 | # [Preview](https://www.youtube.com/watch?v=s-Ihw-aHBbo) 31 | 32 | # Dependencies: 33 | - [ox_lib](https://github.com/overextended/ox_lib/releases) 34 | - Supported Interaction Resources: 35 | - [qb-target](https://github.com/overextended/ox_target/releases) or [ox_target](https://github.com/overextended/ox_target/releases) 36 | - [interact](https://github.com/darktrovx/interact) -------------------------------------------------------------------------------- /bridge/client/esx.lua: -------------------------------------------------------------------------------- 1 | if GetResourceState('es_extended') ~= 'started' then return end 2 | 3 | local ESX = exports["es_extended"]:getSharedObject() 4 | 5 | function isBlacklistedJob(jobs) 6 | local Player = ESX.GetPlayerData() 7 | if type(jobs) == 'table' then 8 | for x = 1, #jobs do 9 | if jobs[x] == Player.job then 10 | return true 11 | end 12 | end 13 | else 14 | return (Player.job == jobs) 15 | end 16 | end 17 | 18 | AddEventHandler('esx:onPlayerLogout', function() 19 | TriggerEvent('xt-robnpcs:client:onUnload') 20 | end) -------------------------------------------------------------------------------- /bridge/client/ox.lua: -------------------------------------------------------------------------------- 1 | if GetResourceState('ox_core') ~= 'started' then return end 2 | 3 | local file = ('imports/%s.lua'):format(IsDuplicityVersion() and 'server' or 'client') 4 | local import = LoadResourceFile('ox_core', file) 5 | local chunk = assert(load(import, ('@@ox_core/%s'):format(file))) 6 | chunk() 7 | 8 | function isBlacklistedJob(jobs) 9 | return player.hasGroup(jobs) 10 | end 11 | 12 | AddEventHandler('ox:playerLogout', function() 13 | TriggerEvent('xt-robnpcs:client:onUnload') 14 | end) -------------------------------------------------------------------------------- /bridge/client/qb.lua: -------------------------------------------------------------------------------- 1 | if GetResourceState('qb-core') ~= 'started' then return end 2 | 3 | local QBCore = exports['qb-core']:GetCoreObject() 4 | 5 | function isBlacklistedJob(jobs) 6 | local Player = QBCore.Functions.GetPlayerData() 7 | if type(jobs) == 'table' then 8 | for x = 1, #jobs do 9 | if jobs[x] == Player.job.name then 10 | return true 11 | end 12 | end 13 | else 14 | return (Player.job.name == jobs) 15 | end 16 | end 17 | 18 | AddEventHandler('QBCore:Client:OnPlayerUnload', function() 19 | TriggerEvent('xt-robnpcs:client:onUnload') 20 | end) -------------------------------------------------------------------------------- /bridge/server/esx.lua: -------------------------------------------------------------------------------- 1 | if GetResourceState('es_extended') ~= 'started' then return end 2 | 3 | local ESX = exports['es_extended']:getSharedObject() 4 | 5 | function getPlayer(src) 6 | return ESX.GetPlayerFromId(src) 7 | end 8 | 9 | function getPlayerJob(src) 10 | local player = getPlayer(src) 11 | return player and player.job.name or nil 12 | end -------------------------------------------------------------------------------- /bridge/server/ox.lua: -------------------------------------------------------------------------------- 1 | if GetResourceState('ox_core') ~= 'started' then return end 2 | 3 | local file = ('imports/%s.lua'):format(IsDuplicityVersion() and 'server' or 'client') 4 | local import = LoadResourceFile('ox_core', file) 5 | local chunk = assert(load(import, ('@@ox_core/%s'):format(file))) 6 | chunk() 7 | 8 | function getPlayer(id) 9 | return Ox.GetPlayer(id) 10 | end 11 | 12 | function getPlayerJob(src) 13 | local player = getPlayer(src) 14 | return player and player.getGroup() or nil 15 | end -------------------------------------------------------------------------------- /bridge/server/qb.lua: -------------------------------------------------------------------------------- 1 | if GetResourceState('qb-core') ~= 'started' then return end 2 | 3 | local QBCore = exports['qb-core']:GetCoreObject() 4 | 5 | function getPlayer(src) 6 | return QBCore.Functions.GetPlayer(src) 7 | end 8 | 9 | function getPlayerJob(src) 10 | local player = getPlayer(src) 11 | return player and player.PlayerData.job.name or nil 12 | end -------------------------------------------------------------------------------- /client/cl_main.lua: -------------------------------------------------------------------------------- 1 | local config = require 'configs.client' 2 | local shared = require 'configs.shared' 3 | local globalState = GlobalState 4 | local target = GetResourceState('qb-target') == 'started' and 'qb' or 'ox' 5 | local targetExport = (target == 'qb') and exports['qb-target'] or exports.ox_target 6 | 7 | targetLocal = nil 8 | isRobbing = false 9 | 10 | -- Ped Gets Up & Runs Away -- 11 | local function pedGetUp(entity) 12 | targetLocal = nil 13 | isRobbing = false 14 | 15 | removeInteraction(entity) 16 | 17 | if IsPedDeadOrDying(entity, true) then 18 | return 19 | end 20 | 21 | if target == 'qb' then 22 | targetExport:RemoveTargetEntity(entity, 'Rob Citizen') 23 | else 24 | targetExport:removeLocalEntity(entity, 'rob_local') 25 | end 26 | 27 | FreezeEntityPosition(entity, false) 28 | lib.requestAnimDict('random@shop_robbery') 29 | TaskPlayAnim(entity, 'random@shop_robbery', 'kneel_getup_p', 2.0, 2.0, 2500, 9, 0, false, false, false) 30 | Wait(2500) 31 | 32 | if not cache.ped then 33 | return 34 | end 35 | 36 | local fightChance = math.random(config.chancePedFights.min, config.chancePedFights.max) 37 | local randomChance = math.random(100) 38 | if randomChance <= fightChance then 39 | attackingPed(entity) 40 | else 41 | pedFlees(entity) 42 | end 43 | end 44 | 45 | -- Handle Robbing Local -- 46 | local function robLocal(entity) 47 | if lib.progressCircle({ 48 | label = 'Running Pockets...', 49 | duration = (config.robLength * 1000), 50 | position = 'bottom', 51 | useWhileDead = false, 52 | canCancel = false, 53 | disable = { car = true, move = true }, 54 | anim = { dict = 'random@shop_robbery', clip = 'robbery_action_b' }, 55 | }) then 56 | local netID = NetworkGetNetworkIdFromEntity(entity) 57 | local robbed = lib.callback.await('xt-robnpcs:server:robNPC', false, netID) 58 | if robbed then 59 | pedGetUp(entity) 60 | end 61 | end 62 | end 63 | 64 | -- Adds Interaction to Ped -- 65 | local function addInteraction(entity) 66 | if config.useInteract then 67 | local netId = NetworkGetNetworkIdFromEntity(entity) 68 | 69 | exports.interact:AddEntityInteraction({ 70 | netId = netId, 71 | id = 'robLocal', 72 | distance = 4.0, 73 | interactDst = 2.0, 74 | ignoreLos = false, 75 | options = { 76 | { 77 | label = 'Rob Citizen', 78 | action = function(_, coords, args) 79 | robLocal(entity) 80 | end, 81 | }, 82 | } 83 | }) 84 | else 85 | 86 | if target == 'qb' then 87 | targetExport:AddTargetEntity(entity, { 88 | options = { 89 | { 90 | type = "client", 91 | icon = 'fas fa-gun', 92 | label = 'Rob Citizen', 93 | action = function(entity) 94 | robLocal(entity) 95 | end, 96 | } 97 | }, 98 | distance = 2.0, 99 | }) 100 | else 101 | targetExport:addLocalEntity(entity, { 102 | { 103 | label = 'Rob Citizen', 104 | name = 'rob_local', 105 | icon = 'fas fa-gun', 106 | distance = 2.0, 107 | onSelect = function(data) 108 | robLocal(entity) 109 | end, 110 | } 111 | }) 112 | end 113 | end 114 | end 115 | 116 | -- Local Plays Anim / Add Target -- 117 | local function handlePedInteraction(pedEntity) 118 | isRobbing = true 119 | targetLocal = pedEntity 120 | 121 | Wait(2000) -- Just a little "buffer" so they dont react instantly 122 | 123 | local coords = GetEntityCoords(targetLocal) 124 | notifyPolice(coords) 125 | 126 | TaskStandStill(targetLocal, 2000) 127 | 128 | -- Chance ped does not surrender 129 | if fightOrFlee(targetLocal) then 130 | isRobbing = false 131 | targetLocal = nil 132 | Entity(pedEntity).state:set('robbed', true, false) 133 | return 134 | end 135 | 136 | TaskHandsUp(targetLocal, 2000) 137 | SetPedKeepTask(targetLocal, true) 138 | FreezeEntityPosition(targetLocal, true) 139 | Wait(2000) 140 | 141 | forceSurrenderAnimation(targetLocal) 142 | addInteraction(targetLocal) 143 | end 144 | 145 | local function aimAtPedsLoop(newWeapon) 146 | local sleep = 10 147 | while cache.weapon ~= nil do 148 | if globalState?.copCount >= shared.requiredCops and not cache.vehicle then 149 | local dist 150 | 151 | -- Ped gets up and runs away if you're too far away 152 | if targetLocal ~= nil then 153 | dist = getDistance(targetLocal) 154 | if dist > config.targetDistance then 155 | pedGetUp(targetLocal) 156 | end 157 | end 158 | 159 | local entity 160 | 161 | if IsPlayerTargettingAnything(cache.playerId) then 162 | _, entity = GetPlayerTargetEntity(cache.playerId) 163 | sleep = 10 164 | elseif IsPlayerFreeAiming(cache.playerId) then 165 | _, entity = GetEntityPlayerIsFreeAimingAt(cache.playerId) 166 | sleep = 10 167 | else 168 | sleep = 500 169 | end 170 | 171 | if entity ~= nil then 172 | local entityState = Entity(entity)?.state?.robbed 173 | local missionEntity = (GetEntityPopulationType(entity) == 7) 174 | dist = getDistance(entity) 175 | 176 | if dist <= config.targetDistance and not entityState and not missionEntity and not isRobbing and IsPedHuman(entity) and not IsPedAPlayer(entity) and not IsPedDeadOrDying(entity, true) and not IsPedInAnyVehicle(entity) then 177 | handlePedInteraction(entity) 178 | end 179 | end 180 | else 181 | sleep = 500 182 | end 183 | Wait(sleep) 184 | end 185 | end 186 | 187 | -- Handlers -- 188 | lib.onCache('weapon', function(newWeapon) 189 | if not newWeapon or not isAllowedWeapon(newWeapon) or isBlacklistedJob(config.blacklistedJobs) then return end 190 | 191 | aimAtPedsLoop(newWeapon) 192 | end) 193 | 194 | AddEventHandler('xt-robnpcs:client:onUnload', function() 195 | if not targetLocal then return end 196 | pedGetUp(targetLocal) 197 | end) 198 | 199 | AddEventHandler('onResourceStop', function(resource) 200 | if resource ~= GetCurrentResourceName() then return end 201 | if not targetLocal then return end 202 | pedGetUp(targetLocal) 203 | end) 204 | -------------------------------------------------------------------------------- /client/utils.lua: -------------------------------------------------------------------------------- 1 | local config = require 'configs.client' 2 | local target = GetResourceState('qb-target') == 'started' and 'qb' or 'ox' 3 | local targetExport = (target == 'qb') and exports['qb-target'] or exports.ox_target 4 | 5 | -- Forces Ped Into Surrended Animation -- 6 | function forceSurrenderAnimation(entity) 7 | CreateThread(function() 8 | lib.requestAnimDict('random@shop_robbery') 9 | while isRobbing do 10 | if not IsEntityPlayingAnim(entity, 'random@shop_robbery', 'kneel_loop_p', 3) then 11 | TaskPlayAnim(entity, 'random@shop_robbery', 'kneel_loop_p', 50.0, 8.0, -1, 1, 1.0, false, false, false) 12 | end 13 | Wait(200) 14 | end 15 | end) 16 | end 17 | 18 | -- Distance Between Player & Ped -- 19 | function getDistance(entity) 20 | local pCoords = GetEntityCoords(cache.ped, true) 21 | local tCoords = GetEntityCoords(entity, true) 22 | local dist = #(tCoords - pCoords) 23 | 24 | return dist 25 | end 26 | 27 | -- Chance Police are Called -- 28 | function notifyPolice(coords) 29 | local copsChance = math.random(config.copsChance.min, config.copsChance.max) 30 | local randomChance = math.random(100) 31 | if randomChance <= copsChance then 32 | config.dispatch(coords) 33 | end 34 | end 35 | 36 | -- Remove Interactions -- 37 | function removeInteraction(entity) 38 | if config.useInteract then 39 | local netId = NetworkGetNetworkIdFromEntity(entity) 40 | exports.interact:RemoveEntityInteraction(netId, 'robLocal') 41 | else 42 | if target == 'qb' then 43 | targetExport:RemoveTargetEntity(entity, 'Rob Citizen') 44 | else 45 | targetExport:removeLocalEntity(entity, 'rob_local') 46 | end 47 | end 48 | end 49 | 50 | -- Ped Chooses to Attack -- 51 | function attackingPed(entity) 52 | if IsPedFleeing(entity) then 53 | ClearPedTasksImmediately(entity) 54 | end 55 | 56 | SetPedFleeAttributes(entity, 0, 0) 57 | SetPedCombatAttributes(entity, 46, 1) -- BF_CanFightArmedPedsWhenNotArmed 58 | SetPedCombatAttributes(entity, 17, 0) -- BF_AlwaysFlee 59 | SetPedCombatAttributes(entity, 5, 1) -- BF_AlwaysFight 60 | SetPedCombatAttributes(entity, 58, 1) -- BF_DisableFleeFromCombat 61 | SetPedCombatRange(entity, 3) 62 | SetPedRelationshipGroupHash(entity, joaat('HATES_PLAYER')) 63 | TaskCombatHatedTargetsAroundPed(entity, 50, 0) 64 | 65 | local weaponChance = math.random(config.chancePedIsArmedWhileFighting.min, config.chancePedIsArmedWhileFighting.max) 66 | local randomChance2 = math.random(100) 67 | if randomChance2 <= weaponChance then 68 | local randomWeapon = math.random(#config.pedWeapons) 69 | GiveWeaponToPed(entity, config.pedWeapons[randomWeapon], false, false) 70 | end 71 | 72 | TaskCombatHatedTargetsAroundPed(entity, 50, 0) 73 | lib.notify({ title = 'Fight Back!', description = 'They didn\'t like that!', type = 'error' }) 74 | end 75 | 76 | -- Ped Chooses to Flee -- 77 | function pedFlees(entity) 78 | SetBlockingOfNonTemporaryEvents(entity, false) 79 | TaskReactAndFleePed(entity, cache.ped) 80 | Wait(2000) -- Another little "buffer" so players cant just snap to the next ped instantly if they run away 81 | targetLocal = nil 82 | isRobbing = false 83 | end 84 | 85 | -- Ped Fights or Flees -- 86 | function fightOrFlee(entity) 87 | local fightChance = math.random(config.chancePedFights.min, config.chancePedFights.max) 88 | local fleeChance = math.random(config.chancePedFlees.min, config.chancePedFlees.max) 89 | local randomChance = math.random(100) 90 | 91 | SetBlockingOfNonTemporaryEvents(entity, true) 92 | 93 | if randomChance <= fightChance then 94 | attackingPed(entity) 95 | return true 96 | end 97 | 98 | if randomChance <= fleeChance then 99 | pedFlees(entity) 100 | lib.notify({ title = 'They ran away!', type = 'error'}) 101 | return true 102 | end 103 | 104 | return false 105 | end 106 | 107 | function isAllowedWeapon(weapon) 108 | local callback = false 109 | 110 | for x = 1, #config.allowedWeapons do 111 | if weapon == joaat(config.allowedWeapons[x]) then 112 | callback = true 113 | break 114 | end 115 | end 116 | 117 | return callback 118 | end -------------------------------------------------------------------------------- /configs/client.lua: -------------------------------------------------------------------------------- 1 | return { 2 | useInteract = false, -- Use interact or ox/qb target (https://github.com/darktrovx/interact) 3 | targetDistance = 20, -- Max distance ped reacts to you aiming at them 4 | blacklistedJobs = { -- Jobs not allowed to rob locals 5 | 'police', 6 | 'ambulance' 7 | }, 8 | robLength = 5, -- Length to rob local (seconds) 9 | chancePedFlees = { -- Chance ped runs away rather than surrendering 10 | min = 5, 11 | max = 25 12 | }, 13 | chancePedFights = { -- Chance ped beats your ass before or after being robbed 14 | min = 5, 15 | max = 15 16 | }, 17 | chancePedIsArmedWhileFighting = { -- Chance ped has a melee weapon to fight player 18 | min = 80, 19 | max = 90 20 | }, 21 | pedWeapons = { -- Weapons ped might have 22 | 'WEAPON_KNIFE', 23 | 'WEAPON_BAT' 24 | }, 25 | copsChance = { -- Chance police are called 26 | min = 80, 27 | max = 90 28 | }, 29 | allowedWeapons = { -- Weapons allowed to rob peds 30 | 'WEAPON_KNIFE', 31 | 'WEAPON_PISTOL' 32 | }, 33 | 34 | dispatch = function(coords) 35 | local PoliceJobs = { 'police' } 36 | 37 | -- Add your own dispatch event / exports 38 | exports["ps-dispatch"]:CustomAlert({ 39 | coords = coords, 40 | job = PoliceJobs, 41 | message = 'Citizen Robbery', 42 | dispatchCode = '10-??', 43 | firstStreet = coords, 44 | description = 'Citizen Robbery', 45 | radius = 0, 46 | sprite = 58, 47 | color = 1, 48 | scale = 1.0, 49 | length = 3, 50 | }) 51 | end 52 | } -------------------------------------------------------------------------------- /configs/server.lua: -------------------------------------------------------------------------------- 1 | return { 2 | payOut = { -- Payout min/max 3 | min = 10, 4 | max = 20 5 | }, 6 | payOutChance = { -- Chance player receives cash 7 | min = 70, 8 | max = 80 9 | }, 10 | chanceItemsFound = { -- Chance player finds items 11 | min = 80, 12 | max = 90 13 | }, 14 | lootableItems = { -- Items player can loot 15 | { item = 'rolex', min = 1, max = 2 }, 16 | { item = 'phone', min = 1, max = 2 } 17 | }, 18 | policeJobs = { 19 | 'police', 20 | 'lspd' 21 | }, 22 | 23 | addCash = function(src, amount) 24 | local player = getPlayer(src) -- Here's your player, use that as you want 25 | -- player.Functions.AddMoney('cash', amount) -- qb/qbx 26 | 27 | return exports.ox_inventory:AddItem(src, 'money', amount) 28 | end, 29 | 30 | addItem = function(src, item, amount) 31 | local player = getPlayer(src) -- Here's your player, use that as you want 32 | -- player.Functions.AddItem(item, amount) -- qb/qbx 33 | 34 | return exports.ox_inventory:AddItem(src, item, amount) 35 | end 36 | } -------------------------------------------------------------------------------- /configs/shared.lua: -------------------------------------------------------------------------------- 1 | return { 2 | requiredCops = 0, -- Amount of cops required to rob locals 3 | } -------------------------------------------------------------------------------- /fxmanifest.lua: -------------------------------------------------------------------------------- 1 | fx_version 'cerulean' 2 | game 'gta5' 3 | use_experimental_fxv2_oal 'yes' 4 | lua54 'yes' 5 | 6 | description 'Rob NPCs | xT Development' 7 | 8 | shared_scripts { '@ox_lib/init.lua', 'configs/shared.lua' } 9 | client_scripts { 'configs/client.lua', 'bridge/client/*.lua', 'client/*.lua' } 10 | server_scripts { 'configs/server.lua', 'bridge/server/*.lua', 'server/*.lua' } -------------------------------------------------------------------------------- /server/sv_main.lua: -------------------------------------------------------------------------------- 1 | local config = require 'configs.server' 2 | local shared = require 'configs.shared' 3 | local globalState = GlobalState 4 | 5 | globalState.copCount = globalState?.copCount or 0 6 | 7 | local function distanceCheck(player, target) 8 | local pCoords = GetEntityCoords(GetPlayerPed(player)) 9 | local tCoords = GetEntityCoords(NetworkGetEntityFromNetworkId(target)) 10 | local dist = #(tCoords - pCoords) 11 | 12 | return dist <= 5 13 | end 14 | 15 | -- Checks if Player is Police -- 16 | local function hasPoliceJob(src, jobs) 17 | local pJob = getPlayerJob(src) 18 | if type(jobs) == 'table' then 19 | for x = 1, #jobs do 20 | if jobs[x] == pJob then 21 | return true 22 | end 23 | end 24 | else 25 | return (pJob == jobs) 26 | end 27 | end 28 | 29 | -- Receive Cash -- 30 | local function receiveCashChance(src) 31 | local payChance = math.random(config.payOutChance.min, config.payOutChance.max) 32 | local randomChance = math.random(100) 33 | local callback = false 34 | 35 | if randomChance <= payChance then 36 | local pay = math.random(config.payOut.min, config.payOut.max) 37 | if config.addCash(src, pay) then 38 | callback = true 39 | end 40 | else 41 | lib.notify(src, { title = 'No Cash!', description = 'They didn\'t have any cash!', type = 'error' }) 42 | callback = true 43 | end 44 | 45 | return callback 46 | end 47 | 48 | -- Receive Items -- 49 | local function receiveItemsChance(src) 50 | local itemChance = math.random(config.chanceItemsFound.min, config.chanceItemsFound.max) 51 | local randomChance = math.random(100) 52 | local callback = false 53 | 54 | if randomChance <= itemChance then 55 | local randomItem = math.random(#config.lootableItems) 56 | local randomAmount = math.random(config.lootableItems[randomItem].min, config.lootableItems[randomItem].max) 57 | if config.addItem(src, config.lootableItems[randomItem].item, randomAmount) then 58 | callback = true 59 | end 60 | end 61 | 62 | return callback 63 | end 64 | 65 | -- Get Paid (or not) & Set State -- 66 | lib.callback.register('xt-robnpcs:server:robNPC', function(source, netID) 67 | local src = source 68 | local dist = distanceCheck(source, netID) 69 | local callback = false 70 | if not dist then return callback end 71 | 72 | local entity = NetworkGetEntityFromNetworkId(netID) 73 | local state = Entity(entity).state 74 | 75 | if state then 76 | state:set('robbed', src, true) 77 | local payChance = math.random(config.payOutChance.min, config.payOutChance.max) 78 | local randomChance = math.random(100) 79 | if receiveCashChance(src) then 80 | receiveItemsChance(src) 81 | callback = true 82 | end 83 | end 84 | 85 | return callback 86 | end) 87 | 88 | -- Constantly Update Cop Count -- 89 | AddEventHandler('onResourceStart', function(resource) 90 | if resource ~= GetCurrentResourceName() then return end 91 | if shared.requiredCops == 0 then return end 92 | 93 | SetInterval(function() 94 | local players = GetPlayers() 95 | local count = 0 96 | 97 | for _, src in pairs(players) do 98 | if hasPoliceJob(tonumber(src), config.policeJobs) then 99 | count += 1 100 | end 101 | end 102 | 103 | if globalState.copCount ~= count then 104 | globalState.copCount = count 105 | end 106 | end, 60000) 107 | end) --------------------------------------------------------------------------------