This commit is contained in:
LORAX 2024-07-21 09:07:35 +07:00
commit 5410b49c44
11 changed files with 2060 additions and 0 deletions

556
client/main.lua Normal file
View File

@ -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', "<FONT FACE='arial font'>" .. msg .. "</FONT>")
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

299
client/main_bk.lua Normal file
View File

@ -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

324
client/main_bk2.lua Normal file
View File

@ -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

140
config.lua Normal file
View File

@ -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,
}

24
fxmanifest.lua Normal file
View File

@ -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'

155
html/app.js Normal file
View File

@ -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;i<spikes;i++){
x=cx+Math.cos(rot)*outerRadius;
y=cy+Math.sin(rot)*outerRadius;
ctx.lineTo(x,y)
rot+=step
x=cx+Math.cos(rot)*innerRadius;
y=cy+Math.sin(rot)*innerRadius;
ctx.lineTo(x,y)
rot+=step
}
ctx.lineTo(cx,cy-outerRadius);
ctx.closePath();
ctx.lineWidth=5;
ctx.strokeStyle='#39a9cb';
ctx.stroke();
ctx.fillStyle='skyblue';
ctx.fill();
}
drawStar(ctx.canvas.width/2,ctx.canvas.height/2,5,ctx.canvas.width/3.8,0);
function SetColor(element, className){
element.removeClass("success");
element.removeClass("warning");
element.removeClass("error");
element.addClass(className)
}
window.addEventListener("message", function(e){
let event = e.data.event;
let data = e.data.data;
switch(event){
case "data-panel2":
/* if (data.canCapture == true){
$("#panel-2 h1").text("Khu vực chiếm đóng");
$("#panel-2 #name").text(`Tên: ${data.name}`);
$("#panel-2 #point").text(`Điểm: ${data.point}`);
$("#panel-2 #time").text(`Thời gian chiếm: ${data.time} giây`);
if (data.capture != undefined){
$("#panel-2 #capture").text(`Đang chiếm bởi: ${data.capture}`);
}else{
$("#panel-2 #capture").text("Chưa có ai chiếm")
}
}else{
$("#panel-2 h1").text("Khu vực chiếm đóng");
$("#panel-2 #name").text(`cần ${data.lastCapture} giây nữa để có thể chiếm`);
$("#panel-2 #point").text(``);
$("#panel-2 #time").text(``);
$("#panel-2 #capture").text(``);
} */
let type = data.type;
let info = data.data;
$("#panel-2").empty();
switch(type){
case "blocked":
SetColor($("#panel-2"), "error");
$("#panel-2").append(`
<h1>Khu vực chiếm đóng</h1>
<h4 class="info">${info.name}</h4>
<h4 class="info">Điểm: ${info.point}</h4>
<h3 class="info">${info.time}</h3>
`)
if (info.owner){
$("#panel-2").append(`
<h4 class="info">Khu vực của: ${info.owner}</h4>
`)
}
break;
case "capturing":
SetColor($("#panel-2"), "warning");
$("#panel-2").append(`
<h1>Khu vực chiếm đóng</h1>
<h1 class="info">${info.time}</h1>
<h4 class="info">${info.name}</h4>
<h4 class="info">Điểm: ${info.point}</h4>
<h4 class="info">Đang Chiếm Bởi: ${info.player}</h4>
`)
break;
case "allow":
SetColor($("#panel-2"), "success");
$("#panel-2").append(`
<h1>Khu vực chiếm đóng</h1>
<h4 class="info">${info.name}</h4>
<h4 class="info">Điểm: ${info.point}</h4>
<h4 class="info">Thời gian chiếm: ${info.time} giây</h4>
<h4 class="info"> thể chiếm</h4>
`)
break;
case "owned":
SetColor($("#panel-2"), "warning");
$("#panel-2").append(`
<h1>Khu vực chiếm đóng</h1>
<h4 class="info">${info.name}</h4>
<h4 class="info">Điểm: ${info.point}</h4>
<h4 class="info">Khu vực của: ${info.owner}</h4>
`)
break;
case "closed":
SetColor($("#panel-2"), "error");
$("#panel-2").append(`
<h1>Khu vực chiếm đóng</h1>
<h1 class="info">Chưa mở</h1>
<h4 class="info">${info.name}</h4>
`)
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:
}
})
})

33
html/index.html Normal file
View File

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" type="text/css" href="https://unpkg.com/augmented-ui@2/augmented-ui.min.css">
<title>Document</title>
</head>
<body>
<audio id="myAudio">
<source src="sound/attention.mp3" type="audio/mpeg">
</audio>
<div id="panel-1" style="display: none;">
<h1>Thông tin chiếm đóng</h1>
<canvas id="canvas"></canvas>
</div>
<div id="panel-2" style="display: none;" data-augmented-ui="exe tl-clip tr-clip bl-clip br-clip inlay">
<!-- <h1>title2</h1>
<h4 class="info" id="name">asd</h4>
<h4 class="info" id="point">asd</h4>
<h4 class="info" id="time">asd</h4>
<h4 class="info" id="capture">asd</h4> -->
</div>
<div id="panel-3" style="display: none;" data-augmented-ui="exe tl-clip tr-clip bl-clip br-clip inlay">
<h3>title3</h3>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="app.js"></script>
</body>
</html>

BIN
html/sound/1.mp3 Normal file

Binary file not shown.

BIN
html/sound/attention.mp3 Normal file

Binary file not shown.

77
html/style.css Normal file
View File

@ -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;
}

452
server/main.lua Normal file
View File

@ -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()