localPlayer = PlayerId() localPlayerServerId = GetPlayerServerId(localPlayer) local crew, crewList, closest_players = {}, {}, {} function isCrewMember(serverId) if not table_is_empty(crew) then for _, member in ipairs(crew.members) do if member.server_id == serverId then return true end end end return false end AddEventHandler("playerSpawned", function() TriggerServerEvent(GetCurrentResourceName() .. ':updateMember', localPlayerServerId) end) function closestPlayers(dist) local ped = PlayerPedId() local peds = GetGamePool("CPed") local coords = GetEntityCoords(ped) local closest = {} for _, p in ipairs(peds) do if p ~= ped and IsPedAPlayer(p) then local netId = NetworkGetPlayerIndexFromPed(p) local serverId = GetPlayerServerId(netId) table.insert(closest, { ped = p, name = GetPlayerName(netId), server_id = serverId, distance = #(coords - GetEntityCoords(p)), is_crew_member = isCrewMember(serverId) }) end end return closest end ---------------------------------------------------------------------------- -- CLIENT EVENTS -- ---------------------------------------------------------------------------- RegisterNetEvent(GetCurrentResourceName() .. ":setCrew", function(data) crew = data end) RegisterNetEvent(GetCurrentResourceName() .. ":setCrewList", function(data) crewList = data end) RegisterNetEvent(GetCurrentResourceName() .. ":memberJoined", function(member) if not table_is_empty(crew) then table.insert(crew.members, member) SendNUIMessage({ action = "NOTIFY", data = { type = "info", message = _U("PlayerJoinedCrew", member.name) } }) end end) RegisterNetEvent(GetCurrentResourceName() .. ":memberLeft", function(member) if not table_is_empty(crew) then for i, mem in ipairs(crew.members) do if mem.token == member.token then SendNUIMessage({ action = "NOTIFY", data = { type = "info", message = _U("PlayerLeftCrew", member.name) } }) table.remove(crew.members, i) break end end end end) RegisterNetEvent(GetCurrentResourceName() .. ":updateMember", function(member) if not table_is_empty(crew) then for i, mem in ipairs(crew.members) do if mem.token == member.token then crew.members[i] = member break end end end end) RegisterNetEvent(GetCurrentResourceName() .. ":invite", function(crewName, senderName) SendNUIMessage({ action = "INVITED", data = { crewName = crewName, senderName = senderName } }) SetNuiFocus(true, true) end) RegisterNetEvent(GetCurrentResourceName() .. ":notify", function(t, m) SendNUIMessage({ action = "NOTIFY", data = { type = t, message = m } }) end) ---------------------------------------------------------------------------- -- NUI CALLBACKS -- ---------------------------------------------------------------------------- RegisterNUICallback('create', function(crewName) TriggerServerEvent(GetCurrentResourceName() .. ':create', crewName) end) RegisterNUICallback('join', function(crewName) TriggerServerEvent(GetCurrentResourceName() .. ':join', crewName) end) RegisterNUICallback('leave', function() TriggerServerEvent(GetCurrentResourceName() .. ':leave') end) RegisterNUICallback('invite', function(playerId) TriggerServerEvent(GetCurrentResourceName() .. ':invite', playerId) end) RegisterNUICallback('kickMember', function(memberToken) TriggerServerEvent(GetCurrentResourceName() .. ':kickMember', memberToken) end) RegisterNUICallback('promoteMember', function(data) TriggerServerEvent(GetCurrentResourceName() .. ':promoteMember', data.targetToken, data.rankUp) end) RegisterNUICallback('loaded', function(_, cb) cb({ playerId = localPlayerServerId, locales = Locales[Config.Locale], memberRanks = Config.MemberRanks }) CreateThread(function() while true do closest_players = closestPlayers() SendNUIMessage({ action = "INIT_DATA", data = { crew = crew, crewList = crewList, closestPlayers = closest_players } }) Wait(1000) end end) end) ---------------------------------------------------------------------------- -- MENU AND NAMETAGS -- ---------------------------------------------------------------------------- local menuOpen = false function openMenu() if not menuOpen then TriggerServerEvent(GetCurrentResourceName() .. ':getCrewList') SendNUIMessage({ action = "OPEN_UI" }) SetNuiFocus(true, true) menuOpen = true end end local nametags = {} CreateThread(function() -- Wait(1000) NetworkSetFriendlyFireOption(true) SetCanAttackFriendly(PlayerPedId(), true, true) TriggerServerEvent(GetCurrentResourceName() .. ':getCrew') RegisterCommand(Config.Command, function() openMenu() end) -- if Config.MenuKey then -- RegisterKeyMapping(Config.Command, 'Crew Menu', 'KEYBOARD', Config.MenuKey) -- end SetMpGamerTagsUseVehicleBehavior(true) SetMpGamerTagsVisibleDistance(50.0) if not menuOpen then local friendlyFire = false for _, player in ipairs(closest_players) do local blip = GetBlipFromEntity(player.ped) local nametag = nametags[player.server_id] if player.is_crew_member then if blip == 0 then blip = AddBlipForEntity(player.ped) SetBlipDisplay(blip, 2) SetBlipAsFriendly(blip, 1) SetBlipShowCone(blip, 1) BeginTextCommandSetBlipName("BLIP") AddTextEntry('BLIP', "(" .. crew.name .. ") " .. player.name) EndTextCommandSetBlipName(blip) end if not nametag or not IsMpGamerTagActive(nametag.tag) or nametag.ped ~= player.ped then nametags[player.server_id] = { ped = player.ped, tag = CreateFakeMpGamerTag(player.ped, player.name .. "(" .. crew.name .. ") [" .. player.server_id .. "]", 0, 0, '', 0) } end tag = nametags[player.server_id].tag SetMpGamerTagVisibility(tag, 2, true) SetMpGamerTagHealthBarColour(tag, 18) SetMpGamerTagAlpha(tag, 2, 200) if IsPlayerTargettingEntity(localPlayer, player.ped) or IsPlayerFreeAimingAtEntity(localPlayer, player.ped) then friendlyFire = true end else if blip then RemoveBlip(blip) end if nametag then RemoveMpGamerTag(nametag.tag) nametags[player.server_id] = nil end end end if friendlyFire then NetworkSetFriendlyFireOption(false) SetCanAttackFriendly(PlayerPedId(), false, false) else NetworkSetFriendlyFireOption(true) SetCanAttackFriendly(PlayerPedId(), true, true) end end end) RegisterNUICallback('close', function() menuOpen = false SetNuiFocus(false, false) end) AddEventHandler('onResourceStop', function(res) if res == GetCurrentResourceName() then for _, nametag in ipairs(nametags) do RemoveMpGamerTag(nametag.tag) end end end)