mirror of
https://github.com/esx-framework/esx_core.git
synced 2026-09-03 11:48:53 +00:00
single resource concept + first attempt to reorganize code
This commit is contained in:
@@ -0,0 +1,194 @@
|
||||
local self = ESX.Modules['interact']
|
||||
|
||||
self.LOVE_PLAYER_GROUP = AddRelationshipGroup('LOVE_PLAYER')
|
||||
|
||||
SetRelationshipBetweenGroups(0, self.LOVE_PLAYER_GROUP, 'PLAYER')
|
||||
|
||||
Citizen.CreateThread(function()
|
||||
|
||||
while true do
|
||||
|
||||
Citizen.Wait(100)
|
||||
|
||||
local ped = PlayerPedId()
|
||||
local coords = GetOffsetFromEntityInWorldCoords(ped, 0.0, 0.0, -1.0)
|
||||
|
||||
self.Cache.player.ped = ped
|
||||
self.Cache.player.coords = vector3(table.unpack(coords))
|
||||
|
||||
local toRemove = {}
|
||||
|
||||
for i=1, #self.Data, 1 do
|
||||
|
||||
local data = self.Data[i]
|
||||
|
||||
if data.pos == nil then
|
||||
|
||||
print('[esx_interact] data.pos is nil => ' .. json.encode(data))
|
||||
|
||||
else
|
||||
|
||||
local distance = #(data.pos - self.Cache.player.coords);
|
||||
if
|
||||
(distance <= data.distance) and
|
||||
(ESX.Table.FindIndex(self.Cache.current, function(e) return e.__id == data.__id end) == -1)
|
||||
then
|
||||
|
||||
if (data.check == nil) or data.check(self.Cache.player.ped, self.Cache.player.coords) then
|
||||
data.playing = false
|
||||
self.Cache.current[#self.Cache.current + 1] = data
|
||||
end
|
||||
|
||||
elseif (distance > data.distance) then
|
||||
|
||||
local idx = ESX.Table.FindIndex(self.Cache.current, function(e) return e.__id == data.__id end)
|
||||
|
||||
if idx ~= -1 then
|
||||
toRemove[#toRemove + 1] = idx
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if #toRemove > 0 then
|
||||
self.Cache.current = ESX.Table.Filter(self.Cache.current, function(e) return ESX.Table.IndexOf(toRemove, e.__id) ~= -1 end)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end)
|
||||
|
||||
-- Markers
|
||||
Citizen.CreateThread(function()
|
||||
while true do
|
||||
|
||||
Citizen.Wait(0)
|
||||
|
||||
for i=1, #self.Cache.current, 1 do
|
||||
|
||||
local curr = self.Cache.current[i]
|
||||
|
||||
if curr.type == 'marker' then
|
||||
|
||||
DrawMarker(
|
||||
curr.mtype,
|
||||
curr.pos.x + 0.0, curr.pos.y + 0.0, curr.pos.z + 0.0,
|
||||
0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0,
|
||||
curr.size.x + 0.0, curr.size.y + 0.0, curr.size.z + 0.0,
|
||||
curr.color.r, curr.color.g, curr.color.b, curr.color.a,
|
||||
curr.bobUpAndDown, curr.faceCamera, 2, curr.rotate, nil, nil, false
|
||||
)
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end)
|
||||
|
||||
-- NPCs
|
||||
Citizen.CreateThread(function()
|
||||
while true do
|
||||
|
||||
Citizen.Wait(1000)
|
||||
|
||||
for i=1, #self.Cache.current, 1 do
|
||||
|
||||
local curr = self.Cache.current[i]
|
||||
|
||||
if curr.type == 'npc' then
|
||||
|
||||
if IsModelValid(curr.model) and IsModelInCdimage(curr.model) then
|
||||
|
||||
local found = false
|
||||
|
||||
local closestPed, closestDistance = ESX.Game.GetClosestPed({
|
||||
x = curr.pos.x + 0.0,
|
||||
y = curr.pos.y + 0.0,
|
||||
z = curr.pos.z + 0.0
|
||||
}, {Cache.player.ped})
|
||||
|
||||
if closestPed ~= -1 then
|
||||
|
||||
local model = GetEntityModel(closestPed)
|
||||
|
||||
if (model == curr.model) and (closestDistance <= 10.0) then
|
||||
|
||||
found = true
|
||||
|
||||
if (curr.lib ~= nil) and (curr.anim ~= nil) then
|
||||
|
||||
if not HasAnimDictLoaded(curr.lib) then
|
||||
RequestAnimDict(curr.lib)
|
||||
end
|
||||
|
||||
if HasAnimDictLoaded(curr.lib) and (not curr.playing) then
|
||||
curr.playing = true
|
||||
TaskPlayAnim(closestPed, curr.lib, curr.anim, 8.0, -8.0, -1, 1, 1.0, false, false, false)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if not found then
|
||||
|
||||
print('Create ped : ' .. curr.model .. ' @ ' .. curr.pos.x .. ' ' .. curr.pos.y .. ' ' .. curr.pos.z)
|
||||
|
||||
RequestModel(curr.model)
|
||||
|
||||
while not HasModelLoaded(curr.model) do
|
||||
Citizen.Wait(0)
|
||||
end
|
||||
|
||||
curr.__ped = CreatePed(26, curr.model, curr.pos.x + 0.0, curr.pos.y + 0.0, curr.pos.z + 0.0, curr.heading + 0.0, true, false)
|
||||
|
||||
SetModelAsNoLongerNeeded(curr.model)
|
||||
|
||||
SetPedRelationshipGroupHash(curr.__ped, self.LOVE_PLAYER_GROUP)
|
||||
SetBlockingOfNonTemporaryEvents(curr.__ped, true)
|
||||
TaskStandStill(curr.__ped, -1)
|
||||
SetEntityInvincible(curr.__ped, true)
|
||||
FreezeEntityPosition(curr.__ped, true)
|
||||
|
||||
end
|
||||
|
||||
else
|
||||
print('Invalid/inexistent model => ' .. curr.model)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end)
|
||||
|
||||
Citizen.CreateThread(function()
|
||||
while true do
|
||||
|
||||
Citizen.Wait(100)
|
||||
|
||||
for i=1, #self.Cache.current, 1 do
|
||||
|
||||
local data = self.Cache.current[i]
|
||||
local distance = #(data.pos - self.Cache.player.coords);
|
||||
|
||||
if (distance <= data.radius) and (not self.Cache.using[data.__id]) then
|
||||
self.Cache.using[data.__id] = true
|
||||
TriggerEvent('esx:interact:enter', data.name, data)
|
||||
elseif (distance > data.radius) and self.Cache.using[data.__id] then
|
||||
self.Cache.using[data.__id] = nil
|
||||
TriggerEvent('esx:interact:exit', data.name, data)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end)
|
||||
Reference in New Issue
Block a user