LR = {} LR.__index = LR local coroutine_yield = coroutine.yield ostime = GlobalState.ostime function LR:Init() local o = {} setmetatable(o, LR) o.PlayerData = {} if ESX.IsPlayerLoaded() then o.PlayerData = ESX.GetPlayerData() end o.CurrentZone = nil o.ZoneDistance = nil o.NUIOpen = false o.Blips = {} o.RadiusBlips = {} o.SelfRadius = {} o.YellowRadius = {} o.PulseBlip = nil o.Capturing = false o.CurCapture = nil o.canC = false o:EventHandler() o:ZoneThread() o:MainThread() o:BlipsThread() return o end function LR:EventHandler() RegisterNetEvent("esx:playerLoaded", function(xPlayer) self.PlayerData = xPlayer end) RegisterNetEvent("esx:setJob", function(org) self.PlayerData.org = org end) RegisterNetEvent("lr_occ2:client:startCapture", function(index, name) local zone = Config.Occ[index] self.CurCapture = index self:ShowNotification("warning", ("%s đang bị chiếm bởi %s"):format(zone.Label, name), true) TriggerEvent("lr_captcha:close") self:PulseBlipF(index) end) RegisterNetEvent("lr_occ:client:cancelCapture", function(index, name) local zone = Config.Occ[index] self:ShowNotification("warning", ("%s đã hủy chiếm khu vực %s, mọi người có thể tiến hành chiếm khu vực lại sau 120 giây nữa"):format(name, zone.Label)) TriggerEvent("lr_captcha:close") self:UnPulse() self.Capturing = false self.CurCapture = nil end) RegisterNetEvent("lr_occ:client:captured", function(index, name, gang) local zone = Config.Occ[index] if self.CurrentZone == index then --SetCurrentPedWeapon(PlayerPedId(), "WEAPON_UNARMED", true) --cam ban end --TriggerServerEvent("lr_occ:server:addPoint", gang, zone.point) self:ShowNotification("success", ("%s đã chiếm thành công %s mang về %s điểm cho %s"):format(name, zone.Label, zone.point, gang)) TriggerEvent("lr_captcha:close") self:UnPulse() self.Capturing = false self.CurCapture = nil Wait(5000) self:BlipsThread() end) RegisterNetEvent("lr_occ2:client:openOcc", function(isOpen) if isOpen then self:ShowNotification("warning", "Đã bắt đầu thời gian chiếm đóng") else self:ShowNotification("warning", "Đã kết thúc thời gian chiếm đóng") end end) end function LR:BlipsThread() for k, v in pairs(self.Blips) do RemoveBlip(v) end for k, v in pairs(self.RadiusBlips) do RemoveBlip(v) end for k, v in pairs(self.SelfRadius) do RemoveBlip(v) end for k, v in pairs(GlobalState.Occ) do local p = v.Pos local Cblip = AddBlipForRadius(p.x, p.y, p.z, v.oRadius) SetBlipColour(Cblip, 5) SetBlipAlpha(Cblip, 150) SetBlipHighDetail(Cblip, true) SetBlipRotation(Cblip, 0.0) SetBlipDisplay(Cblip, 4) SetBlipAsShortRange(Cblip, false) SetBlipHiddenOnLegend(Cblip, true) self.YellowRadius[k] = Cblip local blip = AddBlipForCoord(p.x, p.y, p.z) SetBlipSprite(blip, v.owner and GlobalState.GangBlips[v.owner].sprite or 78) SetBlipDisplay(blip, 2) SetBlipScale(blip, v.owner and 1.2 or 0.9) SetBlipColour(blip, 0) SetBlipAsShortRange(blip, true) SetBlipHighDetail(blip, true) BeginTextCommandSetBlipName("STRING") AddTextComponentString(("Khu Vực Chiếm Đóng [%s]"):format(v.Label)) EndTextCommandSetBlipName(blip) self.Blips[k] = blip local Ablip = AddBlipForRadius(p.x, p.y, p.z, v.Radius) SetBlipColour(Ablip, 1) SetBlipAlpha(Ablip, 150) SetBlipHighDetail(Ablip, true) SetBlipRotation(Ablip, 0.0) SetBlipDisplay(Ablip, 4) SetBlipAsShortRange(Ablip, false) SetBlipHiddenOnLegend(Ablip, true) self.RadiusBlips[k] = Ablip local Bblip = AddBlipForRadius(p.x, p.y, p.z, v.cRadius) SetBlipColour(Bblip, 7) SetBlipAlpha(Bblip, 200) SetBlipHighDetail(Bblip, true) SetBlipRotation(Bblip, 0.0) SetBlipDisplay(Bblip, 4) SetBlipAsShortRange(Bblip, false) SetBlipHiddenOnLegend(Bblip, true) self.SelfRadius[k] = Bblip end end function LR:ZoneThread() self.CurCapture = lib.callback.await("lr_occ2:callback:getCurCapture", false) Citizen.CreateThread(function() while true do coroutine_yield(0) local ped = PlayerPedId() local pedCoords = GetEntityCoords(ped) local z for k, v in pairs(Config.Occ) do local distance = #(pedCoords - v.Pos) if distance <= v.Radius then -- TriggerEvent("LRPT:SetWhiteList", false) SetEntityCanBeDamaged(ped, true) if self.CurrentZone == nil then TriggerServerEvent("lr_occ2:server:join", k) LocalPlayer.state:set('inOcc', true, false) end self.CurrentZone = k self.ZoneDistance = distance self.lastJoin = k self.lastZone = k z = k self:NUI() --[[if self.CurCapture == k then local joinTime = GlobalState.ostime - self.PlayerData.org.join_date if joinTime < 172800 then ESX.ShowNotification("Thời gian gia nhập băng đảng của bạn") ESX.ShowNotification("không đủ để tham gia chiếm đóng") ESX.ShowNotification("Bạn sẽ được teleport về garage") SetEntityCoords(PlayerPedId(), 215.67095947266, -809.82708740234, 30.739696502686, 0.0, 0.0, 0.0, false) TriggerServerEvent("lr_occ2:server:leave", k) LocalPlayer.state:set('inOcc', false, false) self.lastZone = nil end end--]] goto continue break elseif distance > v.Radius and distance < v.oRadius then if self.CurrentZone == nil then local veh = GetVehiclePedIsIn(ped, false) local vehHash = GetEntityModel(veh) if Config.BlockVehicle[vehHash] then SetEntityAsMissionEntity(veh, true, true) DeleteVehicle(veh) end self.CurrentZone = k self.ZoneDistance = distance TriggerServerEvent("lr_occ2:server:join", k) LocalPlayer.state:set('inOcc', true, false) end DisablePlayerFiring(PlayerId(), true) self.lastZone = k if self.lastJoin == nil then -- TriggerEvent("LRPT:SetWhiteList", true) SetEntityCanBeDamaged(ped, false) end z = k goto continue2 break end end if z == nil then TriggerEvent("LRPT:SetWhiteList", false) SetEntityCanBeDamaged(ped, true) if self.lastZone then TriggerServerEvent("lr_occ2:server:leave", self.lastZone) LocalPlayer.state:set('inOcc', false, false) self.lastZone = nil end end self.CurrentZone = nil self.ZoneDistance = nil ::continue:: Wait(1000) ::continue2:: end end) end local KEYS = { ['E'] = 38, ['B'] = 29, ['Q'] = 44, ['Z'] = 20, ['G'] = 47, ['Z'] = 48 } local CONTROL = { 'E', 'B', 'Q', 'Z', 'G', 'Z' } function GetRandomControl() local rd = math.random(1, #CONTROL) return CONTROL[rd] end local cA, cB, cC = GetRandomControl(), GetRandomControl(), GetRandomControl() local pA, pB, pC = false, false local HELP = ("Nhấn ~%s~[%s]~w~ ~%s~[%s]~w~ ~%s~[%s]~w~ ~%s~[%s]~w~ ~%s~[%s]~w~ ~%s~[%s]~w~ ~%s~[%s]~w~ ~%s~[%s]~w~ ~%s~[%s]~w~ ~%s~[%s]~w~ để chiếm") --[[ function LR:GetRandomKeyPress(cb) Citizen.CreateThread(function() local keys = {} for i = 1, 10, 1 do local k = GetRandomControl() table.insert(keys, k) end local crKey = 1 while self.ZoneDistance <= 1.0 and not self.Capturing and not self.CurCapture and self.canC do coroutine_yield(0) ShowHelpNotification(HELP:format(crKey > 1 and 'g' or 'r', keys[1], crKey > 2 and 'g' or 'r', keys[2], crKey > 3 and 'g' or 'r', keys[3], crKey > 4 and 'g' or 'r', keys[4], crKey > 5 and 'g' or 'r', keys[5], crKey > 6 and 'g' or 'r', keys[6], crKey > 7 and 'g' or 'r', keys[7], crKey > 8 and 'g' or 'r', keys[8], crKey > 9 and 'g' or 'r', keys[9], crKey > 10 and 'g' or 'r', keys[10])) for k, v in pairs(KEYS) do DisableControlAction(0, v, true) if IsDisabledControlJustReleased(0, v) then if keys[crKey] == k then crKey = crKey + 1 if crKey > 10 then cb(true) return end else cb(false) return end end end end cb() return end) end ]] function LR:MainThread() local t = 0 Citizen.CreateThread(function() Wait(2000) local OutzoneAttemp = nil local timeout = 0 local lastPress = 0 while true do coroutine_yield(0) if self.CurrentZone ~= nil then LocalPlayer.state:set('occ', true, false) local zone = Config.Occ[tostring(self.CurrentZone)] local pos = zone.Pos DrawMarker(1, pos.x, pos.y, pos.z - 100.100, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, zone.Radius * 2, zone.Radius * 2, 200.0, 255, 0, 0, 100, false, true, 2, nil, nil, false) DrawMarker(1, pos.x, pos.y, pos.z - 1.100, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.0, 2.0, 2.0, 255, 0, 0, 100, false, true, 2, nil, nil, false) --if self.ZoneDistance <= 1.0 and not self.Capturing and not self.CurCapture and GlobalState.OccOpen then if self.ZoneDistance <= 1.0 and not self.Capturing and not self.CurCapture and self.canC and GlobalState.OccOpen then --ShowHelpNotification("Nhấn [E] để chiếm") TriggerEvent("hm_hud:toggleNotifyHelp", { press = cooldown, -- neu true thi sang false thi toi key = "E", -- text phim tat msg = "để chiếm", percent = 0 -- thoi gian nut e sang len }) if IsControlJustReleased(0, 38) then if GetGameTimer() - lastPress > 5000 then lastPress = GetGameTimer() ESX.TriggerServerCallback("lr_occ2:callback:CanCapture", function(canCapture) if canCapture then self.Capturing = true end self.IsBusy = false end, self.CurrentZone) else lastPress = GetGameTimer() ESX.ShowNotification('Vui lòng không SPAM') end end end if self.Capturing then if self.ZoneDistance > zone.cRadius then if OutzoneAttemp == 0 then OutzoneAttemp = ostime self:ShowNotification("warning", "Chiếm đóng sẽ bị hủy sau 10 giây nếu không quay lại khu vực chiếm đóng") else if ostime - OutzoneAttemp > 10 then OutzoneAttemp = 0 TriggerServerEvent("lr_occ2:server:cancelCapture") self.Capturing = false end end else if OutzoneAttemp ~= 0 then OutzoneAttemp = 0 end end if GetEntityHealth(PlayerPedId()) <= 0 then OutzoneAttemp = 0 TriggerServerEvent("lr_occ2:server:cancelCapture") self.Capturing = false end end local i = 0 local zoneData = GlobalState.ZoneData[self.CurrentZone] if zoneData then for k, v in pairs(zoneData) do SetTextFont(0) SetTextProportional(0) SetTextScale(0.3, 0.3) SetTextColour(255, 255, 255, 255) SetTextDropshadow(0, 0, 0, 0, 255) SetTextEdge(1, 0, 0, 0, 255) SetTextDropShadow() SetTextOutline() BeginTextCommandDisplayText("STRING") AddTextComponentSubstringPlayerName(("[%s]: %s"):format(k, v)) EndTextCommandDisplayText(0.01, 0.5 + i) i = i + 0.02 end end else if self.Capturing then TriggerServerEvent("lr_occ2:server:cancelCapture") end LocalPlayer.state:set('occ', false, false) if self.NUIOpen then self.NUIOpen = false self:TogglePanel2(false) end Wait(1000) end end end) end function LR:NUI() if (IsPedInAnyVehicle(PlayerPedId(), false) or IsPlayerFreeAiming(PlayerId()) or IsPlayerDead(PlayerId())) and self.NUIOpen then self.NUIOpen = false self:TogglePanel2(false) elseif not self.NUIOpen and not IsPedInAnyVehicle(PlayerPedId(), false) and not IsPlayerFreeAiming(PlayerId()) and not IsPlayerDead(PlayerId()) then self.NUIOpen = true self:TogglePanel2(true) end local globalCurCapture = GlobalState.CurrentCapture if globalCurCapture[self.CurrentZone] ~= nil then local zone = Config.Occ[self.CurrentZone] self.canC = false self:SetDataPanel2({ type = "capturing", data = { name = zone.Label, point = zone.point, time = zone.time - (ostime - globalCurCapture[self.CurrentZone].startAt), player = globalCurCapture[self.CurrentZone].name } }) else local zone = GlobalState.Occ[self.CurrentZone] local d = ostime - GlobalState.LastCapture if d < Config.Delay then self.canC = false self:SetDataPanel2({ type = "blocked", data = { name = zone.Label, point = zone.point, time = Config.Delay - d } }) else if zone.lastCapture ~= nil then local d = ostime - zone.lastCapture if d < Config.DelayPoint then self.canC = false self:SetDataPanel2({ type = "blocked", data = { name = zone.Label, point = zone.point, owner = zone.owner, time = Config.DelayPoint - d } }) else if zone.owner ~= nil then self.canC = true self:SetDataPanel2({ type = "owned", data = { name = zone.Label, point = zone.point, owner = zone.owner } }) else self.canC = true self:SetDataPanel2({ type = "allow", data = { name = zone.Label, point = zone.point, time = zone.time } }) end end else if zone.owner ~= nil then self.canC = true self:SetDataPanel2({ type = "owned", data = { name = zone.Label, point = zone.point, owner = zone.owner } }) else self.canC = true self:SetDataPanel2({ type = "allow", data = { name = zone.Label, point = zone.point, time = zone.time } }) end end end end end function LR:TogglePanel2(t) SendNUIMessage({ event = "toggle-panel2", data = t }) end function LR:SetDataPanel2(data) SendNUIMessage({ event = "data-panel2", data = data }) end function LR:ShowNotification(type, msg, playSound) SendNUIMessage({ event = "notification", data = { type = type, msg = msg, playSound = playSound } }) end function LR:PulseBlipF(index) local zoneCoords = Config.Occ[index].Pos local Pblip = AddBlipForCoord(zoneCoords.x, zoneCoords.y, zoneCoords.z) SetBlipSprite(Pblip, 161) SetBlipScale(Pblip, 2.0) SetBlipColour(Pblip, 1) PulseBlip(Pblip) self.PulseBlip = Pblip end function LR:UnPulse() RemoveBlip(self.PulseBlip) self.PulseBlip = nil end ESX = nil Citizen.CreateThread(function() while ESX == nil do Wait(0) ESX = exports["es_extended"]:getSharedObject() end Wait(5000) while GlobalState.GangBlips == nil do Wait(100) end LR:Init() while true do Wait(1000) ostime = ostime + 1 if GlobalState.ostime > ostime then ostime = GlobalState.ostime end end end) RegisterCommand("thaneo", function() if IsPedInAnyBoat(PlayerPedId()) then local veh = GetVehiclePedIsIn(PlayerPedId(), false) local driver = GetPedInVehicleSeat(veh, -1) if driver == PlayerPedId() then FreezeEntityPosition(veh, true) else ESX.ShowNotification("Bạn phải lái phương tiện này") end else ESX.ShowNotification("Bạn phải ở trên tàu hoặc thuyền để sử dụng lệnh này") end end, false) RegisterCommand("huythaneo", function() if IsPedInAnyBoat(PlayerPedId()) then local veh = GetVehiclePedIsIn(PlayerPedId(), false) local driver = GetPedInVehicleSeat(veh, -1) if driver == PlayerPedId() then FreezeEntityPosition(veh, false) else ESX.ShowNotification("Bạn phải lái phương tiện này") end else ESX.ShowNotification("Bạn phải ở trên tàu hoặc thuyền để sử dụng lệnh này") end end, false) ShowHelpNotification = function(msg, thisFrame, beep, duration) AddTextEntry('esxHelpNotification', "" .. msg .. "") if thisFrame then DisplayHelpTextThisFrame('esxHelpNotification', false) else if beep == nil then beep = true end BeginTextCommandDisplayHelp('esxHelpNotification') EndTextCommandDisplayHelp(0, false, beep, duration or -1) end end