commit 5410b49c449f0e90e4319e7625d6b4aae8aea558 Author: LORAX Date: Sun Jul 21 09:07:35 2024 +0700 z diff --git a/client/main.lua b/client/main.lua new file mode 100644 index 0000000..4c75d50 --- /dev/null +++ b/client/main.lua @@ -0,0 +1,556 @@ +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 diff --git a/client/main_bk.lua b/client/main_bk.lua new file mode 100644 index 0000000..d693d1d --- /dev/null +++ b/client/main_bk.lua @@ -0,0 +1,299 @@ +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 diff --git a/client/main_bk2.lua b/client/main_bk2.lua new file mode 100644 index 0000000..54c32f3 --- /dev/null +++ b/client/main_bk2.lua @@ -0,0 +1,324 @@ +ESX = nil +LR = {} +LR.__index = LR + +function LR:Init() + local o = {} + setmetatable(o, LR) + o.Capturing = false + o.CurZone = nil + o.InZone = false + o.Blips = {} + o.RadiusBlips = {} + ESX.TriggerServerCallback("lr_occ:callback:getData", function(data) + print(ESX.DumpTable(data)) + o.Zones = data[1] + o.DelayTime = data[2] + o:EventHandler() + o:PosThread() + o:Blip() + o:TimeThread() + end) + + return o +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 <= 5.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_occ: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()) or IsPlayerDead(PlayerId())) and self.Panel2Open then + self:TogglePanel2(false) + elseif not self.Panel2Open and not IsPedInAnyVehicle(self.ped, false) and not IsPlayerFreeAiming(PlayerId()) and not IsPlayerDead(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_occ:server:cancelCapture") + end + else + self.Capturing = false + TriggerServerEvent("lr_occ:server:cancelCapture") + end + end + end) +end + +function LR:CheckPos() + for k, v in pairs(self.Zones) 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 + + return k + end + end + if self.InZone then + self.InZone = false + self:TogglePanel2(false) + --self:TogglePanel3(false) + end + return nil +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:TimeThread() + Citizen.CreateThread(function() + while true do + Wait(1000) + for k, v in pairs(self.Zones) do + if v.open then + if v.playerCaptureName ~= nil then + if v.CaptureTime > 0 then + v.CaptureTime = v.CaptureTime - 1 + end + end + end + end + if self.DelayTime > 0 then + self.DelayTime = self.DelayTime - 1 + end + if self.CurZone ~= nil then + local v = self.Zones[self.CurZone] + if v.open then + if self.DelayTime > 0 then + self:SetDataPanel2({ + type = "blocked", + data = { + name = v.Label, + time = self.DelayTime + } + }) + else + if v.playerCaptureName ~= nil then + self:SetDataPanel2({ + type = "capturing", + data = { + name = v.Label, + point = v.point, + time = v.CaptureTime, + player = v.playerCaptureName + } + }) + else + self:SetDataPanel2({ + type = "allow", + data = { + name = v.Label, + point = v.point, + time = v.time + } + }) + end + end + else + self:SetDataPanel2({ + type = "closed", + data = { + name = v.Label + } + }) + end + end + end + end) +end + +function LR:EventHandler() + RegisterNetEvent("lr_occ:client:startCapture", function(index, data) + self.Zones[index] = data + self:ShowNotification("warning", + ("%s đang bị chiếm bởi %s"):format(self.Zones[index].Label, self.Zones[index].playerCaptureName), true) + self:PulseBlip(index) + end) + RegisterNetEvent("lr_occ:client:cancelCapture", function(index, data) + local zone = self.Zones[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 này ngay bây giờ"):format( + zone.playerCaptureName, zone.Label)) + self.Zones[index].playerCaptureName = nil + self.Zones[index].playerCaptureSource = nil + self.Zones[index].playerCaptureTime = nil + self.Zones[index].CaptureTime = self.Zones[index].time + self:UnPulse() + end) + RegisterNetEvent("lr_occ:client:showNotification", function(...) + self:ShowNotification(...) + end) + RegisterNetEvent("lr_occ:client:captured", function(index, data) + if self.CurZone == index then + SetCurrentPedWeapon(PlayerPedId(), "WEAPON_UNARMED", true) + end + self:ShowNotification("success", + ("%s đã chiếm thành công %s mang về %s điểm cho %s"):format(data.playerCaptureName, data.Label, data.point, + data.owner)) + self.Zones[index] = data + self:UnPulse() + self.DelayTime = Config.Delay + self:Blip() + end) + RegisterNetEvent("lr_occ:client:openMain", function(index, data) + self:ShowNotification("success", + "Khu vực chính đã được mở, các băng đảng có thể tiến hành chiếm đóng ngay bây giờ !!") + self.Zones[index] = data + self.DelayTime = 600 + self:Blip() + end) +end + +function LR:ShowNotification(type, msg, playSound) + SendNUIMessage({ + event = "notification", + data = { + type = type, + msg = msg, + playSound = playSound + } + }) +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:Blip() + for k, v in pairs(self.Blips) do + RemoveBlip(v) + end + self.Blips = {} + for k, v in pairs(self.RadiusBlips) do + RemoveBlip(v) + end + self.RadiusBlips = {} + for k, v in pairs(self.Zones) do + if v.open and v.owner == nil then + local blip = AddBlipForCoord(v.Pos.x, v.Pos.y, v.Pos.z) + SetBlipSprite(blip, 420) + SetBlipDisplay(blip, 2) + SetBlipScale(blip, 0.9) + 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 + else + local blip = AddBlipForCoord(v.Pos.x, v.Pos.y, v.Pos.z) + SetBlipSprite(blip, 420) + SetBlipDisplay(blip, 2) + SetBlipScale(blip, 0.9) + SetBlipColour(blip, 5) + SetBlipAsShortRange(blip, true) + SetBlipHighDetail(blip, true) + BeginTextCommandSetBlipName("STRING") + AddTextComponentString(("Khu Vực Chiếm Đóng [%s]"):format(string.upper(v.owner or k))) + EndTextCommandSetBlipName(blip) + self.Blips[k] = blip + end + local Ablip = AddBlipForRadius(v.Pos.x, v.Pos.y, v.Pos.z, v.Radius) + SetBlipColour(Ablip, 1) + SetBlipAlpha(Ablip, 100) + SetBlipHighDetail(Ablip, true) + SetBlipRotation(Ablip, 0.0) + SetBlipDisplay(Ablip, 4) + SetBlipAsShortRange(Ablip, false) + self.RadiusBlips[k] = Ablip + end + --self:PulseBlip("main") + print("LOADED BLIPS") +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 diff --git a/config.lua b/config.lua new file mode 100644 index 0000000..7508383 --- /dev/null +++ b/config.lua @@ -0,0 +1,140 @@ +Config = {} +Config.Occ = { + ['1'] = { + Pos = vector3(1003.8855, 2367.1669, 51.728935), + Label = "Công trường", + Radius = 200.0, + oRadius = 300.0, + cRadius = 50.0, + time = 600, + point = 500, + open = true + }, + ['2'] = { + Pos = vector3(-1336.3525, -3043.8943, 13.9444), + Label = "Sân bay", + Radius = 200.0, + oRadius = 300.0, + cRadius = 50.0, + time = 600, + point = 500, + open = true + }, + ['3'] = { + Pos = vector3(-425.4942, 1123.6724, 325.8549), + Label = "Đài Thiên Văn", + Radius = 200.0, + oRadius = 300.0, + cRadius = 50.0, + time = 600, + point = 500, + open = true + }, + ['4'] = { + Pos = vector3(-2329.2976, 3043.7192, 32.8146), + Label = "Doanh Trại Quân Đội", + Radius = 200.0, + oRadius = 300.0, + cRadius = 50.0, + time = 600, + point = 500, + open = true + }, + ['5'] = { + Pos = vector3(2834.1601, 1528.3621, 24.56747), + Label = "Nhà máy điện", + Radius = 200.0, + oRadius = 300.0, + cRadius = 50.0, + time = 600, + point = 500, + open = true + }, + --[[ ['5'] = { + Pos = vector3(5136.1894, -5144.942, 2.1036267), + Label = "Đảo kho báu", + oRadius = 100.0,, + oRadius = 150.0, + cRadius = 50.0, + time = 600, + point = 500, + open = false + }, ]] + ['6'] = { + Pos = vector3(56.695755, 3709.9353, 39.75494), + Label = "Khu ổ chuột", + Radius = 200.0, + oRadius = 300.0, + cRadius = 50.0, + time = 600, + point = 500, + open = false + }, + --[[ ['7'] = { + Pos = vector3(979.18133, -3006.66, 5.9007616), + Label = "Tàu chở hàng", + oRadius = 100.0,, + oRadius = 150.0, + cRadius = 50.0, + time = 600, + point = 500, + open = false + }, ]] +} + +Config.Delay = 600 +Config.DelayPoint = 600 +Config.ExceptJobs = { + ["unemployed"] = false, + ["police"] = false, + ["ambulance"] = false, + ["mechanic"] = false, + ["ALS"] = true, + ["LORD"] = true, + ["DALTONII"] = true, + ["CHAMPION"] = true, + ["AOE"] = true, + ["GC"] = true, + ["DN"] = true +} +Config.BlockVehicle = { + [`trash`] = true, + [`boxville`] = true, + [`Pounder`] = true, + [`moonbeam`] = true, + [`burrito3`] = true, + [`surfer`] = true, + [`boxville4`] = true, + [`minivan`] = true, + [`minivan2`] = true, + [`youga`] = true, + [`youga2`] = true, + [`youga3`] = true, + [`surfer2`] = true, + [`dubsta3`] = true, + [`bison2`] = true, + [`bison3`] = true, + [`rumpo2`] = true, + [`rumpo3`] = true, + [`bobcatxl`] = true, + [`bison`] = true, + [`gburrito2`] = true, + [`burrito2`] = true, + [`journey`] = true, + [`rumpo`] = true, + [`packer`] = true, + [`tr3`] = true, + [`phantom`] = true, + [`trailers2`] = true, + [`trailers3`] = true, + [`tr4`] = true, + [`tr2`] = true, + [`barracks2`] = true, + [`armytrailer`] = true, + [`armytrailer2`] = true, + [`trailerlogs`] = true, + [`trflat`] = true, + [`topolm`] = true, + + +} diff --git a/fxmanifest.lua b/fxmanifest.lua new file mode 100644 index 0000000..9d378a5 --- /dev/null +++ b/fxmanifest.lua @@ -0,0 +1,24 @@ +fx_version 'cerulean' +games { 'gta5' } +author 'Lorax' +description 'Training System' +version '1.0.0' +-- What to run +client_scripts { + 'config.lua', + 'client/main.lua' +} +server_scripts { + '@oxmysql/lib/MySQL.lua', + 'config.lua', + 'server/main.lua' +} +ui_page "html/index.html" +files { + "html/index.html", + "html/app.js", + "html/style.css", + 'html/sound/attention.mp3' +} +shared_script { '@ox_lib/init.lua' } +lua54 'yes' diff --git a/html/app.js b/html/app.js new file mode 100644 index 0000000..8716cbc --- /dev/null +++ b/html/app.js @@ -0,0 +1,155 @@ +$(document).ready(function(){ + var x = document.getElementById("myAudio"); + var canvas = document.getElementById("canvas"); + var ctx = canvas.getContext("2d"); + ctx.canvas.width = window.innerWidth / 100 * 20; + ctx.canvas.height = window.innerHeight / 100 * 30; + ctx.beginPath(); + ctx.rect(0, 0, ctx.canvas.width, ctx.canvas.height); + /* ctx.fillStyle = "red"; + ctx.fill(); */ + function drawStar(cx,cy,spikes,outerRadius,innerRadius){ + var rot=Math.PI/2*3; + var x=cx; + var y=cy; + var step=Math.PI/spikes; + + ctx.beginPath(); + ctx.moveTo(cx,cy-outerRadius) + for(i=0;iKhu vực chiếm đóng +

${info.name}

+

Điểm: ${info.point}

+

${info.time}

+ `) + if (info.owner){ + $("#panel-2").append(` +

Khu vực của: ${info.owner}

+ `) + } + break; + case "capturing": + SetColor($("#panel-2"), "warning"); + $("#panel-2").append(` +

Khu vực chiếm đóng

+

${info.time}

+

${info.name}

+

Điểm: ${info.point}

+

Đang Chiếm Bởi: ${info.player}

+ `) + break; + case "allow": + SetColor($("#panel-2"), "success"); + $("#panel-2").append(` +

Khu vực chiếm đóng

+

${info.name}

+

Điểm: ${info.point}

+

Thời gian chiếm: ${info.time} giây

+

Có thể chiếm

+ `) + break; + case "owned": + SetColor($("#panel-2"), "warning"); + $("#panel-2").append(` +

Khu vực chiếm đóng

+

${info.name}

+

Điểm: ${info.point}

+

Khu vực của: ${info.owner}

+ `) + break; + case "closed": + SetColor($("#panel-2"), "error"); + $("#panel-2").append(` +

Khu vực chiếm đóng

+

Chưa mở

+

${info.name}

+ `) + break; + default: + } + + + break; + case "toggle-panel2": + if (data == true){ + $("#panel-2").fadeIn(); + }else{ + $("#panel-2").fadeOut(); + } + break; + case "data-panel3": + $("#panel-3 h3").text(data) + break; + case "notification": + SetColor($("#panel-3"), data.type); + $("#panel-3 h3").text(data.msg); + $("#panel-3").fadeIn(); + if(data.playSound){ + x.play(); + x.volume = 0.1; + } + setTimeout(function(){ + $("#panel-3").fadeOut(); + }, 10000) + break; + default: + } + }) +}) \ No newline at end of file diff --git a/html/index.html b/html/index.html new file mode 100644 index 0000000..9987a5a --- /dev/null +++ b/html/index.html @@ -0,0 +1,33 @@ + + + + + + + + + + Document + + + + + + + + + + \ No newline at end of file diff --git a/html/sound/1.mp3 b/html/sound/1.mp3 new file mode 100644 index 0000000..c8a02ef Binary files /dev/null and b/html/sound/1.mp3 differ diff --git a/html/sound/attention.mp3 b/html/sound/attention.mp3 new file mode 100644 index 0000000..be7b520 Binary files /dev/null and b/html/sound/attention.mp3 differ diff --git a/html/style.css b/html/style.css new file mode 100644 index 0000000..b4ce732 --- /dev/null +++ b/html/style.css @@ -0,0 +1,77 @@ +@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@200&display=swap'); +@import url('https://fonts.googleapis.com/css2?family=Anton&display=swap'); +body{ + font-family: 'Montserrat', sans-serif; + color: #bb371a; + text-transform: uppercase; + -webkit-text-stroke-width: 1px; + -webkit-text-stroke-color: rgba(0, 0, 0, 0.152); +} +h1 { + font-family: 'Anton', sans-serif; + text-align: center; +} +h3{ + text-align: center; +} + +#panel-1{ + position: absolute; + top: 50%; + transform: translateY(-20vh); + width: 20vw; + height: 40vh; + clip-path: polygon(95% 0, 100% 5%, 100% 100%, 0 100%, 0 0); + padding: .3rem; + --grad:transparent 49.5%,#f7fd04 50%; + background: linear-gradient(to top right,var(--grad)) top right,white; + background-size:calc(5% + 4px) calc(5% + 4px); /* 10px of the clip-path + 4px of border */ + background-repeat:no-repeat; + background-origin:border-box; + background-color: #f7fd0469; +} +#panel-2{ + position: absolute; + left: 50%; + bottom: 0; + width: 17vw; + height: auto; + transform: translateX(calc(-17vw / 2)); + padding: .3rem; +} +#panel-3{ + position: absolute; + right: 0; + bottom: 76%; + width: 20vw; + height: auto; + background-color: #f7fd04; + clip-path: polygon(5% 0, 100% 0, 100% 100%, 0 100%, 0 15%); + padding: .3rem; + --grad:transparent 49.5%,#f7fd04 50%; + background: linear-gradient(to top left,var(--grad)) top left,white; + background-size:calc(5% + 4px) calc(15% + 4px); /* 10px of the clip-path + 4px of border */ + background-repeat:no-repeat; + background-origin:border-box; + background-color: #f7fd0469; +} +h1{ + /* padding-bottom: 2rem; */ +} +.info{ + text-align: center; + margin: .4rem; +} + +.success{ + border: 3px solid #9ede73; + background-color: #9ede7369; +} +.warning{ + background-color: #f7fd0469; +} +.error{ + border: 3px solid #f54748; + background-color: #f5474869; + color:#252525; +} \ No newline at end of file diff --git a/server/main.lua b/server/main.lua new file mode 100644 index 0000000..cbf5482 --- /dev/null +++ b/server/main.lua @@ -0,0 +1,452 @@ +ESX = exports["es_extended"]:getSharedObject() +playerCache = {} + +function GetPlayerFromCache(source) + if playerCache[tonumber(source)] == nil then + playerCache[tonumber(source)] = ESX.GetPlayerFromId(source) + end + return playerCache[tonumber(source)] +end + +LR = {} +LR.__index = LR +local playerInZone = {} +local os_time = os.time +local coroutine_yield = coroutine.yield +function LR:Init() + local o = {} + setmetatable(o, LR) + o.LastCapture = 0 + o.Zones = Config.Occ + o.ZoneData = {} + o.CurrentCapture = {} + o.IsOpen = false + GlobalState.LastCapture = 0 + GlobalState.CurrentCapture = {} + GlobalState.Occ = o.Zones + o.OnDev = false + o.PressedPLayer = {} + o:EventHandler() + o:DelayThread() + o:SQL() + GlobalState.ostime = 0 + GlobalState.GangBlips = { + ['HM'] = { + sprite = 16, + color = 1 + }, + ['LORD'] = { + sprite = 77, + color = 1 + }, + ['HLG'] = { + sprite = 355, + color = 1 + }, + ['ALS'] = { + sprite = 76, + color = 1 + }, + ['AOE'] = { + sprite = 78, + color = 1 + }, + ['GC'] = { + sprite = 80, + color = 1 + }, + + + + } + GlobalState.OccOpen = o.IsOpen + return o +end + +function LR:SQL() + MySQL.ready(function() + for k, v in pairs(self.Zones) do + local data = MySQL.Sync.fetchAll("SELECT * FROM occ_data WHERE `index` = @index", { ['@index'] = k }) + if data[1] then + v.owner = data[1].owner + else + MySQL.Sync.execute("INSERT INTO occ_data (`index`, owner) VALUE (@index, @owner)", + { ['@index'] = k, ['@owner'] = v.owner }) + end + self.ZoneData[k] = {} + end + GlobalState.Occ = self.Zones + GlobalState.ZoneData = self.ZoneData + end) +end + +function LR:DelayThread() + --GlobalState.OccDelay = 0 + -- Citizen.CreateThread(function() + -- while true do + -- Wait(1000) + -- local d = os_time() - self.LastCapture + -- GlobalState.ostime = os_time() + -- end + -- end) + + Citizen.CreateThread(function() + while true do + Wait(10 * 60 * 1000) + for k, v in pairs(self.Zones) do + if v.owner then + -- MySQL.Async.execute('UPDATE dh_rank SET scores = scores + @point WHERE name = @name', { + -- ['@name'] = v.owner, + -- ['@point'] = 5 + -- }) + + MySQL.Async.execute('UPDATE jobs SET point = point + @point WHERE name = @name', { + ['@name'] = v.owner, + ['@point'] = 5 + }) + end + end + end + end) +end + +function LR:EventHandler() + AddEventHandler("playerDropped", function(reason) + if playerCache[tonumber(source)] then + if playerInZone[source] then + local org = playerCache[tonumber(source)].job.name + for k, v in pairs(self.ZoneData) do + if v[org] then + v[org] = v[org] - 1 + if v[org] == 0 then + v[org] = nil + end + GlobalState.ZoneData = self.ZoneData + break + end + end + playerInZone[source] = nil + end + playerCache[tonumber(source)] = nil + end + end) + AddEventHandler("esx:setJob", function(playerId, _org, lastorg) + if playerInZone[playerId] then + local org = lastorg.name + local neworg = _org.name + for k, v in pairs(self.ZoneData) do + if v[org] then + v[org] = v[org] - 1 + if v[org] == 0 then + v[org] = nil + end + if v[neworg] then + v[neworg] = v[neworg] + 1 + else + v[neworg] = 1 + end + GlobalState.ZoneData = self.ZoneData + break + end + end + end + end) + RegisterNetEvent("lr_occ2:server:join", function(index) + local src = source + print(src) + print(src) + local xPlayer = GetPlayerFromCache(source) + local org = xPlayer.job.name + if self.ZoneData[index][org] then + if self.ZoneData[index][org] == 30 then --so nguoi chiem dong + SetEntityCoords(GetPlayerPed(source), 236.00483703613, -876.13092041016, 30.031923294067, false, false, + false, false) + TriggerClientEvent("esx:showNotification", source, "Vượt quá số người cho phép") + else + playerInZone[source] = true + -- SetPlayerRoutingBucket(src, 10) + self.ZoneData[index][org] = self.ZoneData[index][org] + 1 + end + else + playerInZone[source] = true + self.ZoneData[index][org] = 1 + end + GlobalState.ZoneData = self.ZoneData + end) + RegisterNetEvent("lr_occ2:server:leave", function(index) + local src = source + -- print(src) + -- print(src) + local xPlayer = GetPlayerFromCache(source) + local org = xPlayer.job.name + if self.ZoneData[index][org] and playerInZone[source] then + self.ZoneData[index][org] = self.ZoneData[index][org] - 1 + if self.ZoneData[index][org] == 0 then + self.ZoneData[index][org] = nil + end + GlobalState.ZoneData = self.ZoneData + playerInZone[source] = nil + -- SetPlayerRoutingBucket(src, 0) + end + end) + ESX.RegisterServerCallback('lr_occ2:callback:cC', function(source, cb, index) + if self.IsOpen then + if os_time() - self.LastCapture >= Config.Delay then + local crZone = self.Zones[index] + if crZone.lastCapture == nil or os_time() - crZone.lastCapture >= Config.DelayPoint then + if self.CurrentCapture[index] == nil then + if getLenght(self.CurrentCapture) < 1 then + local xPlayer = ESX.GetPlayerFromId(source) + if not self.PressedPLayer[xPlayer.identifier] then + if crZone.owner and crZone.owner == xPlayer.job.name then + self:TriggerClientEvent(source, ("Khu vực này đã thuộc về bạn")) + cb(false) + return + end + cb(true) + else + cb(false) + self:TriggerClientEvent(source, + ("Hiện có khu vực đang bị chiếm nên không thể chiếm khu vực này")) + end + else + cb(false) + self:TriggerClientEvent(source, + ("Hiện có khu vực đang bị chiếm nên không thể chiếm khu vực này")) + end + else + cb(false) + self:TriggerClientEvent(source, + ("Khu vực %s đang bị chiếm bởi %s"):format(crZone.Label, self.CurrentCapture[index].name)) + end + else + cb(false) + self:TriggerClientEvent(source, + ("Cần %s giây để có thể chiếm khu vực %s"):format( + Config.Delay - (os_time() - crZone.lastCapture), crZone.Label)) + end + else + cb(false) + self:TriggerClientEvent(source, + ("Cần %s giây để có thể chiếm"):format(Config.Delay - (os_time() - self.LastCapture))) + end + else + cb(false) + self:TriggerClientEvent(source, "Chưa đến thời gian chiếm đóng") + end + end) + ESX.RegisterServerCallback("lr_occ2:callback:CanCapture", function(source, cb, index, moves) + local xPlayer = ESX.GetPlayerFromId(source) + if self.OnDev then + if xPlayer.group ~= 'superadmin' then + cb(false) + return + end + end + if self.IsOpen then + print(os_time() - self.LastCapture) + if os_time() - self.LastCapture >= Config.Delay then + local crZone = self.Zones[index] + if crZone.lastCapture == nil or os_time() - crZone.lastCapture >= Config.DelayPoint then + if self.CurrentCapture[index] == nil then + if getLenght(self.CurrentCapture) < 1 then + local xPlayer = ESX.GetPlayerFromId(source) + if not self.PressedPLayer[xPlayer.identifier] then + if crZone.owner and crZone.owner == xPlayer.job.name then + self:TriggerClientEvent(source, ("Khu vực này đã thuộc về bạn")) + cb(false) + return + end + if not Config.ExceptJobs[xPlayer.job.name] then + self:TriggerClientEvent(source, ("Tổ chức của bạn không có quyền chiếm đóng")) + return + end + --self.PressedPLayer[xPlayer.identifier] = true + self.CurrentCapture[index] = { + name = xPlayer.name, + playerId = source, + startAt = os_time() + } + --self.LastCapture = os_time() + crZone.lastCapture = os_time() + GlobalState.Occ = self.Zones + GlobalState.CurrentCapture = self.CurrentCapture + GlobalState.LastCapture = os_time() - 480 + TriggerClientEvent("lr_occ2:client:startCapture", -1, index, "[" .. xPlayer.job.name .. "] " .. xPlayer + .name) + self.crC = index + cb(true) + Citizen.CreateThread(function() + local time = crZone.time + os_time() + while true do + coroutine_yield(0) + if self.CurrentCapture[index] ~= nil then + Wait(1000) + if time <= os_time() then + if crZone.owner == nil then + + else + self:RemovePoint(crZone.owner, crZone.point) + end + crZone.owner = xPlayer.job.name + crZone.lastCapture = os_time() + self.LastCapture = os_time() + self.CurrentCapture[index] = nil + GlobalState.Occ = self.Zones + GlobalState.CurrentCapture = self.CurrentCapture + GlobalState.LastCapture = os_time() + TriggerClientEvent("lr_occ:client:captured", -1, index, xPlayer.name, + xPlayer.job.name) + self:AddPoint(xPlayer.job.name, crZone.point, index) + break + end + else + self.CurrentCapture[index] = nil + GlobalState.CurrentCapture = self.CurrentCapture + print("Canceled") + break + end + end + end) + else + cb(false) + self:TriggerClientEvent(source, + ("Hiện có khu vực đang bị chiếm nên không thể chiếm khu vực này")) + end + else + cb(false) + self:TriggerClientEvent(source, + ("Hiện có khu vực đang bị chiếm nên không thể chiếm khu vực này")) + end + else + cb(false) + self:TriggerClientEvent(source, + ("Khu vực %s đang bị chiếm bởi %s"):format(crZone.Label, self.CurrentCapture[index].name)) + end + else + cb(false) + self:TriggerClientEvent(source, + ("Cần %s giây để có thể chiếm khu vực %s"):format( + Config.Delay - (os_time() - crZone.lastCapture), crZone.Label)) + end + else + cb(false) + self:TriggerClientEvent(source, + ("Cần %s giây để có thể chiếm"):format(Config.Delay - (os_time() - self.LastCapture))) + end + else + cb(false) + self:TriggerClientEvent(source, "Chưa đến thời gian chiếm đóng") + end + end) + + RegisterCommand("chiemdong", function(source, args, rawCommand) + if self.IsOpen then + TriggerClientEvent("hm_hud:client:addCD", -1, 5 * 10, 'chiếm đóng', 'Kết thúc sau', 'warning', + 'fas fa-skull-crossbones') + else + TriggerClientEvent("hm_hud:client:addCD", -1, 5 * 10, 'chiếm đóng', 'Bắt đầu sau', 'warning', + 'fas fa-skull-crossbones') + end + Wait(10 * 1000) + self.IsOpen = not self.IsOpen + GlobalState.OccOpen = self.IsOpen + TriggerClientEvent("lr_occ2:client:openOcc", -1, self.IsOpen) + end, true) + + -- RegisterCommand("vaochiemdong", function(source, args, rawCommand) + -- if self.IsOpen then + -- SetPlayerRoutingBucket(source, 10) + -- end + -- end, false) + + RegisterCommand("thoatchiemdong", function(source, args, rawCommand) + SetPlayerRoutingBucket(source, 0) + end, false) + + AddEventHandler("esx:playerDropped", function(playerId) + for k, v in pairs(self.CurrentCapture) do + if v.playerId == playerId then + self.CurrentCapture[k] = nil + self.LastCapture = os_time() - 480 + --self.Zones[k].lastCapture = os_time() + TriggerClientEvent("lr_occ:client:cancelCapture", -1, k, "") + GlobalState.LastCapture = os_time() - 480 + return + end + end + end) + + RegisterNetEvent("lr_occ2:server:cancelCapture", function() + for k, v in pairs(self.CurrentCapture) do + if v.playerId == source then + local xPlayer = ESX.GetPlayerFromId(source) + self.LastCapture = os_time() - 480 + GlobalState.LastCapture = os_time() - 480 + self.CurrentCapture[k] = nil + --self.LastCapture = os_time() + self.Zones[k].lastCapture = os_time() - 1200 + GlobalState.Occ = self.Zones + TriggerClientEvent("lr_occ:client:cancelCapture", -1, k, "[" .. xPlayer.job.name .. "] " .. xPlayer.name) + return + end + end + end) + + --[[RegisterNetEvent("lr_occ:server:addPoint", function(gang, point) + local data = MySQL.Sync.fetchAll("SELECT * FROM dh_rank WHERE `name` = @name", {['@name'] = gang}) + if data[1] then + MySQL.Async.execute('UPDATE dh_rank SET scores = scores + @scores WHERE name = @name', { + ['@name'] = gang, + ['@scores'] = tonumber(point) + }) + end + end)--]] + + RegisterCommand("occdev", function(source, args, rawCommand) + self.OnDev = not self.OnDev + end) + lib.callback.register("lr_occ2:callback:getCurCapture", function(source) + return self.crC + end) +end + +function LR:TriggerClientEvent(playerId, msg) + TriggerClientEvent("esx:showNotification", playerId, msg) +end + +function LR:AddPoint(orgName, point, index) + MySQL.Async.execute('UPDATE jobs SET point = point + @point WHERE name = @name', { + ['@name'] = orgName, + ['@point'] = point + }) + --[[MySQL.Async.execute('UPDATE dh_rank SET scores = scores + @point WHERE name = @name', { + ['@name'] = orgName, + ['@point'] = point + })--]] + MySQL.Async.execute("UPDATE occ_data SET owner = @owner WHERE `index` = @index", { + ['@owner'] = orgName, + ['@index'] = index + }) +end + +function LR:RemovePoint(orgName, point) + MySQL.Async.execute('UPDATE jobs SET point = point - @point WHERE name = @name', { + ['@name'] = orgName, + ['@point'] = point + }) + --[[MySQL.Async.execute('UPDATE dh_rank SET scores = scores - @point WHERE name = @name', { + ['@name'] = orgName, + ['@point'] = point + })--]] +end + +function getLenght(tb) + local c = 0 + for k, v in pairs(tb) do + c = c + 1 + end + return c +end + +LR:Init()