557 lines
21 KiB
Lua
557 lines
21 KiB
Lua
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
|