ESX = nil LR = {} LR.__index = LR function LR:Init() local o = {} setmetatable(o, LR) o.PlayerData = {} if ESX.IsPlayerLoaded() then o.PlayerData = ESX.GetPlayerData() end o.InZone = false o.CurZone = nil o.Blips = {} o.PulseBlip = nil o.Busy = false o.Capturing = false o.Panel2Open = false o.RemainCapture = 0 o.CanCapture = true o.Cache = {} ESX.TriggerServerCallback("lr_occ2:callback:getData", function(data) o.Cache = data[1] o.RemainCapture = data[2] for k, v in pairs(o.Cache) do Citizen.CreateThread(function() local index = k while o.Cache[index] ~= nil and o.Cache[index].remain > 0 do Wait(1000) o.Cache[index].remain = o.Cache[index].remain - 1 if o.Cache[index].remain <= 0 then o.Cache[index] = nil end end end) end end) o:EventHandler() o:PosThread() o:Blip() o:TimeThread() print("LOADED LROCC") return o end function LR:TimeThread() Citizen.CreateThread(function() while true do Wait(1000) if self.RemainCapture > 0 then self.RemainCapture = self.RemainCapture - 1 self.CanCapture = false else self.CanCapture = true end end end) end function LR:EventHandler() RegisterNetEvent("esx:playerLoaded", function(xPlayer) self.PlayerData = xPlayer end) RegisterNetEvent("lr_occ2:client:capture", function(index, playerName) self:PulseBlip(index) self:ShowNotification(("Khu vực %s đang bị chiếm bởi %s"):format(Config.Occ[index].Label, playerName)) self.Cache[index] = { remain = Config.Occ[index].time, name = playerName } Citizen.CreateThread(function() local _index = index while self.Cache[_index] ~= nil and self.Cache[_index].remain > 0 do print(_index) Wait(1000) if self.Cache[_index] ~= nil then self.Cache[_index].remain = self.Cache[_index].remain - 1 if self.Cache[index].remain <= 0 then self.Cache[index] = nil end end end end) end) RegisterNetEvent("lr_occ2:client:captured", function(index, playerName) self:UnPulse() self.Cache[index] = nil self.RemainCapture = Config.Delay self:ShowNotification(("%s đã chiếm thành công khu vực %s"):format(playerName, Config.Occ[index].Label)) end) RegisterNetEvent("lr_occ2:client:cancel", function(index, playerName) self:UnPulse() self.Cache[index] = nil self:ShowNotification(("%s đã hủy chiếm %s"):format(playerName, Config.Occ[index].Label)) end) RegisterNetEvent("lr_occ2:client:showNotification", function(msg) self:ShowNotification(msg) end) end function LR:Blip() for k, v in pairs(Config.Occ) do local blip = AddBlipForCoord(v.Pos.x, v.Pos.y, v.Pos.z) SetBlipSprite(blip, 420) SetBlipDisplay(blip, 2) SetBlipScale(blip, 1.2) SetBlipColour(blip, 1) SetBlipAsShortRange(blip, true) SetBlipHighDetail(blip, true) BeginTextCommandSetBlipName("STRING") AddTextComponentString(("Khu Vực Chiếm Đóng [%s]"):format(k)) EndTextCommandSetBlipName(blip) self.Blips[k] = blip end --self:PulseBlip("main") print("LOADED BLIPS") end function LR:PulseBlip(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 function LR:PosThread() Citizen.CreateThread(function() while true do coroutine.yield(0) self.ped = PlayerPedId() self.pedCoords = GetEntityCoords(self.ped, true) self.CurZone = self:CheckPos() if self.CurZone ~= nil then local zoneCoords = Config.Occ[self.CurZone].Pos local distance = #(self.pedCoords - zoneCoords) DrawMarker(1, zoneCoords.x, zoneCoords.y, zoneCoords.z - 100.100, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Config.Occ[self.CurZone].Radius * 2, Config.Occ[self.CurZone].Radius * 2, 200.0, 255, 0, 0, 100, false, true, 2, nil, nil, false) DrawMarker(1, zoneCoords.x, zoneCoords.y, zoneCoords.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 distance <= 1.5 and not self.Busy and not self.Capturing then DisplayText("Nhấn [E] để chiếm khu vực này") if IsControlJustPressed(0, 38) then self.Busy = true ESX.TriggerServerCallback("lr_occ2:callback:canCapture", function(result) self.Busy = false if result == true then self.Capturing = true self:StartCapture(self.CurZone) end end, self.CurZone) end end if (IsPedInAnyVehicle(self.ped, false) or IsPlayerFreeAiming(PlayerId())) and self.Panel2Open then self:TogglePanel2(false) elseif not self.Panel2Open and not IsPedInAnyVehicle(self.ped, false) and not IsPlayerFreeAiming(PlayerId()) then self:TogglePanel2(true) end else Wait(2000) end end end) end function LR:StartCapture(index) Citizen.CreateThread(function() local time = Config.Occ[self.CurZone].time while self.Capturing do coroutine.yield(0) print(time) if self.CurZone ~= nil then Wait(1000) time = time - 1 if time <= 0 then self.Capturing = false end if IsPlayerDead(PlayerId()) then self.Capturing = false TriggerServerEvent("lr_occ2:server:cancelCapture") end else self.Capturing = false TriggerServerEvent("lr_occ2:server:cancelCapture") end end end) end function LR:StopCapture() self.Capturing = false end function LR:ShowNotification(msg) SendNUIMessage({ event = "notification", data = msg }) end function LR:CheckPos() for k, v in pairs(Config.Occ) do local distance = #(self.pedCoords - v.Pos) if distance <= v.Radius then if not self.InZone then self.InZone = true self:TogglePanel2(true) --self:TogglePanel3(true) end self:SetDataPanel2({ canCapture = self.CanCapture, lastCapture = self.RemainCapture, name = k, point = v.point, time = self.Cache[k] and self.Cache[k].remain or v.time, capture = self.Cache[k] and self.Cache[k].name or nil }) return k end end if self.InZone then self.InZone = false self:TogglePanel2(false) --self:TogglePanel3(false) end return nil end function LR:TogglePanel1(t) SendNUIMessage({ event = "toggle-panel1", data = t }) end function LR:SetDataPanel1(data) SendNUIMessage({ event = "data-panel1", data = data }) end function LR:TogglePanel2(t) self.Panel2Open = t SendNUIMessage({ event = "toggle-panel2", data = t }) end function LR:SetDataPanel2(data) SendNUIMessage({ event = "data-panel2", data = data }) end function LR:TogglePanel3(t) SendNUIMessage({ event = "toggle-panel3", data = t }) end function LR:SetDataPanel3(data) SendNUIMessage({ event = "data-panel3", data = data }) end Citizen.CreateThread(function() while ESX == nil do Wait(0) TriggerEvent("esx:getSharedObject", function(obj) ESX = obj end) end LR:Init() end) function DisplayText(text) local width = string.len(text) + 0.0 DrawRect(1.0 - width / 200 / 2, 0.98, width / 200, 0.06, 245, 71, 72, 200) SetTextScale(0.4, 0.4) SetTextFont(ESX.FontId) SetTextProportional(1) SetTextColour(255, 255, 255, 255) SetTextEntry("STRING") SetTextCentre(1) AddTextComponentString(text) DrawText(1.0 - width / 200 / 2, 0.96) end