diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..a97fae66f --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,47 @@ +# Contribution Guidelines + +If you're planning to contribute, **please follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) standard.** + +Pull Requests (PRs) that do not adhere to this standard will **not be accepted**. + +## Branch Requirements + +- **All PRs must be based on the `dev` branch.** +- Merges will only occur into the `dev` branch before being released to the main branch. + +## Commit Message Format + +Ensure your commit messages and PR titles use the following format: + +``` +(): +``` + +For example: +``` +feat(es_extended/client/main): sync where players look at +fix(es_extended/client/functions): validate model is a vehicle +refactor(es_extended/client/modules/death): replace gameEventTriggered +``` + +Common commit types include: +- **`feat`** for new features +- **`fix`** for bug fixes +- **`refactor`** for code improvements without functionality changes +- **`!`** to indicate breaking changes (e.g., `feat!` or `fix!`) + +--- + +## PR Checklist + +**Please include this in your PR.** +``` +- [ ] My commit messages and PR title follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) standard. +- [ ] My changes have been tested locally and function as expected. +- [ ] My PR does not introduce any breaking changes. +- [ ] I have provided a clear explanation of what my PR does, including the reasoning behind the changes and any relevant context. +``` + + +# We value your contribution! +By adhering to these guidelines, we can ensure a clean and maintainable codebase. Thank you for contributing to ESX! \ No newline at end of file diff --git a/[SQL]/legacy.sql b/[SQL]/legacy.sql index 308c608c9..b041f32f4 100644 --- a/[SQL]/legacy.sql +++ b/[SQL]/legacy.sql @@ -821,6 +821,13 @@ ALTER TABLE `licenses` ALTER TABLE `owned_vehicles` ADD PRIMARY KEY (`plate`); +-- +-- +-- Indexes for table `vehicles` +-- +ALTER TABLE `vehicles` + ADD PRIMARY KEY (`model`); + -- -- Indexes for table `rented_vehicles` -- diff --git a/[core]/cron/server/main.lua b/[core]/cron/server/main.lua index bc8f81d00..51da085df 100644 --- a/[core]/cron/server/main.lua +++ b/[core]/cron/server/main.lua @@ -1,51 +1,75 @@ -local Jobs = {} -local LastTime = nil +---@class CronJob +---@field h number +---@field m number +---@field cb function|table +---@type CronJob[] +local cronJobs = {} +---@type number|false +local lastTimestamp = false + +---@param h number +---@param m number +---@param cb function|table function RunAt(h, m, cb) - Jobs[#Jobs + 1] = { + cronJobs[#cronJobs + 1] = { h = h, m = m, cb = cb, } end +---@return number function GetUnixTimestamp() return os.time() end -function OnTime(time) - for i = 1, #Jobs, 1 do +---@param timestamp number +function OnTime(timestamp) + for i = 1, #cronJobs, 1 do local scheduledTimestamp = os.time({ - hour = Jobs[i].h, - min = Jobs[i].m, + hour = cronJobs[i].h, + min = cronJobs[i].m, sec = 0, -- Assuming tasks run at the start of the minute - day = os.date("%d", time), - month = os.date("%m", time), - year = os.date("%Y", time), + day = os.date("%d", timestamp), + month = os.date("%m", timestamp), + year = os.date("%Y", timestamp), }) - if time >= scheduledTimestamp and (not LastTime or LastTime < scheduledTimestamp) then + if timestamp >= scheduledTimestamp and (not lastTimestamp or lastTimestamp < scheduledTimestamp) then local d = os.date('*t', scheduledTimestamp).wday - Jobs[i].cb(d, Jobs[i].h, Jobs[i].m) + cronJobs[i].cb(d, cronJobs[i].h, cronJobs[i].m) end end end +---@return nil function Tick() - local time = GetUnixTimestamp() + local timestamp = GetUnixTimestamp() - if not LastTime or os.date("%M", time) ~= os.date("%M", LastTime) then - OnTime(time) - LastTime = time + if not lastTimestamp or os.date("%M", timestamp) ~= os.date("%M", lastTimestamp) then + OnTime(timestamp) + lastTimestamp = timestamp end SetTimeout(60000, Tick) end -LastTime = GetUnixTimestamp() - +lastTimestamp = GetUnixTimestamp() Tick() +---@param h number +---@param m number +---@param cb function|table AddEventHandler("cron:runAt", function(h, m, cb) + local invokingResource = GetInvokingResource() or "Unknown" + local typeH = type(h) + local typeM = type(m) + local typeCb = type(cb) + + assert(typeH == "number", ("Expected number for h, got %s. Invoking Resource: '%s'"):format(typeH, invokingResource)) + assert(typeM == "number", ("Expected number for m, got %s. Invoking Resource: '%s'"):format(typeM, invokingResource)) + assert(typeCb == "function" or (typeCb == "table" and type(getmetatable(cb)?.__call) == "function"), ("Expected function for cb, got %s. Invoking Resource: '%s'"):format(typeCb, invokingResource)) + RunAt(h, m, cb) end) diff --git a/[core]/es_extended/client/common.lua b/[core]/es_extended/client/common.lua deleted file mode 100644 index 441af7662..000000000 --- a/[core]/es_extended/client/common.lua +++ /dev/null @@ -1,30 +0,0 @@ -Core = {} -Core.Input = {} -Core.Events = {} - -ESX.PlayerData = {} -ESX.PlayerLoaded = false -ESX.playerId = PlayerId() -ESX.serverId = GetPlayerServerId(ESX.playerId) - -ESX.UI = {} -ESX.UI.Menu = {} -ESX.UI.Menu.RegisteredTypes = {} -ESX.UI.Menu.Opened = {} - -ESX.Game = {} -ESX.Game.Utils = {} - -CreateThread(function() - while not Config.Multichar do - Wait(100) - - if NetworkIsPlayerActive(ESX.playerId) then - ESX.DisableSpawnManager() - DoScreenFadeOut(0) - Wait(500) - TriggerServerEvent("esx:onPlayerJoined") - break - end - end -end) diff --git a/[core]/es_extended/client/functions.lua b/[core]/es_extended/client/functions.lua index 58252a0f9..8a577e7e1 100644 --- a/[core]/es_extended/client/functions.lua +++ b/[core]/es_extended/client/functions.lua @@ -391,7 +391,7 @@ function ESX.UI.Menu.Close(menuType, namespace, name, cancel) else local menu = ESX.UI.Menu.Opened[i] ESX.UI.Menu.RegisteredTypes[menu.type].close(menu.namespace, menu.name) - + if type(menu.cancel) ~= "nil" then menu.cancel(menu.data, menu) end @@ -412,7 +412,7 @@ function ESX.UI.Menu.CloseAll(cancel) else local menu = ESX.UI.Menu.Opened[i] ESX.UI.Menu.RegisteredTypes[menu.type].close(menu.namespace, menu.name) - + if type(menu.cancel) ~= "nil" then menu.cancel(menu.data, menu) end @@ -530,10 +530,14 @@ end ---@param vehicleModel integer | string The vehicle to spawn ---@param coords table | vector3 The coords to spawn the vehicle at ---@param heading number The heading of the vehicle ----@param cb? function The callback function +---@param cb? fun(vehicle: number) The callback function ---@param networked? boolean Whether the vehicle should be networked ----@return nil +---@return number? vehicle function ESX.Game.SpawnVehicle(vehicleModel, coords, heading, cb, networked) + if cb and not ESX.IsFunctionReference(cb) then + error("Invalid callback function") + end + local model = type(vehicleModel) == "number" and vehicleModel or joaat(vehicleModel) local vector = type(coords) == "vector3" and coords or vec(coords.x, coords.y, coords.z) local isNetworked = networked == nil or networked @@ -549,8 +553,15 @@ function ESX.Game.SpawnVehicle(vehicleModel, coords, heading, cb, networked) return error(("Resource ^5%s^1 Tried to spawn vehicle on the client but the position is too far away (Out of onesync range)."):format(executingResource)) end + local promise = not cb and promise.new() CreateThread(function() - ESX.Streaming.RequestModel(model) + local modelHash = ESX.Streaming.RequestModel(model) + if not modelHash then + if promise then + return promise:reject(("Tried to spawn invalid vehicle - ^5%s^7!"):format(model)) + end + error(("Tried to spawn invalid vehicle - ^5%s^7!"):format(model)) + end local vehicle = CreateVehicle(model, vector.x, vector.y, vector.z, heading, isNetworked, true) @@ -569,10 +580,16 @@ function ESX.Game.SpawnVehicle(vehicleModel, coords, heading, cb, networked) Wait(0) end - if cb then + if promise then + promise:resolve(vehicle) + elseif cb then cb(vehicle) end end) + + if promise then + return Citizen.Await(promise) + end end ---@param vehicle integer The vehicle to spawn @@ -1585,6 +1602,11 @@ function ESX.GetVehicleTypeClient(model) if not IsModelInCdimage(model) then return false end + + if not IsModelAVehicle(model) then + return false + end + if mismatchedTypes[model] then return mismatchedTypes[model] end diff --git a/[core]/es_extended/client/imports/class.lua b/[core]/es_extended/client/imports/class.lua new file mode 100644 index 000000000..0b21d9983 --- /dev/null +++ b/[core]/es_extended/client/imports/class.lua @@ -0,0 +1,21 @@ +local class = {} +class.__index = class + +function class:new(...) + local instance = setmetatable({}, self) + if instance.constructor then + local ret = instance:constructor(...) + if type(ret) == 'table' then + return ret + end + end + return instance +end + +function Class(body, heritage) + local prototype = body or {} + prototype.__index = prototype + return setmetatable(prototype, heritage or class) +end + +return Class \ No newline at end of file diff --git a/[core]/es_extended/client/imports/point.lua b/[core]/es_extended/client/imports/point.lua new file mode 100644 index 000000000..55ec92bca --- /dev/null +++ b/[core]/es_extended/client/imports/point.lua @@ -0,0 +1,44 @@ +Point = ESX.Class() + +function Point:constructor(properties) + self.coords = properties.coords + self.hidden = properties.hidden or false + self.inside = properties.inside or function() end + self.enter = properties.enter or function() end + self.leave = properties.leave or function() end + self.handle = ESX.CreatePointInternal(properties.coords, properties.distance, properties.hidden, function() + self.nearby = true + if self.enter then + self:enter() + end + if self.inside then + CreateThread(function() + while self.nearby do + local coords = GetEntityCoords(ESX.PlayerData.ped) + self.currDistance = #(coords - self.coords) + self:inside() + Wait(0) + end + end) + end + end, function() + self.nearby = false + if self.leave then + self:leave() + end + end) +end + +function Point:delete() + ESX.RemovePointInternal(self.handle) +end + +function Point:toggle(hidden) + if hidden == nil then + hidden = not self.hidden + end + self.hidden = hidden + ESX.HidePointInternal(self.handle, hidden) +end + +return Point \ No newline at end of file diff --git a/[core]/es_extended/client/main.lua b/[core]/es_extended/client/main.lua index 4dd156edc..441af7662 100644 --- a/[core]/es_extended/client/main.lua +++ b/[core]/es_extended/client/main.lua @@ -1,564 +1,30 @@ -local pickups = {} +Core = {} +Core.Input = {} +Core.Events = {} -ESX.SecureNetEvent("esx:requestModel", function(model) - ESX.Streaming.RequestModel(model) -end) - -RegisterNetEvent("esx:playerLoaded", function(xPlayer, _, skin) - ESX.PlayerData = xPlayer - - if not Config.Multichar then - ESX.SpawnPlayer(skin, ESX.PlayerData.coords, function() - TriggerEvent("esx:onPlayerSpawn") - TriggerEvent("esx:restoreLoadout") - TriggerServerEvent("esx:onPlayerSpawn") - TriggerEvent("esx:loadingScreenOff") - ShutdownLoadingScreen() - ShutdownLoadingScreenNui() - end) - end - - while not DoesEntityExist(ESX.PlayerData.ped) do - Wait(20) - end - - ESX.PlayerLoaded = true - - local timer = GetGameTimer() - while not HaveAllStreamingRequestsCompleted(ESX.PlayerData.ped) and (GetGameTimer() - timer) < 2000 do - Wait(0) - end - - Adjustments:Load() - - ClearPedTasksImmediately(ESX.PlayerData.ped) +ESX.PlayerData = {} +ESX.PlayerLoaded = false +ESX.playerId = PlayerId() +ESX.serverId = GetPlayerServerId(ESX.playerId) - if not Config.Multichar then - Core.FreezePlayer(false) - end - - if IsScreenFadedOut() then - DoScreenFadeIn(500) - end - - Actions:Init() - - StartServerSyncLoops() -end) - -local isFirstSpawn = true -ESX.SecureNetEvent("esx:onPlayerLogout", function() - ESX.PlayerLoaded = false - isFirstSpawn = true -end) - -ESX.SecureNetEvent("esx:setMaxWeight", function(newMaxWeight) - ESX.SetPlayerData("maxWeight", newMaxWeight) -end) +ESX.UI = {} +ESX.UI.Menu = {} +ESX.UI.Menu.RegisteredTypes = {} +ESX.UI.Menu.Opened = {} -local function onPlayerSpawn() - ESX.SetPlayerData("ped", PlayerPedId()) - ESX.SetPlayerData("dead", false) -end +ESX.Game = {} +ESX.Game.Utils = {} -AddEventHandler("playerSpawned", onPlayerSpawn) -AddEventHandler("esx:onPlayerSpawn", function() - onPlayerSpawn() - - if isFirstSpawn then - isFirstSpawn = false - - if ESX.PlayerData.metadata.health and (ESX.PlayerData.metadata.health > 0 or Config.SaveDeathStatus) then - SetEntityHealth(ESX.PlayerData.ped, ESX.PlayerData.metadata.health) - end - - if ESX.PlayerData.metadata.armor and ESX.PlayerData.metadata.armor > 0 then - SetPedArmour(ESX.PlayerData.ped, ESX.PlayerData.metadata.armor) - end - end -end) - -AddEventHandler("esx:onPlayerDeath", function() - ESX.SetPlayerData("ped", PlayerPedId()) - ESX.SetPlayerData("dead", true) -end) - -AddEventHandler("skinchanger:modelLoaded", function() - while not ESX.PlayerLoaded do +CreateThread(function() + while not Config.Multichar do Wait(100) - end - TriggerEvent("esx:restoreLoadout") -end) - -AddEventHandler("esx:restoreLoadout", function() - ESX.SetPlayerData("ped", PlayerPedId()) - - if not Config.CustomInventory then - local ammoTypes = {} - RemoveAllPedWeapons(ESX.PlayerData.ped, true) - - for _, v in ipairs(ESX.PlayerData.loadout) do - local weaponName = v.name - local weaponHash = joaat(weaponName) - GiveWeaponToPed(ESX.PlayerData.ped, weaponHash, 0, false, false) - SetPedWeaponTintIndex(ESX.PlayerData.ped, weaponHash, v.tintIndex) - - local ammoType = GetPedAmmoTypeFromWeapon(ESX.PlayerData.ped, weaponHash) - - for _, v2 in ipairs(v.components) do - local componentHash = ESX.GetWeaponComponent(weaponName, v2).hash - GiveWeaponComponentToPed(ESX.PlayerData.ped, weaponHash, componentHash) - end - - if not ammoTypes[ammoType] then - AddAmmoToPed(ESX.PlayerData.ped, weaponHash, v.ammo) - ammoTypes[ammoType] = true - end - end - end -end) - ----@diagnostic disable-next-line: param-type-mismatch -AddStateBagChangeHandler("VehicleProperties", nil, function(bagName, _, value) - if not value then - return - end - - bagName = bagName:gsub("entity:", "") - local netId = tonumber(bagName) - if not netId then - error("Tried to set vehicle properties with invalid netId") - return - end - - local vehicle = NetToVeh(netId) - - local tries = 0 - while not NetworkDoesEntityExistWithNetworkId(netId) do - Wait(200) - tries = tries + 1 - if tries > 20 then - return error(("Invalid entity - ^5%s^7!"):format(netId)) - end - end - - if NetworkGetEntityOwner(vehicle) ~= ESX.playerId then - return - end - - ESX.Game.SetVehicleProperties(vehicle, value) -end) - -ESX.SecureNetEvent("esx:setAccountMoney", function(account) - for i = 1, #ESX.PlayerData.accounts do - if ESX.PlayerData.accounts[i].name == account.name then - ESX.PlayerData.accounts[i] = account + if NetworkIsPlayerActive(ESX.playerId) then + ESX.DisableSpawnManager() + DoScreenFadeOut(0) + Wait(500) + TriggerServerEvent("esx:onPlayerJoined") break end end - - ESX.SetPlayerData("accounts", ESX.PlayerData.accounts) -end) - -if not Config.CustomInventory then - ESX.SecureNetEvent("esx:addInventoryItem", function(item, count, showNotification) - for k, v in ipairs(ESX.PlayerData.inventory) do - if v.name == item then - ESX.UI.ShowInventoryItemNotification(true, v.label, count - v.count) - ESX.PlayerData.inventory[k].count = count - break - end - end - - if showNotification then - ESX.UI.ShowInventoryItemNotification(true, item, count) - end - end) - - ESX.SecureNetEvent("esx:removeInventoryItem", function(item, count, showNotification) - for i = 1, #ESX.PlayerData.inventory do - if ESX.PlayerData.inventory[i].name == item then - ESX.UI.ShowInventoryItemNotification(false, ESX.PlayerData.inventory[i].label, ESX.PlayerData.inventory[i].count - count) - ESX.PlayerData.inventory[i].count = count - break - end - end - - if showNotification then - ESX.UI.ShowInventoryItemNotification(false, item, count) - end - end) - - RegisterNetEvent("esx:addWeapon", function() - error("event ^5'esx:addWeapon'^1 Has Been Removed. Please use ^5xPlayer.addWeapon^1 Instead!") - end) - - - RegisterNetEvent("esx:addWeaponComponent", function() - error("event ^5'esx:addWeaponComponent'^1 Has Been Removed. Please use ^5xPlayer.addWeaponComponent^1 Instead!") - end) - - RegisterNetEvent("esx:setWeaponAmmo", function() - error("event ^5'esx:setWeaponAmmo'^1 Has Been Removed. Please use ^5xPlayer.addWeaponAmmo^1 Instead!") - end) - - ESX.SecureNetEvent("esx:setWeaponTint", function(weapon, weaponTintIndex) - SetPedWeaponTintIndex(ESX.PlayerData.ped, joaat(weapon), weaponTintIndex) - end) - - RegisterNetEvent("esx:removeWeapon", function() - error("event ^5'esx:removeWeapon'^1 Has Been Removed. Please use ^5xPlayer.removeWeapon^1 Instead!") - end) - - ESX.SecureNetEvent("esx:removeWeaponComponent", function(weapon, weaponComponent) - local componentHash = ESX.GetWeaponComponent(weapon, weaponComponent).hash - RemoveWeaponComponentFromPed(ESX.PlayerData.ped, joaat(weapon), componentHash) - end) -end - -ESX.SecureNetEvent("esx:setJob", function(Job) - ESX.SetPlayerData("job", Job) -end) - -ESX.SecureNetEvent("esx:setGroup", function(group) - ESX.SetPlayerData("group", group) -end) - -if not Config.CustomInventory then - ESX.SecureNetEvent("esx:createPickup", function(pickupId, label, coords, itemType, name, components, tintIndex) - local function setObjectProperties(object) - SetEntityAsMissionEntity(object, true, false) - PlaceObjectOnGroundProperly(object) - FreezeEntityPosition(object, true) - SetEntityCollision(object, false, true) - - pickups[pickupId] = { - obj = object, - label = label, - inRange = false, - coords = coords, - } - end - - if itemType == "item_weapon" then - local weaponHash = joaat(name) - ESX.Streaming.RequestWeaponAsset(weaponHash) - local pickupObject = CreateWeaponObject(weaponHash, 50, coords.x, coords.y, coords.z, true, 1.0, 0) - SetWeaponObjectTintIndex(pickupObject, tintIndex) - - for _, v in ipairs(components) do - local component = ESX.GetWeaponComponent(name, v) - if component then - GiveWeaponComponentToWeaponObject(pickupObject, component.hash) - end - end - - setObjectProperties(pickupObject) - else - ESX.Game.SpawnLocalObject("prop_money_bag_01", coords, setObjectProperties) - end - end) - - ESX.SecureNetEvent("esx:createMissingPickups", function(missingPickups) - for pickupId, pickup in pairs(missingPickups) do - TriggerEvent("esx:createPickup", pickupId, pickup.label, vector3(pickup.coords.x, pickup.coords.y, pickup.coords.z - 1.0), pickup.type, pickup.name, pickup.components, pickup.tintIndex) - end - end) -end - -ESX.SecureNetEvent("esx:registerSuggestions", function(registeredCommands) - for name, command in pairs(registeredCommands) do - if command.suggestion then - TriggerEvent("chat:addSuggestion", ("/%s"):format(name), command.suggestion.help, command.suggestion.arguments) - end - end -end) - -if not Config.CustomInventory then - ESX.SecureNetEvent("esx:removePickup", function(pickupId) - if pickups[pickupId] and pickups[pickupId].obj then - ESX.Game.DeleteObject(pickups[pickupId].obj) - pickups[pickupId] = nil - end - end) -end - -function StartServerSyncLoops() - if Config.CustomInventory then return end - -- keep track of ammo - CreateThread(function() - local currentWeapon = { Ammo = 0 } - while ESX.PlayerLoaded do - local sleep = 1500 - if GetSelectedPedWeapon(ESX.PlayerData.ped) ~= -1569615261 then - sleep = 1000 - local _, weaponHash = GetCurrentPedWeapon(ESX.PlayerData.ped, true) - local weapon = ESX.GetWeaponFromHash(weaponHash) - if weapon then - local ammoCount = GetAmmoInPedWeapon(ESX.PlayerData.ped, weaponHash) - if weapon.name ~= currentWeapon.name then - currentWeapon.Ammo = ammoCount - currentWeapon.name = weapon.name - else - if ammoCount ~= currentWeapon.Ammo then - currentWeapon.Ammo = ammoCount - TriggerServerEvent("esx:updateWeaponAmmo", weapon.name, ammoCount) - end - end - end - end - Wait(sleep) - end - end) -end - -if not Config.CustomInventory and Config.EnableDefaultInventory then - ESX.RegisterInput("showinv", TranslateCap("keymap_showinventory"), "keyboard", "F2", function() - if not ESX.PlayerData.dead then - ESX.ShowInventory() - end - end) -end - -if not Config.CustomInventory then - CreateThread(function() - while true do - local Sleep = 1500 - local playerCoords = GetEntityCoords(ESX.PlayerData.ped) - local _, closestDistance = ESX.Game.GetClosestPlayer(playerCoords) - - for pickupId, pickup in pairs(pickups) do - local distance = #(playerCoords - pickup.coords) - - if distance < 5 then - Sleep = 0 - local label = pickup.label - - if distance < 1 then - if IsControlJustReleased(0, 38) then - if IsPedOnFoot(ESX.PlayerData.ped) and (closestDistance == -1 or closestDistance > 3) and not pickup.inRange then - pickup.inRange = true - - local dict, anim = "weapons@first_person@aim_rng@generic@projectile@sticky_bomb@", "plant_floor" - ESX.Streaming.RequestAnimDict(dict) - TaskPlayAnim(ESX.PlayerData.ped, dict, anim, 8.0, 1.0, 1000, 16, 0.0, false, false, false) - RemoveAnimDict(dict) - Wait(1000) - - TriggerServerEvent("esx:onPickup", pickupId) - PlaySoundFrontend(-1, "PICK_UP", "HUD_FRONTEND_DEFAULT_SOUNDSET", false) - end - end - - label = ("%s~n~%s"):format(label, TranslateCap("threw_pickup_prompt")) - end - - local textCoords = pickup.coords + vector3(0.0, 0.0, 0.25) - ESX.Game.Utils.DrawText3D(textCoords, label, 1.2, 1) - elseif pickup.inRange then - pickup.inRange = false - end - end - Wait(Sleep) - end - end) -end - ------ Admin commands from esx_adminplus -ESX.SecureNetEvent("esx:tpm", function() - local GetEntityCoords = GetEntityCoords - local GetGroundZFor_3dCoord = GetGroundZFor_3dCoord - local GetFirstBlipInfoId = GetFirstBlipInfoId - local DoesBlipExist = DoesBlipExist - local DoScreenFadeOut = DoScreenFadeOut - local GetBlipInfoIdCoord = GetBlipInfoIdCoord - local GetVehiclePedIsIn = GetVehiclePedIsIn - - ESX.TriggerServerCallback("esx:isUserAdmin", function(admin) - if not admin then - return - end - local blipMarker = GetFirstBlipInfoId(8) - if not DoesBlipExist(blipMarker) then - ESX.ShowNotification(TranslateCap("tpm_nowaypoint"), "error") - return "marker" - end - - -- Fade screen to hide how clients get teleported. - DoScreenFadeOut(650) - while not IsScreenFadedOut() do - Wait(0) - end - - local ped, coords = ESX.PlayerData.ped, GetBlipInfoIdCoord(blipMarker) - local vehicle = GetVehiclePedIsIn(ped, false) - local oldCoords = GetEntityCoords(ped) - - -- Unpack coords instead of having to unpack them while iterating. - -- 825.0 seems to be the max a player can reach while 0.0 being the lowest. - local x, y, groundZ, Z_START = coords["x"], coords["y"], 850.0, 950.0 - local found = false - FreezeEntityPosition(vehicle > 0 and vehicle or ped, true) - - for i = Z_START, 0, -25.0 do - local z = i - if (i % 2) ~= 0 then - z = Z_START - i - end - - NewLoadSceneStart(x, y, z, x, y, z, 50.0, 0) - local curTime = GetGameTimer() - while IsNetworkLoadingScene() do - if GetGameTimer() - curTime > 1000 then - break - end - Wait(0) - end - NewLoadSceneStop() - SetPedCoordsKeepVehicle(ped, x, y, z) - - while not HasCollisionLoadedAroundEntity(ped) do - RequestCollisionAtCoord(x, y, z) - if GetGameTimer() - curTime > 1000 then - break - end - Wait(0) - end - - -- Get ground coord. As mentioned in the natives, this only works if the client is in render distance. - found, groundZ = GetGroundZFor_3dCoord(x, y, z, false) - if found then - Wait(0) - SetPedCoordsKeepVehicle(ped, x, y, groundZ) - break - end - Wait(0) - end - - -- Remove black screen once the loop has ended. - DoScreenFadeIn(650) - FreezeEntityPosition(vehicle > 0 and vehicle or ped, false) - - if not found then - -- If we can't find the coords, set the coords to the old ones. - -- We don't unpack them before since they aren't in a loop and only called once. - SetPedCoordsKeepVehicle(ped, oldCoords["x"], oldCoords["y"], oldCoords["z"] - 1.0) - ESX.ShowNotification(TranslateCap("tpm_success"), "success") - end - - -- If Z coord was found, set coords in found coords. - SetPedCoordsKeepVehicle(ped, x, y, groundZ) - ESX.ShowNotification(TranslateCap("tpm_success"), "success") - end) -end) - -local noclip = false -local noclip_pos = vector3(0, 0, 70) -local heading = 0 - -local function noclipThread() - while noclip do - SetEntityCoordsNoOffset(ESX.PlayerData.ped, noclip_pos.x, noclip_pos.y, noclip_pos.z, false, false, true) - - if IsControlPressed(1, 34) then - heading = heading + 1.5 - if heading > 360 then - heading = 0 - end - - SetEntityHeading(ESX.PlayerData.ped, heading) - end - - if IsControlPressed(1, 9) then - heading = heading - 1.5 - if heading < 0 then - heading = 360 - end - - SetEntityHeading(ESX.PlayerData.ped, heading) - end - - if IsControlPressed(1, 8) then - noclip_pos = GetOffsetFromEntityInWorldCoords(ESX.PlayerData.ped, 0.0, 1.0, 0.0) - end - - if IsControlPressed(1, 32) then - noclip_pos = GetOffsetFromEntityInWorldCoords(ESX.PlayerData.ped, 0.0, -1.0, 0.0) - end - - if IsControlPressed(1, 27) then - noclip_pos = GetOffsetFromEntityInWorldCoords(ESX.PlayerData.ped, 0.0, 0.0, 1.0) - end - - if IsControlPressed(1, 173) then - noclip_pos = GetOffsetFromEntityInWorldCoords(ESX.PlayerData.ped, 0.0, 0.0, -1.0) - end - Wait(0) - end -end - -ESX.SecureNetEvent("esx:noclip", function() - ESX.TriggerServerCallback("esx:isUserAdmin", function(admin) - if not admin then - return - end - - if not noclip then - noclip_pos = GetEntityCoords(ESX.PlayerData.ped, false) - heading = GetEntityHeading(ESX.PlayerData.ped) - end - - noclip = not noclip - if noclip then - CreateThread(noclipThread) - end - - if noclip then - ESX.ShowNotification(TranslateCap("noclip_message", Translate("enabled")), "success") - else - ESX.ShowNotification(TranslateCap("noclip_message", Translate("disabled")), "error") - end - end) -end) - -ESX.SecureNetEvent("esx:killPlayer", function() - SetEntityHealth(ESX.PlayerData.ped, 0) -end) - -ESX.SecureNetEvent("esx:repairPedVehicle", function() - local ped = ESX.PlayerData.ped - local vehicle = GetVehiclePedIsIn(ped, false) - SetVehicleEngineHealth(vehicle, 1000) - SetVehicleEngineOn(vehicle, true, true, false) - SetVehicleFixed(vehicle) - SetVehicleDirtLevel(vehicle, 0) -end) - -ESX.SecureNetEvent("esx:freezePlayer", function(input) - if input == "freeze" then - SetEntityCollision(ESX.PlayerData.ped, false, false) - FreezeEntityPosition(ESX.PlayerData.ped, true) - SetPlayerInvincible(ESX.playerId, true) - elseif input == "unfreeze" then - SetEntityCollision(ESX.PlayerData.ped, true, true) - FreezeEntityPosition(ESX.PlayerData.ped, false) - SetPlayerInvincible(ESX.playerId, false) - end -end) - -ESX.RegisterClientCallback("esx:GetVehicleType", function(cb, model) - cb(ESX.GetVehicleTypeClient(model)) -end) - -ESX.SecureNetEvent('esx:updatePlayerData', function(key, val) - ESX.SetPlayerData(key, val) -end) - -AddEventHandler("onResourceStop", function(resource) - if Core.Events[resource] then - for i = 1, #Core.Events[resource] do - RemoveEventHandler(Core.Events[resource][i]) - end - end end) diff --git a/[core]/es_extended/client/modules/actions.lua b/[core]/es_extended/client/modules/actions.lua index 750d3bea5..98b864b1d 100644 --- a/[core]/es_extended/client/modules/actions.lua +++ b/[core]/es_extended/client/modules/actions.lua @@ -4,6 +4,7 @@ Actions._index = Actions Actions.inVehicle = false Actions.enteringVehicle = false Actions.inPauseMenu = false +Actions.currentWeapon = false function Actions:GetSeatPedIsIn() for i = -1, 16 do @@ -44,10 +45,13 @@ function Actions:TrackPed() local newPed = PlayerPedId() if playerPed ~= newPed then - ESX.PlayerData.ped = newPed ESX.SetPlayerData("ped", newPed) TriggerEvent("esx:playerPedChanged", newPed) + + if Config.EnableDebug then + print("[DEBUG] Player ped changed:", newPed) + end end end @@ -57,6 +61,10 @@ function Actions:TrackPauseMenu() if isActive ~= self.inPauseMenu then self.inPauseMenu = isActive TriggerEvent("esx:pauseMenuActive", isActive) + + if Config.EnableDebug then + print("[DEBUG] Pause menu active:", isActive) + end end end @@ -65,11 +73,15 @@ function Actions:EnterVehicle() local _, netId, plate = self:GetVehicleData() - self.isEnteringVehicle = true + self.enteringVehicle = true TriggerEvent("esx:enteringVehicle", self.vehicle, plate, self.seat, netId) TriggerServerEvent("esx:enteringVehicle", plate, self.seat, netId) self:SetVehicleStatus() + + if Config.EnableDebug then + print("[DEBUG] Entering vehicle:", self.vehicle, plate, self.seat, netId) + end end function Actions:ResetVehicleData() @@ -86,6 +98,10 @@ function Actions:EnterAborted() TriggerEvent("esx:enteringVehicleAborted") TriggerServerEvent("esx:enteringVehicleAborted") + + if Config.EnableDebug then + print("[DEBUG] Entering vehicle aborted") + end end function Actions:WarpEnter() @@ -99,6 +115,10 @@ function Actions:WarpEnter() self:SetVehicleStatus() TriggerEvent("esx:enteredVehicle", self.vehicle, plate, self.seat, displayName, netId) TriggerServerEvent("esx:enteredVehicle", plate, self.seat, displayName, netId) + + if Config.EnableDebug then + print("[DEBUG] Entered vehicle:", self.vehicle, plate, self.seat, displayName, netId) + end end function Actions:ExitVehicle() @@ -110,6 +130,10 @@ function Actions:ExitVehicle() TriggerEvent("esx:exitedVehicle", self.vehicle, plate, self.seat, displayName, netId) TriggerServerEvent("esx:exitedVehicle", plate, self.seat, displayName, netId) + if Config.EnableDebug then + print("[DEBUG] Exited vehicle:", self.vehicle, plate, self.seat, displayName, netId) + end + self:ResetVehicleData() end end @@ -129,6 +153,40 @@ function Actions:TrackVehicle() end elseif self.inVehicle then self:ExitVehicle() + self:TrackSeat() + end +end + +function Actions:TrackSeat() + if not self.inVehicle then + return + end + + local newSeat = self:GetSeatPedIsIn() + if newSeat ~= self.seat then + self.seat = newSeat + ESX.SetPlayerData("seat", self.seat) + TriggerEvent("esx:vehicleSeatChanged", self.seat) + + if Config.EnableDebug then + print("[DEBUG] Vehicle seat changed:", self.seat) + end + end +end + +function Actions:TrackWeapon() + ---@type number|false + local newWeapon = GetSelectedPedWeapon(ESX.PlayerData.ped) + newWeapon = newWeapon ~= `WEAPON_UNARMED` and newWeapon or false + + if newWeapon ~= self.currentWeapon then + self.currentWeapon = newWeapon + ESX.SetPlayerData("weapon", self.currentWeapon) + TriggerEvent("esx:weaponChanged", self.currentWeapon) + + if Config.EnableDebug then + print("[DEBUG] Weapon changed:", self.currentWeapon) + end end end @@ -138,6 +196,7 @@ function Actions:SlowLoop() self:TrackPedCoords() self:TrackPauseMenu() self:TrackVehicle() + self:TrackWeapon() Wait(500) end end) @@ -152,7 +211,6 @@ function Actions:PedLoop() end) end - function Actions:Init() self:SlowLoop() self:PedLoop() diff --git a/[core]/es_extended/client/modules/adjustments.lua b/[core]/es_extended/client/modules/adjustments.lua index 42fa93982..b4d4fe8ad 100644 --- a/[core]/es_extended/client/modules/adjustments.lua +++ b/[core]/es_extended/client/modules/adjustments.lua @@ -4,6 +4,7 @@ function Adjustments:RemoveHudComponents() for i = 1, #Config.RemoveHudComponents do if Config.RemoveHudComponents[i] then SetHudComponentSize(i, 0.0, 0.0) + SetHudComponentPosition(i, 900, 900) end end end @@ -215,6 +216,15 @@ function Adjustments:WantedLevel() end end +function Adjustments:DisableRadio() + if Config.RemoveHudComponents[16] then + AddEventHandler("esx:enteredVehicle", function(vehicle, plate, seat, displayName, netId) + SetVehRadioStation(vehicle,"OFF") + SetUserRadioControlEnabled(false) + end) + end +end + function Adjustments:Load() self:RemoveHudComponents() self:DisableAimAssist() @@ -228,4 +238,5 @@ function Adjustments:Load() self:LicensePlates() self:DiscordPresence() self:WantedLevel() + self:DisableRadio() end diff --git a/[core]/es_extended/client/modules/callback.lua b/[core]/es_extended/client/modules/callback.lua index 738b3bb15..6bd2d7586 100644 --- a/[core]/es_extended/client/modules/callback.lua +++ b/[core]/es_extended/client/modules/callback.lua @@ -1,47 +1,68 @@ ---@diagnostic disable: duplicate-set-field +-- ============================================= +-- MARK: Variables +-- ============================================= + Callbacks = {} Callbacks.requests = {} Callbacks.storage = {} Callbacks.id = 0 +-- ============================================= +-- MARK: Internal Functions +-- ============================================= + function Callbacks:Trigger(event, cb, invoker, ...) - self.requests[self.id] = cb + + self.requests[self.id] = { + await = type(cb) == "boolean", + cb = cb or promise:new() + } + local table = self.requests[self.id] + TriggerServerEvent("esx:triggerServerCallback", event, self.id, invoker, ...) self.id += 1 + + return table.cb end -function Callbacks:Execute(cb, ...) +function Callbacks:Execute(cb, id, ...) local success, errorString = pcall(cb, ...) if not success then - print(("[^1ERROR^7] Failed to execute Callback with RequestId: ^5%s^7"):format(self.currentId)) + print(("[^1ERROR^7] Failed to execute Callback with RequestId: ^5%s^7"):format(id)) error(errorString) return end - self.currentId = nil end function Callbacks:ServerRecieve(requestId, invoker, ...) - self.currentId = requestId - if not self.requests[self.currentId] then - return error(("Server Callback with requestId ^5%s^1 Was Called by ^5%s^1 but does not exist."):format(self.currentId, invoker)) + if not self.requests[requestId] then + return error(("Server Callback with requestId ^5%s^1 Was Called by ^5%s^1 but does not exist."):format(requestId, invoker)) end - local callback = self.requests[self.currentId] + local callback = self.requests[requestId] - Callbacks:Execute(callback, ...) self.requests[requestId] = nil + + if callback.await then + callback.cb:resolve({...}) + else + self:Execute(callback.cb, requestId, ...) + end end -function Callbacks:Register(name, cb) - self.storage[name] = cb +function Callbacks:Register(name, resource, cb) + self.storage[name] = { + resource = resource, + cb = cb + } end function Callbacks:ClientRecieve(eventName, requestId, invoker, ...) - self.currentId = requestId if not self.storage[eventName] then return error(("Client Callback with requestId ^5%s^1 Was Called by ^5%s^1 but does not exist."):format(eventName, invoker)) @@ -50,33 +71,77 @@ function Callbacks:ClientRecieve(eventName, requestId, invoker, ...) local returnCb = function(...) TriggerServerEvent("esx:clientCallback", requestId, invoker, ...) end - local callback = self.storage[eventName] + local callback = self.storage[eventName].cb - Callbacks:Execute(callback, returnCb, ...) + self:Execute(callback, requestId, returnCb, ...) end +-- ============================================= +-- MARK: ESX Functions +-- ============================================= + ---@param eventName string ---@param callback function ---@param ... any ---@return nil -ESX.TriggerServerCallback = function(eventName, callback, ...) +function ESX.TriggerServerCallback(eventName, callback, ...) local invokingResource = GetInvokingResource() local invoker = (invokingResource and invokingResource ~= "unknown") and invokingResource or "es_extended" Callbacks:Trigger(eventName, callback, invoker, ...) end -ESX.SecureNetEvent("esx:serverCallback", function(...) - Callbacks:ServerRecieve(...) -end) +---@param eventName string +---@param ... any +---@return any +function ESX.AwaitServerCallback(eventName, ...) + local invokingResource = GetInvokingResource() + local invoker = (invokingResource and invokingResource ~= "unknown") and invokingResource or "es_extended" + + local p = Callbacks:Trigger(eventName, false, invoker, ...) + if not p then return end + + -- if the server callback takes longer than 15 seconds to respond, reject the promise + SetTimeout(15000, function() + if p.state == "pending" then + p:reject("Server Callback Timed Out") + end + end) + + Citizen.Await(p) + + return table.unpack(p.value) +end + +function ESX.RegisterClientCallback(eventName, callback) + local invokingResource = GetInvokingResource() + local invoker = (invokingResource and invokingResource ~= "Unknown") and invokingResource or "es_extended" + + Callbacks:Register(eventName, invoker, callback) +end ---@param eventName string ----@param callback function ----@return nil -ESX.RegisterClientCallback = function(eventName, callback) - Callbacks:Register(eventName, callback) +---@return boolean +function ESX.DoesClientCallbackExist(eventName) + return Callbacks.storage[eventName] ~= nil end +-- ============================================= +-- MARK: Events +-- ============================================= + ESX.SecureNetEvent("esx:triggerClientCallback", function(...) Callbacks:ClientRecieve(...) end) + +ESX.SecureNetEvent("esx:serverCallback", function(...) + Callbacks:ServerRecieve(...) +end) + +AddEventHandler("onResourceStop", function(resource) + for k, v in pairs(Callbacks.storage) do + if v.resource == resource then + Callbacks.storage[k] = nil + end + end +end) diff --git a/[core]/es_extended/client/modules/death.lua b/[core]/es_extended/client/modules/death.lua index 4054421e2..ba3fb846d 100644 --- a/[core]/es_extended/client/modules/death.lua +++ b/[core]/es_extended/client/modules/death.lua @@ -29,7 +29,7 @@ function Death:ByPlayer() TriggerServerEvent("esx:onPlayerDeath", data) end -function Death:Natual() +function Death:Natural() local coords = GetEntityCoords(ESX.PlayerData.ped) local data = { @@ -43,25 +43,7 @@ function Death:Natual() TriggerServerEvent("esx:onPlayerDeath", data) end -function Death:Damaged(victim, victimDied) - if not victimDied then - return - end - - if not IsEntityAPed(victim) then - return - end - - if not IsPedAPlayer(victim) then - return - end - - local victimId = NetworkGetPlayerIndexFromPed(victim) - local isDead = IsPedDeadOrDying(victim, true) or IsPedFatallyInjured(victim) - if victimId ~= ESX.playerId or not isDead then - return - end - +function Death:Died() self.killerEntity = GetPedSourceOfDeath(ESX.PlayerData.ped) self.deathCause = GetPedCauseOfDeath(ESX.PlayerData.ped) self.killerId = NetworkGetPlayerIndexFromPed(self.killerEntity) @@ -72,15 +54,20 @@ function Death:Damaged(victim, victimDied) if self.killerEntity ~= ESX.PlayerData.ped and self.killerId and isActive then self:ByPlayer() else - self:Natual() + self:Natural() end self:ResetValues() end -AddEventHandler("gameEventTriggered", function(event, data) - if event ~= "CEventNetworkEntityDamage" then - return - end - Death:Damaged(data[1], data[4]) +AddEventHandler("esx:onPlayerSpawn", function() + Citizen.CreateThreadNow(function() + while ESX.PlayerLoaded and not ESX.PlayerData.dead do + if DoesEntityExist(ESX.PlayerData.ped) and (IsPedDeadOrDying(ESX.PlayerData.ped, true) or IsPedFatallyInjured(ESX.PlayerData.ped)) then + Death:Died() + break + end + Citizen.Wait(250) + end + end) end) diff --git a/[core]/es_extended/client/modules/events.lua b/[core]/es_extended/client/modules/events.lua new file mode 100644 index 000000000..08d85b78b --- /dev/null +++ b/[core]/es_extended/client/modules/events.lua @@ -0,0 +1,594 @@ +local pickups = {} + +ESX.SecureNetEvent("esx:requestModel", function(model) + ESX.Streaming.RequestModel(model) +end) + +RegisterNetEvent("esx:playerLoaded", function(xPlayer, _, skin) + ESX.PlayerData = xPlayer + + if not Config.Multichar then + ESX.SpawnPlayer(skin, ESX.PlayerData.coords, function() + TriggerEvent("esx:onPlayerSpawn") + TriggerEvent("esx:restoreLoadout") + TriggerServerEvent("esx:onPlayerSpawn") + TriggerEvent("esx:loadingScreenOff") + ShutdownLoadingScreen() + ShutdownLoadingScreenNui() + end) + end + + while not DoesEntityExist(ESX.PlayerData.ped) do + Wait(20) + end + + ESX.PlayerLoaded = true + + local timer = GetGameTimer() + while not HaveAllStreamingRequestsCompleted(ESX.PlayerData.ped) and (GetGameTimer() - timer) < 2000 do + Wait(0) + end + + Adjustments:Load() + + ClearPedTasksImmediately(ESX.PlayerData.ped) + + if not Config.Multichar then + Core.FreezePlayer(false) + end + + if IsScreenFadedOut() then + DoScreenFadeIn(500) + end + + Actions:Init() + StartPointsLoop() + StartServerSyncLoops() + NetworkSetLocalPlayerSyncLookAt(true) +end) + +local isFirstSpawn = true +ESX.SecureNetEvent("esx:onPlayerLogout", function() + ESX.PlayerLoaded = false + isFirstSpawn = true +end) + +ESX.SecureNetEvent("esx:setMaxWeight", function(newMaxWeight) + ESX.SetPlayerData("maxWeight", newMaxWeight) +end) + +local function onPlayerSpawn() + ESX.SetPlayerData("ped", PlayerPedId()) + ESX.SetPlayerData("dead", false) +end + +AddEventHandler("playerSpawned", onPlayerSpawn) +AddEventHandler("esx:onPlayerSpawn", function() + onPlayerSpawn() + + if isFirstSpawn then + isFirstSpawn = false + + if ESX.PlayerData.metadata.health and (ESX.PlayerData.metadata.health > 0 or Config.SaveDeathStatus) then + SetEntityHealth(ESX.PlayerData.ped, ESX.PlayerData.metadata.health) + end + + if ESX.PlayerData.metadata.armor and ESX.PlayerData.metadata.armor > 0 then + SetPedArmour(ESX.PlayerData.ped, ESX.PlayerData.metadata.armor) + end + end +end) + +AddEventHandler("esx:onPlayerDeath", function() + ESX.SetPlayerData("ped", PlayerPedId()) + ESX.SetPlayerData("dead", true) +end) + +AddEventHandler("skinchanger:modelLoaded", function() + while not ESX.PlayerLoaded do + Wait(100) + end + TriggerEvent("esx:restoreLoadout") +end) + +AddEventHandler("esx:restoreLoadout", function() + ESX.SetPlayerData("ped", PlayerPedId()) + + if not Config.CustomInventory then + local ammoTypes = {} + RemoveAllPedWeapons(ESX.PlayerData.ped, true) + + for _, v in ipairs(ESX.PlayerData.loadout) do + local weaponName = v.name + local weaponHash = joaat(weaponName) + + GiveWeaponToPed(ESX.PlayerData.ped, weaponHash, 0, false, false) + SetPedWeaponTintIndex(ESX.PlayerData.ped, weaponHash, v.tintIndex) + + local ammoType = GetPedAmmoTypeFromWeapon(ESX.PlayerData.ped, weaponHash) + + for _, v2 in ipairs(v.components) do + local componentHash = ESX.GetWeaponComponent(weaponName, v2).hash + GiveWeaponComponentToPed(ESX.PlayerData.ped, weaponHash, componentHash) + end + + if not ammoTypes[ammoType] then + AddAmmoToPed(ESX.PlayerData.ped, weaponHash, v.ammo) + ammoTypes[ammoType] = true + end + end + end +end) + +---@diagnostic disable-next-line: param-type-mismatch +AddStateBagChangeHandler("VehicleProperties", nil, function(bagName, _, value) + if not value then + return + end + + bagName = bagName:gsub("entity:", "") + local netId = tonumber(bagName) + if not netId then + error("Tried to set vehicle properties with invalid netId") + return + end + + local vehicle = NetToVeh(netId) + + local tries = 0 + while not NetworkDoesEntityExistWithNetworkId(netId) do + Wait(200) + tries = tries + 1 + if tries > 20 then + return error(("Invalid entity - ^5%s^7!"):format(netId)) + end + end + + if NetworkGetEntityOwner(vehicle) ~= ESX.playerId then + return + end + + ESX.Game.SetVehicleProperties(vehicle, value) +end) + +ESX.SecureNetEvent("esx:setAccountMoney", function(account) + for i = 1, #ESX.PlayerData.accounts do + if ESX.PlayerData.accounts[i].name == account.name then + ESX.PlayerData.accounts[i] = account + break + end + end + + ESX.SetPlayerData("accounts", ESX.PlayerData.accounts) +end) + +if not Config.CustomInventory then + ESX.SecureNetEvent("esx:addInventoryItem", function(item, count, showNotification) + for k, v in ipairs(ESX.PlayerData.inventory) do + if v.name == item then + ESX.UI.ShowInventoryItemNotification(true, v.label, count - v.count) + ESX.PlayerData.inventory[k].count = count + break + end + end + + if showNotification then + ESX.UI.ShowInventoryItemNotification(true, item, count) + end + end) + + ESX.SecureNetEvent("esx:removeInventoryItem", function(item, count, showNotification) + for i = 1, #ESX.PlayerData.inventory do + if ESX.PlayerData.inventory[i].name == item then + ESX.UI.ShowInventoryItemNotification(false, ESX.PlayerData.inventory[i].label, ESX.PlayerData.inventory[i].count - count) + ESX.PlayerData.inventory[i].count = count + break + end + end + + if showNotification then + ESX.UI.ShowInventoryItemNotification(false, item, count) + end + end) + + RegisterNetEvent("esx:addWeapon", function() + error("event ^5'esx:addWeapon'^1 Has Been Removed. Please use ^5xPlayer.addWeapon^1 Instead!") + end) + + + RegisterNetEvent("esx:addWeaponComponent", function() + error("event ^5'esx:addWeaponComponent'^1 Has Been Removed. Please use ^5xPlayer.addWeaponComponent^1 Instead!") + end) + + RegisterNetEvent("esx:setWeaponAmmo", function() + error("event ^5'esx:setWeaponAmmo'^1 Has Been Removed. Please use ^5xPlayer.addWeaponAmmo^1 Instead!") + end) + + ESX.SecureNetEvent("esx:setWeaponTint", function(weapon, weaponTintIndex) + SetPedWeaponTintIndex(ESX.PlayerData.ped, joaat(weapon), weaponTintIndex) + end) + + RegisterNetEvent("esx:removeWeapon", function() + error("event ^5'esx:removeWeapon'^1 Has Been Removed. Please use ^5xPlayer.removeWeapon^1 Instead!") + end) + + ESX.SecureNetEvent("esx:removeWeaponComponent", function(weapon, weaponComponent) + local componentHash = ESX.GetWeaponComponent(weapon, weaponComponent).hash + RemoveWeaponComponentFromPed(ESX.PlayerData.ped, joaat(weapon), componentHash) + end) +end + +ESX.SecureNetEvent("esx:setJob", function(Job) + ESX.SetPlayerData("job", Job) +end) + +ESX.SecureNetEvent("esx:setGroup", function(group) + ESX.SetPlayerData("group", group) +end) + +if not Config.CustomInventory then + ESX.SecureNetEvent("esx:createPickup", function(pickupId, label, coords, itemType, name, components, tintIndex) + local function setObjectProperties(object) + SetEntityAsMissionEntity(object, true, false) + PlaceObjectOnGroundProperly(object) + FreezeEntityPosition(object, true) + SetEntityCollision(object, false, true) + + pickups[pickupId] = { + obj = object, + label = label, + inRange = false, + coords = coords, + } + end + + if itemType == "item_weapon" then + local weaponHash = joaat(name) + ESX.Streaming.RequestWeaponAsset(weaponHash) + local pickupObject = CreateWeaponObject(weaponHash, 50, coords.x, coords.y, coords.z, true, 1.0, 0) + SetWeaponObjectTintIndex(pickupObject, tintIndex) + + for _, v in ipairs(components) do + local component = ESX.GetWeaponComponent(name, v) + if component then + GiveWeaponComponentToWeaponObject(pickupObject, component.hash) + end + end + + setObjectProperties(pickupObject) + else + ESX.Game.SpawnLocalObject("prop_money_bag_01", coords, setObjectProperties) + end + end) + + ESX.SecureNetEvent("esx:createMissingPickups", function(missingPickups) + for pickupId, pickup in pairs(missingPickups) do + TriggerEvent("esx:createPickup", pickupId, pickup.label, vector3(pickup.coords.x, pickup.coords.y, pickup.coords.z - 1.0), pickup.type, pickup.name, pickup.components, pickup.tintIndex) + end + end) +end + +ESX.SecureNetEvent("esx:registerSuggestions", function(registeredCommands) + for name, command in pairs(registeredCommands) do + if command.suggestion then + TriggerEvent("chat:addSuggestion", ("/%s"):format(name), command.suggestion.help, command.suggestion.arguments) + end + end +end) + +if not Config.CustomInventory then + ESX.SecureNetEvent("esx:removePickup", function(pickupId) + if pickups[pickupId] and pickups[pickupId].obj then + ESX.Game.DeleteObject(pickups[pickupId].obj) + pickups[pickupId] = nil + end + end) +end + +function StartServerSyncLoops() + if Config.CustomInventory then return end + + local currentWeapon = { + ---@type number + ---@diagnostic disable-next-line: assign-type-mismatch + hash = `WEAPON_UNARMED`, + ammo = 0, + } + + local function updateCurrentWeaponAmmo(weaponName) + local newAmmo = GetAmmoInPedWeapon(ESX.PlayerData.ped, currentWeapon.hash) + + if newAmmo ~= currentWeapon.ammo then + currentWeapon.ammo = newAmmo + TriggerServerEvent("esx:updateWeaponAmmo", weaponName, newAmmo) + end + end + + CreateThread(function() + while ESX.PlayerLoaded do + currentWeapon.hash = GetSelectedPedWeapon(ESX.PlayerData.ped) + + if currentWeapon.hash ~= `WEAPON_UNARMED` then + local weaponConfig = ESX.GetWeaponFromHash(currentWeapon.hash) + + if weaponConfig then + currentWeapon.ammo = GetAmmoInPedWeapon(ESX.PlayerData.ped, currentWeapon.hash) + + while GetSelectedPedWeapon(ESX.PlayerData.ped) == currentWeapon.hash do + updateCurrentWeaponAmmo(weaponConfig.name) + Wait(1000) + end + + updateCurrentWeaponAmmo(weaponConfig.name) + end + end + Wait(250) + end + end) + + CreateThread(function() + local PARACHUTE_OPENING = 1 + local PARACHUTE_OPEN = 2 + + while ESX.PlayerLoaded do + local parachuteState = GetPedParachuteState(ESX.PlayerData.ped) + + if parachuteState == PARACHUTE_OPENING or parachuteState == PARACHUTE_OPEN then + TriggerServerEvent("esx:updateWeaponAmmo", "GADGET_PARACHUTE", 0) + + while GetPedParachuteState(ESX.PlayerData.ped) ~= -1 do Wait(1000) end + end + Wait(500) + end + end) +end + +if not Config.CustomInventory and Config.EnableDefaultInventory then + ESX.RegisterInput("showinv", TranslateCap("keymap_showinventory"), "keyboard", "F2", function() + if not ESX.PlayerData.dead then + ESX.ShowInventory() + end + end) +end + +if not Config.CustomInventory then + CreateThread(function() + while true do + local Sleep = 1500 + local playerCoords = GetEntityCoords(ESX.PlayerData.ped) + local _, closestDistance = ESX.Game.GetClosestPlayer(playerCoords) + + for pickupId, pickup in pairs(pickups) do + local distance = #(playerCoords - pickup.coords) + + if distance < 5 then + Sleep = 0 + local label = pickup.label + + if distance < 1 then + if IsControlJustReleased(0, 38) then + if IsPedOnFoot(ESX.PlayerData.ped) and (closestDistance == -1 or closestDistance > 3) and not pickup.inRange then + pickup.inRange = true + + local dict, anim = "weapons@first_person@aim_rng@generic@projectile@sticky_bomb@", "plant_floor" + ESX.Streaming.RequestAnimDict(dict) + TaskPlayAnim(ESX.PlayerData.ped, dict, anim, 8.0, 1.0, 1000, 16, 0.0, false, false, false) + RemoveAnimDict(dict) + Wait(1000) + + TriggerServerEvent("esx:onPickup", pickupId) + PlaySoundFrontend(-1, "PICK_UP", "HUD_FRONTEND_DEFAULT_SOUNDSET", false) + end + end + + label = ("%s~n~%s"):format(label, TranslateCap("threw_pickup_prompt")) + end + + local textCoords = pickup.coords + vector3(0.0, 0.0, 0.25) + ESX.Game.Utils.DrawText3D(textCoords, label, 1.2, 1) + elseif pickup.inRange then + pickup.inRange = false + end + end + Wait(Sleep) + end + end) +end + +----- Admin commands from esx_adminplus +ESX.SecureNetEvent("esx:tpm", function() + local GetEntityCoords = GetEntityCoords + local GetGroundZFor_3dCoord = GetGroundZFor_3dCoord + local GetFirstBlipInfoId = GetFirstBlipInfoId + local DoesBlipExist = DoesBlipExist + local DoScreenFadeOut = DoScreenFadeOut + local GetBlipInfoIdCoord = GetBlipInfoIdCoord + local GetVehiclePedIsIn = GetVehiclePedIsIn + + ESX.TriggerServerCallback("esx:isUserAdmin", function(admin) + if not admin then + return + end + local blipMarker = GetFirstBlipInfoId(8) + if not DoesBlipExist(blipMarker) then + ESX.ShowNotification(TranslateCap("tpm_nowaypoint"), "error") + return "marker" + end + + -- Fade screen to hide how clients get teleported. + DoScreenFadeOut(650) + while not IsScreenFadedOut() do + Wait(0) + end + + local ped, coords = ESX.PlayerData.ped, GetBlipInfoIdCoord(blipMarker) + local vehicle = GetVehiclePedIsIn(ped, false) + local oldCoords = GetEntityCoords(ped) + + -- Unpack coords instead of having to unpack them while iterating. + -- 825.0 seems to be the max a player can reach while 0.0 being the lowest. + local x, y, groundZ, Z_START = coords["x"], coords["y"], 850.0, 950.0 + local found = false + FreezeEntityPosition(vehicle > 0 and vehicle or ped, true) + + for i = Z_START, 0, -25.0 do + local z = i + if (i % 2) ~= 0 then + z = Z_START - i + end + + NewLoadSceneStart(x, y, z, x, y, z, 50.0, 0) + local curTime = GetGameTimer() + while IsNetworkLoadingScene() do + if GetGameTimer() - curTime > 1000 then + break + end + Wait(0) + end + NewLoadSceneStop() + SetPedCoordsKeepVehicle(ped, x, y, z) + + while not HasCollisionLoadedAroundEntity(ped) do + RequestCollisionAtCoord(x, y, z) + if GetGameTimer() - curTime > 1000 then + break + end + Wait(0) + end + + -- Get ground coord. As mentioned in the natives, this only works if the client is in render distance. + found, groundZ = GetGroundZFor_3dCoord(x, y, z, false) + if found then + Wait(0) + SetPedCoordsKeepVehicle(ped, x, y, groundZ) + break + end + Wait(0) + end + + -- Remove black screen once the loop has ended. + DoScreenFadeIn(650) + FreezeEntityPosition(vehicle > 0 and vehicle or ped, false) + + if not found then + -- If we can't find the coords, set the coords to the old ones. + -- We don't unpack them before since they aren't in a loop and only called once. + SetPedCoordsKeepVehicle(ped, oldCoords["x"], oldCoords["y"], oldCoords["z"] - 1.0) + ESX.ShowNotification(TranslateCap("tpm_success"), "success") + end + + -- If Z coord was found, set coords in found coords. + SetPedCoordsKeepVehicle(ped, x, y, groundZ) + ESX.ShowNotification(TranslateCap("tpm_success"), "success") + end) +end) + +local noclip = false +local noclip_pos = vector3(0, 0, 70) +local heading = 0 + +local function noclipThread() + while noclip do + SetEntityCoordsNoOffset(ESX.PlayerData.ped, noclip_pos.x, noclip_pos.y, noclip_pos.z, false, false, true) + + if IsControlPressed(1, 34) then + heading = heading + 1.5 + if heading > 360 then + heading = 0 + end + + SetEntityHeading(ESX.PlayerData.ped, heading) + end + + if IsControlPressed(1, 9) then + heading = heading - 1.5 + if heading < 0 then + heading = 360 + end + + SetEntityHeading(ESX.PlayerData.ped, heading) + end + + if IsControlPressed(1, 8) then + noclip_pos = GetOffsetFromEntityInWorldCoords(ESX.PlayerData.ped, 0.0, 1.0, 0.0) + end + + if IsControlPressed(1, 32) then + noclip_pos = GetOffsetFromEntityInWorldCoords(ESX.PlayerData.ped, 0.0, -1.0, 0.0) + end + + if IsControlPressed(1, 27) then + noclip_pos = GetOffsetFromEntityInWorldCoords(ESX.PlayerData.ped, 0.0, 0.0, 1.0) + end + + if IsControlPressed(1, 173) then + noclip_pos = GetOffsetFromEntityInWorldCoords(ESX.PlayerData.ped, 0.0, 0.0, -1.0) + end + Wait(0) + end +end + +ESX.SecureNetEvent("esx:noclip", function() + ESX.TriggerServerCallback("esx:isUserAdmin", function(admin) + if not admin then + return + end + + if not noclip then + noclip_pos = GetEntityCoords(ESX.PlayerData.ped, false) + heading = GetEntityHeading(ESX.PlayerData.ped) + end + + noclip = not noclip + if noclip then + CreateThread(noclipThread) + end + + if noclip then + ESX.ShowNotification(TranslateCap("noclip_message", Translate("enabled")), "success") + else + ESX.ShowNotification(TranslateCap("noclip_message", Translate("disabled")), "error") + end + end) +end) + +ESX.SecureNetEvent("esx:killPlayer", function() + SetEntityHealth(ESX.PlayerData.ped, 0) +end) + +ESX.SecureNetEvent("esx:repairPedVehicle", function() + local ped = ESX.PlayerData.ped + local vehicle = GetVehiclePedIsIn(ped, false) + SetVehicleEngineHealth(vehicle, 1000) + SetVehicleEngineOn(vehicle, true, true, false) + SetVehicleFixed(vehicle) + SetVehicleDirtLevel(vehicle, 0) +end) + +ESX.SecureNetEvent("esx:freezePlayer", function(input) + if input == "freeze" then + SetEntityCollision(ESX.PlayerData.ped, false, false) + FreezeEntityPosition(ESX.PlayerData.ped, true) + SetPlayerInvincible(ESX.playerId, true) + elseif input == "unfreeze" then + SetEntityCollision(ESX.PlayerData.ped, true, true) + FreezeEntityPosition(ESX.PlayerData.ped, false) + SetPlayerInvincible(ESX.playerId, false) + end +end) + +ESX.RegisterClientCallback("esx:GetVehicleType", function(cb, model) + cb(ESX.GetVehicleTypeClient(model)) +end) + +ESX.SecureNetEvent('esx:updatePlayerData', function(key, val) + ESX.SetPlayerData(key, val) +end) + +AddEventHandler("onResourceStop", function(resource) + if Core.Events[resource] then + for i = 1, #Core.Events[resource] do + RemoveEventHandler(Core.Events[resource][i]) + end + end +end) diff --git a/[core]/es_extended/client/modules/points.lua b/[core]/es_extended/client/modules/points.lua new file mode 100644 index 000000000..fee318be6 --- /dev/null +++ b/[core]/es_extended/client/modules/points.lua @@ -0,0 +1,57 @@ +local points = {} + +function ESX.CreatePointInternal(coords, distance, hidden, enter, leave) + local point = { + coords = coords, + distance = distance, + hidden = hidden, + enter = enter, + leave = leave, + resource = GetInvokingResource() + } + local handle = ESX.Table.SizeOf(points) + 1 + points[handle] = point + return handle +end + +function ESX.RemovePointInternal(handle) + points[handle] = nil +end + +function ESX.HidePointInternal(handle, hidden) + if points[handle] then + points[handle].hidden = hidden + end +end + +function StartPointsLoop() + CreateThread(function() + while true do + local coords = GetEntityCoords(ESX.PlayerData.ped) + for i, point in pairs(points) do + local distance = #(coords - point.coords) + + if not point.hidden and distance <= point.distance then + if not point.nearby then + points[i].nearby = true + points[i].enter() + end + point.currentDistance = distance + elseif point.nearby then + points[i].nearby = false + points[i].leave() + end + end + Wait(500) + end + end) +end + + +AddEventHandler('onResourceStop', function(resource) + for i, point in pairs(points) do + if point.resource == resource then + points[i] = nil + end + end +end) diff --git a/[core]/es_extended/fxmanifest.lua b/[core]/es_extended/fxmanifest.lua index 7660407dc..f2e295c38 100644 --- a/[core]/es_extended/fxmanifest.lua +++ b/[core]/es_extended/fxmanifest.lua @@ -34,19 +34,19 @@ server_scripts { 'server/modules/commands.lua', 'server/bridge/**/*.lua', - 'server/modules/actions.lua', 'server/modules/npwd.lua', 'server/modules/createJob.lua' } client_scripts { - 'client/common.lua', + 'client/main.lua', 'client/functions.lua', 'client/modules/wrapper.lua', 'client/modules/callback.lua', 'client/modules/adjustments.lua', + 'client/modules/points.lua', - 'client/main.lua', + 'client/modules/events.lua', 'client/modules/actions.lua', 'client/modules/death.lua', @@ -73,6 +73,7 @@ files { 'html/fonts/pdown.ttf', 'html/fonts/bankgothic.ttf', + "client/imports/*.lua", } dependencies { diff --git a/[core]/es_extended/imports.lua b/[core]/es_extended/imports.lua index c4bb76c77..2727995d3 100644 --- a/[core]/es_extended/imports.lua +++ b/[core]/es_extended/imports.lua @@ -14,6 +14,7 @@ if not IsDuplicityVersion() then -- Only register this event for the client RegisterNetEvent("esx:playerLoaded", function(xPlayer) ESX.PlayerData = xPlayer + while not ESX.PlayerData.ped or not DoesEntityExist(ESX.PlayerData.ped) do Wait(0) end ESX.PlayerLoaded = true end) @@ -21,4 +22,23 @@ if not IsDuplicityVersion() then -- Only register this event for the client ESX.PlayerLoaded = false ESX.PlayerData = {} end) + + local external = {{"Class", "class.lua"}, {"Point", "point.lua"}} + for i=1, #external do + local module = external[i] + local path = string.format("client/imports/%s", module[2]) + + local file = LoadResourceFile("es_extended", path) + if file then + local fn, err = load(file, ('@@es_extended/%s'):format(path)) + + if not fn or err then + return error(('\n^1Error importing module (%s)'):format(external[i])) + end + + ESX[module[1]] = fn() + else + return error(('\n^1Error loading module (%s)'):format(external[i])) + end + end end diff --git a/[core]/es_extended/locales/cs.lua b/[core]/es_extended/locales/cs.lua index 0e9d3a92b..a9b278fd7 100644 --- a/[core]/es_extended/locales/cs.lua +++ b/[core]/es_extended/locales/cs.lua @@ -368,4 +368,36 @@ Locales["cs"] = { ["tint_lspd"] = "blue skin", ["tint_orange"] = "orange skin", ["tint_platinum"] = "platinum skin", + -- MK2 Weapon Tints + ["tint_classic_gray"] = "klasická šedá", + ["tint_classic_two_tone"] = "klasická dvoutónová", + ["tint_classic_white"] = "klasická bílá", + ["tint_classic_beige"] = "klasická béžová", + ["tint_classic_green"] = "klasická zelená", + ["tint_classic_blue"] = "klasická modrá", + ["tint_classic_earth"] = "klasická hnědá", + ["tint_classic_brown_black"] = "klasická hnědá-černá", + ["tint_contrast_red"] = "kontrastní červená", + ["tint_contrast_blue"] = "kontrastní modrá", + ["tint_contrast_yellow"] = "kontrastní žlutá", + ["tint_contrast_orange"] = "kontrastní oranžová", + ["tint_bold_pink"] = "odvážná růžová", + ["tint_bold_purple_yellow"] = "odvážná fialovo-žlutá", + ["tint_bold_orange"] = "odvážná oranžová", + ["tint_bold_green_purple"] = "odvážná zeleno-fialová", + ["tint_bold_red_feat"] = "odvážná červená feat", + ["tint_bold_green_feat"] = "odvážná zelená feat", + ["tint_bold_cyan_feat"] = "odvážná azurová feat", + ["tint_bold_yellow_feat"] = "odvážná žlutá feat", + ["tint_bold_red_white"] = "odvážná červená bílá", + ["tint_bold_blue_white"] = "odvážná modrá bílá", + ["tint_metallic_gold"] = "metalická zlatá", + ["tint_metallic_platinum"] = "metalická platina", + ["tint_metallic_gray_lilac"] = "metalická šedá lila", + ["tint_metallic_purple_lime"] = "metalická fialová limetka", + ["tint_metallic_red"] = "metalická červená", + ["tint_metallic_green"] = "metalická zelená", + ["tint_metallic_blue"] = "metalická modrá", + ["tint_metallic_white_aqua"] = "metalická bílá aqua", + ["tint_metallic_red_yellow"] = "metalická červená žlutá", } diff --git a/[core]/es_extended/locales/de.lua b/[core]/es_extended/locales/de.lua index cbdb524dd..8951fdf08 100644 --- a/[core]/es_extended/locales/de.lua +++ b/[core]/es_extended/locales/de.lua @@ -21,7 +21,7 @@ Locales["de"] = { ["received_weapon_ammo"] = "Du bekommst ~o~%sx %s für deine %s von %s", ["received_weapon_withammo"] = "Du bekommst %s mit ~o~%sx %s von %s", ["received_weapon_hasalready"] = "%s hat versucht dir eine %s zu geben, jedoch hast du diese Waffe bereits!", - ["received_weapon_noweapon"] = "%s hat versucht dir Munition für eine %s zu geben, jedoch hast du diese Waffe bereits!", + ["received_weapon_noweapon"] = "%s hat versucht dir Munition für eine %s zu geben, jedoch hast du diese Waffe nicht!", ["gave_account_money"] = "Du gibst %s€ (%s) an %s", ["received_account_money"] = "Du bekommst %s€ (%s) von %s", ["amount_invalid"] = "Ungültige Anzahl", @@ -114,9 +114,11 @@ Locales["de"] = { ["commanderror_invalidcommand"] = "Ungültiger Befehl - /%s", ["commanderror_invalidplayerid"] = "Angegebener Spieler ist nicht online!", ["commandgeneric_playerid"] = "Spieler ID", + ["commandgeneric_dimension"] = "Ziel Dimension", ["command_giveammo_noweapon_found"] = "%s besitzt diese Waffe nicht!", ["command_giveammo_weapon"] = "Waffenname", ["command_giveammo_ammo"] = "Munitionsanzahl", + ["command_setdim"] = "Setzt Spieler Dimension!", ["tpm_nowaypoint"] = "Kein Wegpunkt gesetzt!", ["tpm_success"] = "Erfolgreich teleportiert.", @@ -378,4 +380,37 @@ Locales["de"] = { ["tint_lspd"] = "Blau", ["tint_orange"] = "Orange", ["tint_platinum"] = "Platin", + -- MK2 Weapon Tints + ["tint_classic_black"] = "klassisches Schwarz", + ["tint_classic_gray"] = "klassisches Grau", + ["tint_classic_two_tone"] = "klassisches Zwei-Ton", + ["tint_classic_white"] = "klassisches Weiß", + ["tint_classic_beige"] = "klassisches Beige", + ["tint_classic_green"] = "klassisches Grün", + ["tint_classic_blue"] = "klassisches Blau", + ["tint_classic_earth"] = "klassisches Erdfarben", + ["tint_classic_brown_black"] = "klassisches Braun-Schwarz", + ["tint_contrast_red"] = "Kontrast Rot", + ["tint_contrast_blue"] = "Kontrast Blau", + ["tint_contrast_yellow"] = "Kontrast Gelb", + ["tint_contrast_orange"] = "Kontrast Orange", + ["tint_bold_pink"] = "fette Pink", + ["tint_bold_purple_yellow"] = "fette Lila-Gelb", + ["tint_bold_orange"] = "fette Orange", + ["tint_bold_green_purple"] = "fette Grün-Lila", + ["tint_bold_red_feat"] = "fette Rot feat", + ["tint_bold_green_feat"] = "fette Grün feat", + ["tint_bold_cyan_feat"] = "fette Cyan feat", + ["tint_bold_yellow_feat"] = "fette Gelb feat", + ["tint_bold_red_white"] = "fette Rot Weiß", + ["tint_bold_blue_white"] = "fette Blau Weiß", + ["tint_metallic_gold"] = "metallisches Gold", + ["tint_metallic_platinum"] = "metallisches Platin", + ["tint_metallic_gray_lilac"] = "metallisches Grau-Lila", + ["tint_metallic_purple_lime"] = "metallisches Lila-Limette", + ["tint_metallic_red"] = "metallisches Rot", + ["tint_metallic_green"] = "metallisches Grün", + ["tint_metallic_blue"] = "metallisches Blau", + ["tint_metallic_white_aqua"] = "metallisches Weiß-Aqua", + ["tint_metallic_red_yellow"] = "metallisches Rot-Gelb", } diff --git a/[core]/es_extended/locales/el.lua b/[core]/es_extended/locales/el.lua index 1de660c6f..ba1d1ab0b 100644 --- a/[core]/es_extended/locales/el.lua +++ b/[core]/es_extended/locales/el.lua @@ -378,4 +378,37 @@ Locales["el"] = { ["tint_lspd"] = "μπλε δέρμα", ["tint_orange"] = "πορτοκαλί δέρμα", ["tint_platinum"] = "πλατίνενο δέρμα", + -- MK2 Weapon Tints + ["tint_classic_black"] = "κλασικό μαύρο", + ["tint_classic_gray"] = "κλασικό γκρι", + ["tint_classic_two_tone"] = "κλασικό δίχρωμο", + ["tint_classic_white"] = "κλασικό λευκό", + ["tint_classic_beige"] = "κλασικό μπεζ", + ["tint_classic_green"] = "κλασικό πράσινο", + ["tint_classic_blue"] = "κλασικό μπλε", + ["tint_classic_earth"] = "κλασική γή", + ["tint_classic_brown_black"] = "κλασικό καφέ-μαύρο", + ["tint_contrast_red"] = "αντίθεση κόκκινο", + ["tint_contrast_blue"] = "αντίθεση μπλε", + ["tint_contrast_yellow"] = "αντίθεση κίτρινο", + ["tint_contrast_orange"] = "αντίθεση πορτοκαλί", + ["tint_bold_pink"] = "τολμηρό ροζ", + ["tint_bold_purple_yellow"] = "τολμηρό μοβ-κίτρινο", + ["tint_bold_orange"] = "τολμηρό πορτοκαλί", + ["tint_bold_green_purple"] = "τολμηρό πράσινο-μοβ", + ["tint_bold_red_feat"] = "τολμηρό κόκκινο feat", + ["tint_bold_green_feat"] = "τολμηρό πράσινο feat", + ["tint_bold_cyan_feat"] = "τολμηρό κυανό feat", + ["tint_bold_yellow_feat"] = "τολμηρό κίτρινο feat", + ["tint_bold_red_white"] = "τολμηρό κόκκινο λευκό", + ["tint_bold_blue_white"] = "τολμηρό μπλε λευκό", + ["tint_metallic_gold"] = "μεταλλικό χρυσό", + ["tint_metallic_platinum"] = "μεταλλικό πλατίνα", + ["tint_metallic_gray_lilac"] = "μεταλλικό γκρι λιλά", + ["tint_metallic_purple_lime"] = "μεταλλικό μοβ-λάιμ", + ["tint_metallic_red"] = "μεταλλικό κόκκινο", + ["tint_metallic_green"] = "μεταλλικό πράσινο", + ["tint_metallic_blue"] = "μεταλλικό μπλε", + ["tint_metallic_white_aqua"] = "μεταλλικό λευκό aqua", + ["tint_metallic_red_yellow"] = "μεταλλικό κόκκινο-κίτρινο", } diff --git a/[core]/es_extended/locales/en.lua b/[core]/es_extended/locales/en.lua index 10a0bdd5f..44d622930 100644 --- a/[core]/es_extended/locales/en.lua +++ b/[core]/es_extended/locales/en.lua @@ -114,9 +114,11 @@ Locales["en"] = { ["commanderror_invalidcommand"] = "Invalid Command - /%s", ["commanderror_invalidplayerid"] = "Specified Player is not online", ["commandgeneric_playerid"] = "Player`s Server Id", + ["commandgeneric_dimension"] = "Target Dimension", ["command_giveammo_noweapon_found"] = "%s does not have that weapon", ["command_giveammo_weapon"] = "Weapon name", ["command_giveammo_ammo"] = "Ammo Quantity", + ["command_setdim"] = "Set a players dimension", ["tpm_nowaypoint"] = "No Waypoint Set.", ["tpm_success"] = "Successfully Teleported", @@ -378,4 +380,37 @@ Locales["en"] = { ["tint_lspd"] = "blue skin", ["tint_orange"] = "orange skin", ["tint_platinum"] = "platinum skin", + -- MK2 Weapon Tints + ["tint_classic_black"] = "classic black", + ["tint_classic_gray"] = "classic gray", + ["tint_classic_two_tone"] = "classic two-tone", + ["tint_classic_white"] = "classic white", + ["tint_classic_beige"] = "classic beige", + ["tint_classic_green"] = "classic green", + ["tint_classic_blue"] = "classic blue", + ["tint_classic_earth"] = "classic earth", + ["tint_classic_brown_black"] = "classic brown-black", + ["tint_contrast_red"] = "contrast red", + ["tint_contrast_blue"] = "contrast blue", + ["tint_contrast_yellow"] = "contrast yellow", + ["tint_contrast_orange"] = "contrast orange", + ["tint_bold_pink"] = "bold pink", + ["tint_bold_purple_yellow"] = "bold purple-yellow", + ["tint_bold_orange"] = "bold orange", + ["tint_bold_green_purple"] = "bold green-purple", + ["tint_bold_red_feat"] = "bold red feat", + ["tint_bold_green_feat"] = "bold green feat", + ["tint_bold_cyan_feat"] = "bold cyan feat", + ["tint_bold_yellow_feat"] = "bold yellow feat", + ["tint_bold_red_white"] = "bold red-white", + ["tint_bold_blue_white"] = "bold blue-white", + ["tint_metallic_gold"] = "metallic gold", + ["tint_metallic_platinum"] = "metallic platinum", + ["tint_metallic_gray_lilac"] = "metallic gray-lilac", + ["tint_metallic_purple_lime"] = "metallic purple-lime", + ["tint_metallic_red"] = "metallic red", + ["tint_metallic_green"] = "metallic green", + ["tint_metallic_blue"] = "metallic blue", + ["tint_metallic_white_aqua"] = "metallic white-aqua", + ["tint_metallic_red_yellow"] = "metallic red-yellow", } diff --git a/[core]/es_extended/locales/es.lua b/[core]/es_extended/locales/es.lua index 9ee9a33b2..9d03a65d2 100644 --- a/[core]/es_extended/locales/es.lua +++ b/[core]/es_extended/locales/es.lua @@ -363,8 +363,37 @@ Locales["es"] = { ["tint_lspd"] = "Skin Azul", ["tint_orange"] = "Skin Naranja", ["tint_platinum"] = "Skin Plata", - - -- Duty related - ["stopped_duty"] = "Has salido de servicio.", - ["started_duty"] = "Has entrado de servicio.", + -- MK2 Weapon Tints + ["tint_classic_black"] = "negro clásico", + ["tint_classic_gray"] = "gris clásico", + ["tint_classic_two_tone"] = "dos tonos clásicos", + ["tint_classic_white"] = "blanco clásico", + ["tint_classic_beige"] = "beige clásico", + ["tint_classic_green"] = "verde clásico", + ["tint_classic_blue"] = "azul clásico", + ["tint_classic_earth"] = "tierra clásica", + ["tint_classic_brown_black"] = "marrón negro clásico", + ["tint_contrast_red"] = "rojo de contraste", + ["tint_contrast_blue"] = "azul de contraste", + ["tint_contrast_yellow"] = "amarillo de contraste", + ["tint_contrast_orange"] = "naranja de contraste", + ["tint_bold_pink"] = "rosa atrevida", + ["tint_bold_purple_yellow"] = "púrpura amarilla atrevida", + ["tint_bold_orange"] = "naranja atrevido", + ["tint_bold_green_purple"] = "verde púrpura atrevido", + ["tint_bold_red_feat"] = "rojo atrevido feat", + ["tint_bold_green_feat"] = "verde atrevido feat", + ["tint_bold_cyan_feat"] = "cian atrevido feat", + ["tint_bold_yellow_feat"] = "amarillo atrevido feat", + ["tint_bold_red_white"] = "rojo blanco atrevido", + ["tint_bold_blue_white"] = "azul blanco atrevido", + ["tint_metallic_gold"] = "oro metálico", + ["tint_metallic_platinum"] = "platino metálico", + ["tint_metallic_gray_lilac"] = "gris lila metálico", + ["tint_metallic_purple_lime"] = "púrpura lima metálico", + ["tint_metallic_red"] = "rojo metálico", + ["tint_metallic_green"] = "verde metálico", + ["tint_metallic_blue"] = "azul metálico", + ["tint_metallic_white_aqua"] = "blanco aqua metálico", + ["tint_metallic_red_yellow"] = "rojo amarillo metálico", } diff --git a/[core]/es_extended/locales/fi.lua b/[core]/es_extended/locales/fi.lua index 983fa79b8..4d71ff482 100644 --- a/[core]/es_extended/locales/fi.lua +++ b/[core]/es_extended/locales/fi.lua @@ -237,4 +237,37 @@ Locales["fi"] = { ["tint_lspd"] = "Sininen ulkokuori", ["tint_orange"] = "Oranssi ulkokuori", ["tint_platinum"] = "Platina ulkokuori", + -- MK2 Weapon Tints + ["tint_classic_black"] = "klassinen musta", + ["tint_classic_gray"] = "klassinen harmaa", + ["tint_classic_two_tone"] = "klassinen kaksivärinen", + ["tint_classic_white"] = "klassinen valkoinen", + ["tint_classic_beige"] = "klassinen beessi", + ["tint_classic_green"] = "klassinen vihreä", + ["tint_classic_blue"] = "klassinen sininen", + ["tint_classic_earth"] = "klassinen maa", + ["tint_classic_brown_black"] = "klassinen ruskea-musta", + ["tint_contrast_red"] = "kontrastinen punainen", + ["tint_contrast_blue"] = "kontrastinen sininen", + ["tint_contrast_yellow"] = "kontrastinen keltainen", + ["tint_contrast_orange"] = "kontrastinen oranssi", + ["tint_bold_pink"] = "rohkea vaaleanpunainen", + ["tint_bold_purple_yellow"] = "rohkea violetti-keltainen", + ["tint_bold_orange"] = "rohkea oranssi", + ["tint_bold_green_purple"] = "rohkea vihreä-violetti", + ["tint_bold_red_feat"] = "rohkea punainen feat", + ["tint_bold_green_feat"] = "rohkea vihreä feat", + ["tint_bold_cyan_feat"] = "rohkea syaani feat", + ["tint_bold_yellow_feat"] = "rohkea keltainen feat", + ["tint_bold_red_white"] = "rohkea punainen valkoinen", + ["tint_bold_blue_white"] = "rohkea sininen valkoinen", + ["tint_metallic_gold"] = "metallinen kulta", + ["tint_metallic_platinum"] = "metallinen platina", + ["tint_metallic_gray_lilac"] = "metallinen harmaa lila", + ["tint_metallic_purple_lime"] = "metallinen violetti limetti", + ["tint_metallic_red"] = "metallinen punainen", + ["tint_metallic_green"] = "metallinen vihreä", + ["tint_metallic_blue"] = "metallinen sininen", + ["tint_metallic_white_aqua"] = "metallinen valkoinen aqua", + ["tint_metallic_red_yellow"] = "metallinen punainen keltainen", } diff --git a/[core]/es_extended/locales/fr.lua b/[core]/es_extended/locales/fr.lua index 44760c691..3792406e2 100644 --- a/[core]/es_extended/locales/fr.lua +++ b/[core]/es_extended/locales/fr.lua @@ -378,4 +378,37 @@ Locales["fr"] = { ["tint_lspd"] = "skin bleu", ["tint_orange"] = "skin orange", ["tint_platinum"] = "skin platine", + -- MK2 Weapon Tints + ["tint_classic_black"] = "noir classique", + ["tint_classic_gray"] = "gris classique", + ["tint_classic_two_tone"] = "deux tons classiques", + ["tint_classic_white"] = "blanc classique", + ["tint_classic_beige"] = "beige classique", + ["tint_classic_green"] = "vert classique", + ["tint_classic_blue"] = "bleu classique", + ["tint_classic_earth"] = "terre classique", + ["tint_classic_brown_black"] = "marron noir classique", + ["tint_contrast_red"] = "rouge contrasté", + ["tint_contrast_blue"] = "bleu contrasté", + ["tint_contrast_yellow"] = "jaune contrasté", + ["tint_contrast_orange"] = "orange contrasté", + ["tint_bold_pink"] = "rose audacieux", + ["tint_bold_purple_yellow"] = "violet jaune audacieux", + ["tint_bold_orange"] = "orange audacieux", + ["tint_bold_green_purple"] = "vert violet audacieux", + ["tint_bold_red_feat"] = "rouge audacieux feat", + ["tint_bold_green_feat"] = "vert audacieux feat", + ["tint_bold_cyan_feat"] = "cyan audacieux feat", + ["tint_bold_yellow_feat"] = "jaune audacieux feat", + ["tint_bold_red_white"] = "rouge blanc audacieux", + ["tint_bold_blue_white"] = "bleu blanc audacieux", + ["tint_metallic_gold"] = "or métallique", + ["tint_metallic_platinum"] = "platine métallique", + ["tint_metallic_gray_lilac"] = "gris lilas métallique", + ["tint_metallic_purple_lime"] = "violet lime métallique", + ["tint_metallic_red"] = "rouge métallique", + ["tint_metallic_green"] = "vert métallique", + ["tint_metallic_blue"] = "bleu métallique", + ["tint_metallic_white_aqua"] = "blanc aqua métallique", + ["tint_metallic_red_yellow"] = "rouge jaune métallique", } diff --git a/[core]/es_extended/locales/he.lua b/[core]/es_extended/locales/he.lua index 12ebc9e5f..d6216573b 100644 --- a/[core]/es_extended/locales/he.lua +++ b/[core]/es_extended/locales/he.lua @@ -372,4 +372,37 @@ Locales["he"] = { ["tint_lspd"] = "צבע כחול", ["tint_orange"] = "צבע כתום", ["tint_platinum"] = "צבע פלטינה", + -- MK2 Weapon Tints + ["tint_classic_black"] = "שחור קלאסי", + ["tint_classic_gray"] = "אפור קלאסי", + ["tint_classic_two_tone"] = "קלאסי דו-גוני", + ["tint_classic_white"] = "לבן קלאסי", + ["tint_classic_beige"] = "בז' קלאסי", + ["tint_classic_green"] = "ירוק קלאסי", + ["tint_classic_blue"] = "כחול קלאסי", + ["tint_classic_earth"] = "אדמה קלאסית", + ["tint_classic_brown_black"] = "חום שחור קלאסי", + ["tint_contrast_red"] = "אדום קונטרסט", + ["tint_contrast_blue"] = "כחול קונטרסט", + ["tint_contrast_yellow"] = "צהוב קונטרסט", + ["tint_contrast_orange"] = "כתום קונטרסט", + ["tint_bold_pink"] = "ורוד נועז", + ["tint_bold_purple_yellow"] = "סגול צהוב נועז", + ["tint_bold_orange"] = "כתום נועז", + ["tint_bold_green_purple"] = "ירוק סגול נועז", + ["tint_bold_red_feat"] = "אדום נועז feat", + ["tint_bold_green_feat"] = "ירוק נועז feat", + ["tint_bold_cyan_feat"] = "סיאן נועז feat", + ["tint_bold_yellow_feat"] = "צהוב נועז feat", + ["tint_bold_red_white"] = "אדום לבן נועז", + ["tint_bold_blue_white"] = "כחול לבן נועז", + ["tint_metallic_gold"] = "זהב מתכתי", + ["tint_metallic_platinum"] = "פלטינה מתכתית", + ["tint_metallic_gray_lilac"] = "אפור לילך מתכתי", + ["tint_metallic_purple_lime"] = "סגול ליים מתכתי", + ["tint_metallic_red"] = "אדום מתכתי", + ["tint_metallic_green"] = "ירוק מתכתי", + ["tint_metallic_blue"] = "כחול מתכתי", + ["tint_metallic_white_aqua"] = "לבן aqua מתכתי", + ["tint_metallic_red_yellow"] = "אדום צהוב מתכתי", } diff --git a/[core]/es_extended/locales/hu.lua b/[core]/es_extended/locales/hu.lua index 6971d6623..5d3b230be 100644 --- a/[core]/es_extended/locales/hu.lua +++ b/[core]/es_extended/locales/hu.lua @@ -374,8 +374,37 @@ Locales["hu"] = { ["tint_lspd"] = "blue skin", ["tint_orange"] = "orange skin", ["tint_platinum"] = "platinum skin", - - -- Duty related - ["stopped_duty"] = "Leadtad a szolgálatot.", - ["started_duty"] = "Szolgálatba álltál.", + -- MK2 Weapon Tints + ["tint_classic_black"] = "klasszikus fekete", + ["tint_classic_gray"] = "klasszikus szürke", + ["tint_classic_two_tone"] = "klasszikus két szín", + ["tint_classic_white"] = "klasszikus fehér", + ["tint_classic_beige"] = "klasszikus bézs", + ["tint_classic_green"] = "klasszikus zöld", + ["tint_classic_blue"] = "klasszikus kék", + ["tint_classic_earth"] = "klasszikus föld", + ["tint_classic_brown_black"] = "klasszikus barna-fekete", + ["tint_contrast_red"] = "kontraszt piros", + ["tint_contrast_blue"] = "kontraszt kék", + ["tint_contrast_yellow"] = "kontraszt sárga", + ["tint_contrast_orange"] = "kontraszt narancs", + ["tint_bold_pink"] = "merész rózsaszín", + ["tint_bold_purple_yellow"] = "merész lila-sárga", + ["tint_bold_orange"] = "merész narancs", + ["tint_bold_green_purple"] = "merész zöld-lila", + ["tint_bold_red_feat"] = "merész piros feat", + ["tint_bold_green_feat"] = "merész zöld feat", + ["tint_bold_cyan_feat"] = "merész cián feat", + ["tint_bold_yellow_feat"] = "merész sárga feat", + ["tint_bold_red_white"] = "merész piros fehér", + ["tint_bold_blue_white"] = "merész kék fehér", + ["tint_metallic_gold"] = "metál arany", + ["tint_metallic_platinum"] = "metál platina", + ["tint_metallic_gray_lilac"] = "metál szürke lila", + ["tint_metallic_purple_lime"] = "metál lila lime", + ["tint_metallic_red"] = "metál piros", + ["tint_metallic_green"] = "metál zöld", + ["tint_metallic_blue"] = "metál kék", + ["tint_metallic_white_aqua"] = "metál fehér aqua", + ["tint_metallic_red_yellow"] = "metál piros sárga", } diff --git a/[core]/es_extended/locales/id.lua b/[core]/es_extended/locales/id.lua index 1d7d1d822..bbd2587c7 100644 --- a/[core]/es_extended/locales/id.lua +++ b/[core]/es_extended/locales/id.lua @@ -378,4 +378,37 @@ Locales["id"] = { ["tint_lspd"] = "blue skin", ["tint_orange"] = "orange skin", ["tint_platinum"] = "platinum skin", + -- MK2 Weapon Tints + ["tint_classic_black"] = "hitam klasik", + ["tint_classic_gray"] = "abu-abu klasik", + ["tint_classic_two_tone"] = "dua warna klasik", + ["tint_classic_white"] = "putih klasik", + ["tint_classic_beige"] = "beige klasik", + ["tint_classic_green"] = "hijau klasik", + ["tint_classic_blue"] = "biru klasik", + ["tint_classic_earth"] = "tanah klasik", + ["tint_classic_brown_black"] = "coklat hitam klasik", + ["tint_contrast_red"] = "merah kontras", + ["tint_contrast_blue"] = "biru kontras", + ["tint_contrast_yellow"] = "kuning kontras", + ["tint_contrast_orange"] = "oren kontras", + ["tint_bold_pink"] = "pink berani", + ["tint_bold_purple_yellow"] = "ungu kuning berani", + ["tint_bold_orange"] = "oren berani", + ["tint_bold_green_purple"] = "hijau ungu berani", + ["tint_bold_red_feat"] = "merah berani feat", + ["tint_bold_green_feat"] = "hijau berani feat", + ["tint_bold_cyan_feat"] = "sian berani feat", + ["tint_bold_yellow_feat"] = "kuning berani feat", + ["tint_bold_red_white"] = "merah putih berani", + ["tint_bold_blue_white"] = "biru putih berani", + ["tint_metallic_gold"] = "emas metalik", + ["tint_metallic_platinum"] = "platina metalik", + ["tint_metallic_gray_lilac"] = "abu-abu lilac metalik", + ["tint_metallic_purple_lime"] = "ungu jeruk nipis metalik", + ["tint_metallic_red"] = "merah metalik", + ["tint_metallic_green"] = "hijau metalik", + ["tint_metallic_blue"] = "biru metalik", + ["tint_metallic_white_aqua"] = "putih aqua metalik", + ["tint_metallic_red_yellow"] = "merah kuning metalik", } diff --git a/[core]/es_extended/locales/it.lua b/[core]/es_extended/locales/it.lua index 24280c155..8a7caf594 100644 --- a/[core]/es_extended/locales/it.lua +++ b/[core]/es_extended/locales/it.lua @@ -378,4 +378,37 @@ Locales["it"] = { ["tint_lspd"] = "color blu", ["tint_orange"] = "color arancio", ["tint_platinum"] = "color platino", + -- MK2 Weapon Tints + ["tint_classic_black"] = "nero classico", + ["tint_classic_gray"] = "grigio classico", + ["tint_classic_two_tone"] = "due toni classico", + ["tint_classic_white"] = "bianco classico", + ["tint_classic_beige"] = "beige classico", + ["tint_classic_green"] = "verde classico", + ["tint_classic_blue"] = "blu classico", + ["tint_classic_earth"] = "terra classica", + ["tint_classic_brown_black"] = "marrone nero classico", + ["tint_contrast_red"] = "rosso contrastante", + ["tint_contrast_blue"] = "blu contrastante", + ["tint_contrast_yellow"] = "giallo contrastante", + ["tint_contrast_orange"] = "arancione contrastante", + ["tint_bold_pink"] = "rosa audace", + ["tint_bold_purple_yellow"] = "viola giallo audace", + ["tint_bold_orange"] = "arancione audace", + ["tint_bold_green_purple"] = "verde viola audace", + ["tint_bold_red_feat"] = "rosso audace feat", + ["tint_bold_green_feat"] = "verde audace feat", + ["tint_bold_cyan_feat"] = "cyan audace feat", + ["tint_bold_yellow_feat"] = "giallo audace feat", + ["tint_bold_red_white"] = "rosso bianco audace", + ["tint_bold_blue_white"] = "blu bianco audace", + ["tint_metallic_gold"] = "oro metallico", + ["tint_metallic_platinum"] = "platino metallico", + ["tint_metallic_gray_lilac"] = "grigio lilla metallico", + ["tint_metallic_purple_lime"] = "viola lime metallico", + ["tint_metallic_red"] = "rosso metallico", + ["tint_metallic_green"] = "verde metallico", + ["tint_metallic_blue"] = "blu metallico", + ["tint_metallic_white_aqua"] = "bianco aqua metallico", + ["tint_metallic_red_yellow"] = "rosso giallo metallico", } diff --git a/[core]/es_extended/locales/nl.lua b/[core]/es_extended/locales/nl.lua index b6a699aca..2dee1716e 100644 --- a/[core]/es_extended/locales/nl.lua +++ b/[core]/es_extended/locales/nl.lua @@ -369,4 +369,37 @@ Locales["nl"] = { ["tint_lspd"] = "blauwe skin", ["tint_orange"] = "oranje skin", ["tint_platinum"] = "platina skin", + -- MK2 Weapon Tints + ["tint_classic_black"] = "klassiek zwart", + ["tint_classic_gray"] = "klassiek grijs", + ["tint_classic_two_tone"] = "klassiek twee-tonig", + ["tint_classic_white"] = "klassiek wit", + ["tint_classic_beige"] = "klassiek beige", + ["tint_classic_green"] = "klassiek groen", + ["tint_classic_blue"] = "klassiek blauw", + ["tint_classic_earth"] = "klassieke aarde", + ["tint_classic_brown_black"] = "klassiek bruin zwart", + ["tint_contrast_red"] = "contrast rood", + ["tint_contrast_blue"] = "contrast blauw", + ["tint_contrast_yellow"] = "contrast geel", + ["tint_contrast_orange"] = "contrast oranje", + ["tint_bold_pink"] = "gedurfde roze", + ["tint_bold_purple_yellow"] = "gedurfde paarse geel", + ["tint_bold_orange"] = "gedurfde oranje", + ["tint_bold_green_purple"] = "gedurfde groene paarse", + ["tint_bold_red_feat"] = "gedurfde rode feat", + ["tint_bold_green_feat"] = "gedurfde groene feat", + ["tint_bold_cyan_feat"] = "gedurfde cyaan feat", + ["tint_bold_yellow_feat"] = "gedurfde gele feat", + ["tint_bold_red_white"] = "gedurfde rode witte", + ["tint_bold_blue_white"] = "gedurfde blauwe witte", + ["tint_metallic_gold"] = "metallisch goud", + ["tint_metallic_platinum"] = "metallisch platina", + ["tint_metallic_gray_lilac"] = "metallisch grijs lila", + ["tint_metallic_purple_lime"] = "metallisch paarse limo", + ["tint_metallic_red"] = "metallisch rood", + ["tint_metallic_green"] = "metallisch groen", + ["tint_metallic_blue"] = "metallisch blauw", + ["tint_metallic_white_aqua"] = "metallisch wit aqua", + ["tint_metallic_red_yellow"] = "metallisch rood geel", } diff --git a/[core]/es_extended/locales/pl.lua b/[core]/es_extended/locales/pl.lua index d50f91eb7..a9dceb4f1 100644 --- a/[core]/es_extended/locales/pl.lua +++ b/[core]/es_extended/locales/pl.lua @@ -236,4 +236,37 @@ Locales["pl"] = { ["tint_lspd"] = "niebieski skin", ["tint_orange"] = "pomarańczowy skin", ["tint_platinum"] = "platynowy skin", + -- MK2 Weapon Tints + ["tint_classic_black"] = "klasyczna czerń", + ["tint_classic_gray"] = "klasyczny szary", + ["tint_classic_two_tone"] = "klasyczny dwutonowy", + ["tint_classic_white"] = "klasyczna biel", + ["tint_classic_beige"] = "klasyczny beż", + ["tint_classic_green"] = "klasyczna zieleń", + ["tint_classic_blue"] = "klasyczny niebieski", + ["tint_classic_earth"] = "klasyczna ziemia", + ["tint_classic_brown_black"] = "klasyczny brązowo-czarny", + ["tint_contrast_red"] = "kontrastowy czerwony", + ["tint_contrast_blue"] = "kontrastowy niebieski", + ["tint_contrast_yellow"] = "kontrastowy żółty", + ["tint_contrast_orange"] = "kontrastowy pomarańczowy", + ["tint_bold_pink"] = "odważny różowy", + ["tint_bold_purple_yellow"] = "odważny fioletowo-żółty", + ["tint_bold_orange"] = "odważny pomarańczowy", + ["tint_bold_green_purple"] = "odważny zielono-fioletowy", + ["tint_bold_red_feat"] = "odważny czerwony feat", + ["tint_bold_green_feat"] = "odważny zielony feat", + ["tint_bold_cyan_feat"] = "odważny cyjan feat", + ["tint_bold_yellow_feat"] = "odważny żółty feat", + ["tint_bold_red_white"] = "odważny czerwony biały", + ["tint_bold_blue_white"] = "odważny niebieski biały", + ["tint_metallic_gold"] = "złoto metaliczne", + ["tint_metallic_platinum"] = "platyna metaliczna", + ["tint_metallic_gray_lilac"] = "szaro-liliowe metaliczne", + ["tint_metallic_purple_lime"] = "fioletowo-limonkowe metaliczne", + ["tint_metallic_red"] = "czerwony metaliczny", + ["tint_metallic_green"] = "zielony metaliczny", + ["tint_metallic_blue"] = "niebieski metaliczny", + ["tint_metallic_white_aqua"] = "białe aqua metaliczne", + ["tint_metallic_red_yellow"] = "czerwono-żółte metaliczne", } diff --git a/[core]/es_extended/locales/sl.lua b/[core]/es_extended/locales/sl.lua index 2c3e1f8e8..da0c9de44 100644 --- a/[core]/es_extended/locales/sl.lua +++ b/[core]/es_extended/locales/sl.lua @@ -374,4 +374,37 @@ Locales["sl"] = { ["tint_lspd"] = "blue skin", ["tint_orange"] = "orange skin", ["tint_platinum"] = "platinum skin", + -- MK2 Weapon Tints + ["tint_classic_black"] = "klasična črna", + ["tint_classic_gray"] = "klasična siva", + ["tint_classic_two_tone"] = "klasična dvo-tonska", + ["tint_classic_white"] = "klasična bela", + ["tint_classic_beige"] = "klasična bež", + ["tint_classic_green"] = "klasična zelena", + ["tint_classic_blue"] = "klasična modra", + ["tint_classic_earth"] = "klasična zemlja", + ["tint_classic_brown_black"] = "klasična rjava-črna", + ["tint_contrast_red"] = "kontrastna rdeča", + ["tint_contrast_blue"] = "kontrastna modra", + ["tint_contrast_yellow"] = "kontrastna rumena", + ["tint_contrast_orange"] = "kontrastna oranžna", + ["tint_bold_pink"] = "drzna roza", + ["tint_bold_purple_yellow"] = "drzna vijolično-rumena", + ["tint_bold_orange"] = "drzna oranžna", + ["tint_bold_green_purple"] = "drzna zelena-vijolična", + ["tint_bold_red_feat"] = "drzna rdeča feat", + ["tint_bold_green_feat"] = "drzna zelena feat", + ["tint_bold_cyan_feat"] = "drzna cian feat", + ["tint_bold_yellow_feat"] = "drzna rumena feat", + ["tint_bold_red_white"] = "drzna rdeča bela", + ["tint_bold_blue_white"] = "drzna modra bela", + ["tint_metallic_gold"] = "metalik zlato", + ["tint_metallic_platinum"] = "metalik platina", + ["tint_metallic_gray_lilac"] = "metalik siv lila", + ["tint_metallic_purple_lime"] = "metalik vijolična limona", + ["tint_metallic_red"] = "metalik rdeča", + ["tint_metallic_green"] = "metalik zelena", + ["tint_metallic_blue"] = "metalik modra", + ["tint_metallic_white_aqua"] = "metalik bela aqua", + ["tint_metallic_red_yellow"] = "metalik rdeče rumeno", } diff --git a/[core]/es_extended/locales/sr.lua b/[core]/es_extended/locales/sr.lua index 6aefa25bc..9ef517030 100644 --- a/[core]/es_extended/locales/sr.lua +++ b/[core]/es_extended/locales/sr.lua @@ -374,4 +374,37 @@ Locales["sr"] = { ["tint_lspd"] = "blue skin", ["tint_orange"] = "orange skin", ["tint_platinum"] = "platinum skin", + -- MK2 Weapon Tints + ["tint_classic_black"] = "klasična crna", + ["tint_classic_gray"] = "klasična siva", + ["tint_classic_two_tone"] = "klasična dvo-tonska", + ["tint_classic_white"] = "klasična bela", + ["tint_classic_beige"] = "klasična bež", + ["tint_classic_green"] = "klasična zelena", + ["tint_classic_blue"] = "klasična plava", + ["tint_classic_earth"] = "klasična zemlja", + ["tint_classic_brown_black"] = "klasična braon-crna", + ["tint_contrast_red"] = "kontrastna crvena", + ["tint_contrast_blue"] = "kontrastna plava", + ["tint_contrast_yellow"] = "kontrastna žuta", + ["tint_contrast_orange"] = "kontrastna narandžasta", + ["tint_bold_pink"] = "drska roze", + ["tint_bold_purple_yellow"] = "drska ljubičasto-žuta", + ["tint_bold_orange"] = "drska narandžasta", + ["tint_bold_green_purple"] = "drska zelena-ljubičasta", + ["tint_bold_red_feat"] = "drska crvena feat", + ["tint_bold_green_feat"] = "drska zelena feat", + ["tint_bold_cyan_feat"] = "drska cijan feat", + ["tint_bold_yellow_feat"] = "drska žuta feat", + ["tint_bold_red_white"] = "drska crvena bela", + ["tint_bold_blue_white"] = "drska plava bela", + ["tint_metallic_gold"] = "metalik zlatna", + ["tint_metallic_platinum"] = "metalik platina", + ["tint_metallic_gray_lilac"] = "metalik siva lila", + ["tint_metallic_purple_lime"] = "metalik ljubičasta limeta", + ["tint_metallic_red"] = "metalik crvena", + ["tint_metallic_green"] = "metalik zelena", + ["tint_metallic_blue"] = "metalik plava", + ["tint_metallic_white_aqua"] = "metalik bela aqua", + ["tint_metallic_red_yellow"] = "metalik crvena-žuta", } diff --git a/[core]/es_extended/locales/sv.lua b/[core]/es_extended/locales/sv.lua index 193089a71..e528baca5 100644 --- a/[core]/es_extended/locales/sv.lua +++ b/[core]/es_extended/locales/sv.lua @@ -378,4 +378,37 @@ Locales["sv"] = { ["tint_lspd"] = "blue skin", ["tint_orange"] = "orange skin", ["tint_platinum"] = "platinum skin", + -- MK2 Weapon Tints + ["tint_classic_black"] = "klassisk svart", + ["tint_classic_gray"] = "klassisk grå", + ["tint_classic_two_tone"] = "klassisk tvåfärgad", + ["tint_classic_white"] = "klassisk vit", + ["tint_classic_beige"] = "klassisk beige", + ["tint_classic_green"] = "klassisk grön", + ["tint_classic_blue"] = "klassisk blå", + ["tint_classic_earth"] = "klassisk jord", + ["tint_classic_brown_black"] = "klassisk brun svart", + ["tint_contrast_red"] = "kontrast röd", + ["tint_contrast_blue"] = "kontrast blå", + ["tint_contrast_yellow"] = "kontrast gul", + ["tint_contrast_orange"] = "kontrast orange", + ["tint_bold_pink"] = "djärv rosa", + ["tint_bold_purple_yellow"] = "djärv lila gul", + ["tint_bold_orange"] = "djärv orange", + ["tint_bold_green_purple"] = "djärv grön lila", + ["tint_bold_red_feat"] = "djärv röd feat", + ["tint_bold_green_feat"] = "djärv grön feat", + ["tint_bold_cyan_feat"] = "djärv cyan feat", + ["tint_bold_yellow_feat"] = "djärv gul feat", + ["tint_bold_red_white"] = "djärv röd vit", + ["tint_bold_blue_white"] = "djärv blå vit", + ["tint_metallic_gold"] = "metalliskt guld", + ["tint_metallic_platinum"] = "metalliskt platina", + ["tint_metallic_gray_lilac"] = "metalliskt grå lila", + ["tint_metallic_purple_lime"] = "metalliskt lila lime", + ["tint_metallic_red"] = "metalliskt röd", + ["tint_metallic_green"] = "metalliskt grön", + ["tint_metallic_blue"] = "metalliskt blå", + ["tint_metallic_white_aqua"] = "metalliskt vitt aqua", + ["tint_metallic_red_yellow"] = "metalliskt röd gul", } diff --git a/[core]/es_extended/locales/tr.lua b/[core]/es_extended/locales/tr.lua new file mode 100644 index 000000000..f12d64957 --- /dev/null +++ b/[core]/es_extended/locales/tr.lua @@ -0,0 +1,381 @@ +Locales["tr"] = { + -- Inventory + ["inventory"] = "Envanter ( Ağırlık %s / %s )", + ["use"] = "Kullan", + ["give"] = "Ver", + ["remove"] = "At", + ["return"] = "Geri Ver", + ["give_to"] = "Şuna Ver", + ["amount"] = "Miktar", + ["giveammo"] = "Mermi Ver", + ["amountammo"] = "Mermi Miktarı", + ["noammo"] = "Yeterli Değil!", + ["gave_item"] = "Verilen %sx %s %s'ye", + ["received_item"] = "Alınan %sx %s %s'den", + ["gave_weapon"] = "Verilen %s %s'ye", + ["gave_weapon_ammo"] = "Verilen ~o~%sx %s %s için %s'ye", + ["gave_weapon_withammo"] = "Verilen %s ile ~o~%sx %s %s'ye", + ["gave_weapon_hasalready"] = "%s Zaten Bir %s Sahip", + ["gave_weapon_noweapon"] = "%s O Silahı Sahip Değil", + ["received_weapon"] = "%s'den %s Alındı", + ["received_weapon_ammo"] = "%s'den %s için ~o~%sx %s Alındı", + ["received_weapon_withammo"] = "%s'den %s ile ~o~%sx %s Alındı", + ["received_weapon_hasalready"] = "%s Size Bir %s Vermeye Çalıştı, Ama Zaten Bu Silahınız Var", + ["received_weapon_noweapon"] = "%s Size Bir %s İçin Mermi Vermeye Çalıştı, Ama Bu Silaha Sahip Değilsiniz", + ["gave_account_money"] = "Verilen $%s (%s) %s'ye", + ["received_account_money"] = "Alınan $%s (%s) %s'den", + ["amount_invalid"] = "Geçersiz Miktar", + ["players_nearby"] = "Yakınlarda Hiçbir Oyuncu Yok", + ["ex_inv_lim"] = "İşlem Yapılamaz, %s Ağırlık Sınırı Aşıldı", + ["imp_invalid_quantity"] = "İşlem Yapılamaz, Miktar Geçersiz", + ["imp_invalid_amount"] = "İşlem Yapılamaz, Miktar Geçersiz", + ["threw_standard"] = "Atılan %sx %s", + ["threw_account"] = "Atılan $%s %s", + ["threw_weapon"] = "Atılan %s", + ["threw_weapon_ammo"] = "Atılan %s ile ~o~%sx %s", + ["threw_weapon_already"] = "Bu Silaha Zaten Sahipsiniz", + ["threw_cannot_pickup"] = "Envanter Dolu, Alınamaz!", + ["threw_pickup_prompt"] = "Almak İçin E'ye Basın", + + -- Key mapping + ["keymap_showinventory"] = "Envanteri Göster", + + -- Salary related + ["received_salary"] = "Maaşınız Ödendi: $%s", + ["received_help"] = "Yardım Çekiniz Ödendi: $%s", + ["company_nomoney"] = "Çalıştığınız Şirket Maaşınızı Ödeyebilecek Kadar Zengin Değil", + ["received_paycheck"] = "Maaş Alındı", + ["bank"] = "Maze Bank", + ["account_bank"] = "Banka", + ["account_black_money"] = "Kirli Para", + ["account_money"] = "Nakit", + + ["act_imp"] = "İşlem Yapılamaz", + ["in_vehicle"] = "İşlem Yapılamaz, Oyuncu Araçta", + ["not_in_vehicle"] = "İşlem Yapılamaz, Oyuncu Araçta Değil", + + -- Commands + ["command_bring"] = "Oyuncuyu Yanınıza Getir", + ["command_car"] = "Araç Spawn Et", + ["command_car_car"] = "Araç Modeli veya Hash", + ["command_cardel"] = "Yakınlardaki Araçları Kaldır", + ["command_cardel_radius"] = "Belirtilen Yarıçap İçindeki Tüm Araçları Kaldırır", + ["command_repair"] = "Araçınızı Onarın", + ["command_repair_success"] = "Araç Başarıyla Onarıldı", + ["command_repair_success_target"] = "Bir Yönetici Araçınızı Onardı", + ["command_clear"] = "Sohbeti Temizle", + ["command_clearall"] = "Tüm Oyuncular İçin Sohbeti Temizle", + ["command_clearinventory"] = "Oyuncunun Envanterindeki Tüm Eşyaları Kaldır", + ["command_clearloadout"] = "Oyuncunun Yükündeki Tüm Silahları Kaldır", + ["command_freeze"] = "Bir Oyuncuyu Dondur", + ["command_unfreeze"] = "Bir Oyuncunun Dondurmasını Kaldır", + ["command_giveaccountmoney"] = "Bir Hesaba Para Ver", + ["command_giveaccountmoney_account"] = "Ekleme Yapılacak Hesap", + ["command_giveaccountmoney_amount"] = "Eklemek İçin Miktar", + ["command_giveaccountmoney_invalid"] = "Hesap Adı Geçersiz", + ["command_removeaccountmoney"] = "Bir Hesaptan Para Çek", + ["command_removeaccountmoney_account"] = "Çekilecek Hesap", + ["command_removeaccountmoney_amount"] = "Çekilecek Miktar", + ["command_removeaccountmoney_invalid"] = "Hesap Adı Geçersiz", + ["command_giveitem"] = "Oyuncuya Eşya Ver", + ["command_giveitem_item"] = "Eşya Adı", + ["command_giveitem_count"] = "Miktar", + ["command_giveweapon"] = "Oyuncuya Silah Ver", + ["command_giveweapon_weapon"] = "Silah Adı", + ["command_giveweapon_ammo"] = "Mermi Miktarı", + ["command_giveweapon_hasalready"] = "Oyuncu Zaten Bu Silaha Sahip", + ["command_giveweaponcomponent"] = "Oyuncuya Silah Parçası Ver", + ["command_giveweaponcomponent_component"] = "Parça Adı", + ["command_giveweaponcomponent_invalid"] = "Geçersiz Silah Parçası", + ["command_giveweaponcomponent_hasalready"] = "Oyuncu Zaten Bu Silah Parçasına Sahip", + ["command_giveweaponcomponent_missingweapon"] = "Oyuncu Bu Silaha Sahip Değil", + ["command_goto"] = "Kendinizi Bir Oyuncuya Teleport Et", + ["command_kill"] = "Bir Oyuncuyu Öldür", + ["command_save"] = "Bir Oyuncunun Verilerini Zorla Kaydet", + ["command_saveall"] = "Tüm Oyuncu Verilerini Zorla Kaydet", + ["command_setaccountmoney"] = "Bir Hesaptaki Parayı Ayarla", + ["command_setaccountmoney_amount"] = "Miktar", + ["command_setcoords"] = "Belirtilen Koordinatlara Teleport Ol", + ["command_setcoords_x"] = "X Değeri", + ["command_setcoords_y"] = "Y Değeri", + ["command_setcoords_z"] = "Z Değeri", + ["command_setjob"] = "Bir Oyuncunun Mesleğini Ayarla", + ["command_setjob_job"] = "Adı", + ["command_setjob_grade"] = "Meslek Derecesi", + ["command_setjob_invalid"] = "Meslek, Derece veya Her Ikisi Geçersiz", + ["command_setgroup"] = "Bir Oyuncunun Yetki Grubunu Ayarla", + ["command_setgroup_group"] = "Grup Adı", + ["commanderror_argumentmismatch"] = "Geçersiz Argüman Sayısı (Verilen %s, İstenen %s)", + ["commanderror_argumentmismatch_number"] = "Geçersiz Argüman #%s Veri Tipi (Verilen Metin, İstenen Sayı)", + ["commanderror_argumentmismatch_string"] = "Geçersiz Argüman #%s Veri Tipi (Verilen Sayı, İstenen Metin)", + ["commanderror_invaliditem"] = "Geçersiz Eşya", + ["commanderror_invalidweapon"] = "Geçersiz Silah", + ["commanderror_console"] = "Komut Konsoldan Çalıştırılamaz", + ["commanderror_invalidcommand"] = "Geçersiz Komut - /%s", + ["commanderror_invalidplayerid"] = "Belirtilen Oyuncu Çevrimdışı", + ["commandgeneric_playerid"] = "Oyuncunun Sunucu ID'si", + ["command_giveammo_noweapon_found"] = "%s O Silaha Sahip Değil", + ["command_giveammo_weapon"] = "Silah Adı", + ["command_giveammo_ammo"] = "Mermi Miktarı", + ["tpm_nowaypoint"] = "Hiçbir Yol İşareti Ayarlanmadı.", + ["tpm_success"] = "Başarıyla Teleport Edildi", + + ["noclip_message"] = "Noclip %s Yapıldı", + ["enabled"] = "~g~Aktif Edildi~s~", + ["disabled"] = "~r~Pasif Edildi~s~", + + -- Locale settings + ["locale_digit_grouping_symbol"] = ",", + ["locale_currency"] = "£%s", + + -- Silahlar + + -- Melee + ["weapon_dagger"] = "Kılıç", + ["weapon_bat"] = "Sopa", + ["weapon_battleaxe"] = "Savaş Balta", + ["weapon_bottle"] = "Şişe", + ["weapon_crowbar"] = "Kaldıraç", + ["weapon_flashlight"] = "Fener", + ["weapon_golfclub"] = "Golf Sopası", + ["weapon_hammer"] = "Çekiç", + ["weapon_hatchet"] = "Balta", + ["weapon_knife"] = "Bıçak", + ["weapon_knuckle"] = "Düğmeli Eldiven", + ["weapon_machete"] = "Machete", + ["weapon_nightstick"] = "Gece Dürbünü", + ["weapon_wrench"] = "Anahtar", + ["weapon_poolcue"] = "Havuz Sopası", + ["weapon_stone_hatchet"] = "Taş Balta", + ["weapon_switchblade"] = "Dönme Bıçağı", + + -- Tabancalar + ["weapon_appistol"] = "AP Tabancası", + ["weapon_ceramicpistol"] = "Seramik Tabanca", + ["weapon_combatpistol"] = "Savaş Tabancası", + ["weapon_doubleaction"] = "Çift Aksiyonlu Tabanca", + ["weapon_navyrevolver"] = "Donanma Revolveri", + ["weapon_flaregun"] = "Işık Fişeği Tabancası", + ["weapon_gadgetpistol"] = "Cihaz Tabancası", + ["weapon_heavypistol"] = "Ağır Tabanca", + ["weapon_revolver"] = "Revolver", + ["weapon_revolver_mk2"] = "Revolver MK2", + ["weapon_marksmanpistol"] = "Nişancı Tabancası", + ["weapon_pistol"] = "Tabanca", + ["weapon_pistol_mk2"] = "Tabanca MK2", + ["weapon_pistol50"] = "Tabanca .50", + ["weapon_snspistol"] = "SNS Tabancası", + ["weapon_snspistol_mk2"] = "SNS Tabancası MK2", + ["weapon_stungun"] = "Elektrik Tabancası", + ["weapon_raypistol"] = "Atomizer Tabancası", + ["weapon_vintagepistol"] = "Vintage Tabanca", + + -- Av Tüfekleri + ["weapon_assaultshotgun"] = "Saldırı Tüfeği", + ["weapon_autoshotgun"] = "Otomatik Tüfek", + ["weapon_bullpupshotgun"] = "Bullpup Tüfeği", + ["weapon_combatshotgun"] = "Savaş Tüfeği", + ["weapon_dbshotgun"] = "Çift Namlu Tüfeği", + ["weapon_heavyshotgun"] = "Ağır Tüfek", + ["weapon_musket"] = "Tüfek", + ["weapon_pumpshotgun"] = "Pompalı Tüfek", + ["weapon_pumpshotgun_mk2"] = "Pompalı Tüfek MK2", + ["weapon_sawnoffshotgun"] = "Kısa Namlu Tüfek", + + -- SMG ve LMG + ["weapon_assaultsmg"] = "Saldırı SMG", + ["weapon_combatmg"] = "Savaş MG", + ["weapon_combatmg_mk2"] = "Savaş MG MK2", + ["weapon_combatpdw"] = "Savaş PDW", + ["weapon_gusenberg"] = "Gusenberg Sweeper", + ["weapon_machinepistol"] = "Makine Tabancası", + ["weapon_mg"] = "MG", + ["weapon_microsmg"] = "Micro SMG", + ["weapon_minismg"] = "Mini SMG", + ["weapon_smg"] = "SMG", + ["weapon_smg_mk2"] = "SMG MK2", + ["weapon_raycarbine"] = "Unholy Hellbringer", + + -- Tüfekler + ["weapon_advancedrifle"] = "İleri Düzey Tüfeği", + ["weapon_assaultrifle"] = "Saldırı Tüfeği", + ["weapon_assaultrifle_mk2"] = "Saldırı Tüfeği MK2", + ["weapon_bullpuprifle"] = "Bullpup Tüfeği", + ["weapon_bullpuprifle_mk2"] = "Bullpup Tüfeği MK2", + ["weapon_carbinerifle"] = "Carbine Tüfeği", + ["weapon_carbinerifle_mk2"] = "Carbine Tüfeği MK2", + ["weapon_compactrifle"] = "Komple Tüfek", + ["weapon_militaryrifle"] = "Askeri Tüfek", + ["weapon_specialcarbine"] = "Özel Carbine", + ["weapon_specialcarbine_mk2"] = "Özel Carbine MK2", + ["weapon_heavyrifle"] = "Ağır Tüfek", + + -- Keskin Nişancı + ["weapon_heavysniper"] = "Ağır Keskin Nişancı", + ["weapon_heavysniper_mk2"] = "Ağır Keskin Nişancı MK2", + ["weapon_marksmanrifle"] = "Keskin Nişancı Tüfeği", + ["weapon_marksmanrifle_mk2"] = "Keskin Nişancı Tüfeği MK2", + ["weapon_sniperrifle"] = "Keskin Nişancı Tüfeği", + + -- Ağır / Roket Atıcılar + ["weapon_compactlauncher"] = "Kompakt Roket Atıcı", + ["weapon_firework"] = "Havai Fişek Atıcı", + ["weapon_grenadelauncher"] = "El Bombası Atıcı", + ["weapon_hominglauncher"] = "Hedefli Roket Atıcı", + ["weapon_minigun"] = "Minigun", + ["weapon_railgun"] = "Raylı Silah", + ["weapon_rpg"] = "Roket Atıcı", + ["weapon_rayminigun"] = "Widowmaker", + + -- Suçlu Girişimleri DLC + ["weapon_metaldetector"] = "Metal Dedektörü", + ["weapon_precisionrifle"] = "Keskin Nişancı Tüfeği", + ["weapon_tactilerifle"] = "Hizmet Karabina", + + -- Uyuşturucu Savaşları DLC + ["weapon_candycane"] = "Şeker Kamışı", + ["weapon_acidpackage"] = "Asit Paketi", + ["weapon_pistolxm3"] = "Pistol8 x3m", + ["weapon_railgunxm3"] = "Raylı Silah", + + -- Atılan Silahlar + ["weapon_ball"] = "Beyzbol Topu", + ["weapon_bzgas"] = "BZ Gazı", + ["weapon_flare"] = "Duman Fişeği", + ["weapon_grenade"] = "El Bombası", + ["weapon_petrolcan"] = "Petrol Bidonu", + ["weapon_hazardcan"] = "Tehlikeli Bidon", + ["weapon_molotov"] = "Molotof Kokteyli", + ["weapon_proxmine"] = "Yakınlık Mayını", + ["weapon_pipebomb"] = "Boru Bombası", + ["weapon_snowball"] = "Karla Bombası", + ["weapon_stickybomb"] = "Yapışkan Bomba", + ["weapon_smokegrenade"] = "Gözyaşı Gazı", + + -- Özel + ["weapon_fireextinguisher"] = "Yangın Söndürücü", + ["weapon_digiscanner"] = "Dijital Tarayıcı", + ["weapon_garbagebag"] = "Çöp Torbası", + ["weapon_handcuffs"] = "Kelepçe", + ["gadget_nightvision"] = "Gece Görüşü", + ["gadget_parachute"] = "Paraşüt", + + -- Silah Bileşenleri + ["component_knuckle_base"] = "Temel Model", + ["component_knuckle_pimp"] = "Fahişe", + ["component_knuckle_ballas"] = "Ballas", + ["component_knuckle_dollar"] = "Hustler", + ["component_knuckle_diamond"] = "Elmas", + ["component_knuckle_hate"] = "Nefret", + ["component_knuckle_love"] = "Aşk", + ["component_knuckle_player"] = "Oyuncu", + ["component_knuckle_king"] = "Kral", + ["component_knuckle_vagos"] = "Vagos", + + ["component_luxary_finish"] = "Lüks Silah Kaplama", + + ["component_handle_default"] = "Varsayılan Sap", + ["component_handle_vip"] = "VIP Sap", + ["component_handle_bodyguard"] = "Vücut Koruma Sapı", + + ["component_vip_finish"] = "VIP Kaplama", + ["component_bodyguard_finish"] = "Vücut Koruma Kaplaması", + + ["component_camo_finish"] = "Dijital Kamuflaj", + ["component_camo_finish2"] = "Fırçalama Kamuflaj", + ["component_camo_finish3"] = "Orman Kamuflajı", + ["component_camo_finish4"] = "Kafatası Kamuflajı", + ["component_camo_finish5"] = "Sessanta Nove Kamuflajı", + ["component_camo_finish6"] = "Perseus Kamuflajı", + ["component_camo_finish7"] = "Leopar Kamuflajı", + ["component_camo_finish8"] = "Zebra Kamuflajı", + ["component_camo_finish9"] = "Geometrik Kamuflaj", + ["component_camo_finish10"] = "Boom Kamuflajı", + ["component_camo_finish11"] = "Patriot Kamuflajı", + + ["component_camo_slide_finish"] = "Dijital Kayma Kamuflajı", + ["component_camo_slide_finish2"] = "Fırçalama Kayma Kamuflajı", + ["component_camo_slide_finish3"] = "Orman Kayma Kamuflajı", + ["component_camo_slide_finish4"] = "Kafatası Kayma Kamuflajı", + ["component_camo_slide_finish5"] = "Sessanta Nove Kayma Kamuflajı", + ["component_camo_slide_finish6"] = "Perseus Kayma Kamuflajı", + ["component_camo_slide_finish7"] = "Leopar Kayma Kamuflajı", + ["component_camo_slide_finish8"] = "Zebra Kayma Kamuflajı", + ["component_camo_slide_finish9"] = "Geometrik Kayma Kamuflajı", + ["component_camo_slide_finish10"] = "Boom Kayma Kamuflajı", + ["component_camo_slide_finish11"] = "Patriot Kayma Kamuflajı", + + ["component_clip_default"] = "Varsayılan Şarjör", + ["component_clip_extended"] = "Uzun Şarjör", + ["component_clip_drum"] = "Davul Şarjör", + ["component_clip_box"] = "Kutu Şarjör", + + ["component_scope_holo"] = "Holografik Dürbün", + ["component_scope_small"] = "Küçük Dürbün", + ["component_scope_medium"] = "Orta Dürbün", + ["component_scope_large"] = "Büyük Dürbün", + ["component_scope"] = "Montelenmiş Dürbün", + ["component_scope_advanced"] = "İleri Seviye Dürbün", + ["component_ironsights"] = "Nişangah", + + ["component_suppressor"] = "Susturucu", + ["component_compensator"] = "Dengeleyici", + + ["component_muzzle_flat"] = "Düz Namlu Freni", + ["component_muzzle_tactical"] = "Taktiksel Namlu Freni", + ["component_muzzle_fat"] = "Geniş Uçlu Namlu Freni", + ["component_muzzle_precision"] = "Hassas Namlu Freni", + ["component_muzzle_heavy"] = "Ağır Namlu Freni", + ["component_muzzle_slanted"] = "Eğik Namlu Freni", + ["component_muzzle_split"] = "Bölünmüş Namlu Freni", + ["component_muzzle_squared"] = "Kare Namlu Freni", + + ["component_flashlight"] = "Fener", + ["component_grip"] = "Tutamak", + + ["component_barrel_default"] = "Varsayılan Namlu", + ["component_barrel_heavy"] = "Ağır Namlu", + + ["component_ammo_tracer"] = "Işık İzli Mühimmat", + ["component_ammo_incendiary"] = "Alev Alıcı Mühimmat", + ["component_ammo_hollowpoint"] = "Hollowpoint Mühimmat", + ["component_ammo_fmj"] = "FMJ Mühimmat", + ["component_ammo_armor"] = "Zırh Delici Mühimmat", + ["component_ammo_explosive"] = "Zırh Delici Alev Alıcı Mühimmat", + + ["component_shells_default"] = "Varsayılan Mühimmat", + ["component_shells_incendiary"] = "Dragon's Breath Mühimmatı", + ["component_shells_armor"] = "Çelik Buckshot Mühimmat", + ["component_shells_hollowpoint"] = "Flechette Mühimmat", + ["component_shells_explosive"] = "Patlayıcı Slug Mühimmat", + + -- Silah Mermileri + ["ammo_rounds"] = "Dişli(ler)", + ["ammo_shells"] = "Kovan(lar)", + ["ammo_charge"] = "Şarjör", + ["ammo_petrol"] = "Yakıt Galonları", + ["ammo_firework"] = "Havai Fişek(ler)", + ["ammo_rockets"] = "Roket(ler)", + ["ammo_grenadelauncher"] = "El Bombası(ları)", + ["ammo_grenade"] = "El Bombası(ları)", + ["ammo_stickybomb"] = "Bomba(lar)", + ["ammo_pipebomb"] = "Bomba(lar)", + ["ammo_smokebomb"] = "Bomba(lar)", + ["ammo_molotov"] = "Molotof Kokteyli(leri)", + ["ammo_proxmine"] = "Mayın(lar)", + ["ammo_bzgas"] = "Kutu(lar)", + ["ammo_ball"] = "Top(lar)", + ["ammo_snowball"] = "Kar Topu(ları)", + ["ammo_flare"] = "Duman Fişek(leri)", + ["ammo_flaregun"] = "Duman Fişek(leri)", + + -- Silah Renkleri + ["tint_default"] = "Varsayılan Kaplama", + ["tint_green"] = "Yeşil Kaplama", + ["tint_gold"] = "Altın Kaplama", + ["tint_pink"] = "Pembe Kaplama", + ["tint_army"] = "Ordu Kaplaması", + ["tint_lspd"] = "Mavi Kaplama", + ["tint_orange"] = "Turuncu Kaplama", + ["tint_platinum"] = "Platin Kaplama", +} diff --git a/[core]/es_extended/locales/zh-cn.lua b/[core]/es_extended/locales/zh-cn.lua index a8a1ad8e6..5971cc35b 100644 --- a/[core]/es_extended/locales/zh-cn.lua +++ b/[core]/es_extended/locales/zh-cn.lua @@ -374,4 +374,37 @@ Locales["zh-cn"] = { ["tint_lspd"] = "洛圣都警局色调", ["tint_orange"] = "橙色调", ["tint_platinum"] = "铂金色调", + -- MK2 Weapon Tints + ["tint_classic_black"] = "经典黑色", + ["tint_classic_gray"] = "经典灰色", + ["tint_classic_two_tone"] = "经典双色", + ["tint_classic_white"] = "经典白色", + ["tint_classic_beige"] = "经典米色", + ["tint_classic_green"] = "经典绿色", + ["tint_classic_blue"] = "经典蓝色", + ["tint_classic_earth"] = "经典大地色", + ["tint_classic_brown_black"] = "经典棕黑色", + ["tint_contrast_red"] = "对比红色", + ["tint_contrast_blue"] = "对比蓝色", + ["tint_contrast_yellow"] = "对比黄色", + ["tint_contrast_orange"] = "对比橙色", + ["tint_bold_pink"] = "大胆粉色", + ["tint_bold_purple_yellow"] = "大胆紫黄色", + ["tint_bold_orange"] = "大胆橙色", + ["tint_bold_green_purple"] = "大胆绿色紫色", + ["tint_bold_red_feat"] = "大胆红色feat", + ["tint_bold_green_feat"] = "大胆绿色feat", + ["tint_bold_cyan_feat"] = "大胆青色feat", + ["tint_bold_yellow_feat"] = "大胆黄色feat", + ["tint_bold_red_white"] = "大胆红白色", + ["tint_bold_blue_white"] = "大胆蓝白色", + ["tint_metallic_gold"] = "金属金色", + ["tint_metallic_platinum"] = "金属铂金", + ["tint_metallic_gray_lilac"] = "金属灰紫色", + ["tint_metallic_purple_lime"] = "金属紫色青柠", + ["tint_metallic_red"] = "金属红色", + ["tint_metallic_green"] = "金属绿色", + ["tint_metallic_blue"] = "金属蓝色", + ["tint_metallic_white_aqua"] = "金属白色水蓝", + ["tint_metallic_red_yellow"] = "金属红黄色", } diff --git a/[core]/es_extended/server/classes/player.lua b/[core]/es_extended/server/classes/player.lua index 1011c0d35..b5e66e7b8 100644 --- a/[core]/es_extended/server/classes/player.lua +++ b/[core]/es_extended/server/classes/player.lua @@ -130,6 +130,7 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, ---@return number function self.getPlayTime() + -- luacheck: ignore return self.lastPlaytime + GetPlayerTimeOnline(self.source) end @@ -607,8 +608,17 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, function self.updateWeaponAmmo(weaponName, ammoCount) local _, weapon = self.getWeapon(weaponName) - if weapon then - weapon.ammo = ammoCount + if not weapon then + return + end + + weapon.ammo = ammoCount + + if weapon.ammo <= 0 then + local _, weaponConfig = ESX.GetWeapon(weaponName) + if weaponConfig.throwable then + self.removeWeapon(weaponName) + end end end diff --git a/[core]/es_extended/server/functions.lua b/[core]/es_extended/server/functions.lua index 606ab0e74..884ef4a57 100644 --- a/[core]/es_extended/server/functions.lua +++ b/[core]/es_extended/server/functions.lua @@ -276,15 +276,15 @@ end ESX.GetPlayers = GetPlayers -local function checkTable(key, val, player, xPlayers) +local function checkTable(key, val, xPlayer, xPlayers) for valIndex = 1, #val do local value = val[valIndex] if not xPlayers[value] then xPlayers[value] = {} end - if (key == "job" and player.job.name == value) or player[key] == value then - xPlayers[value][#xPlayers[value] + 1] = player + if (key == "job" and xPlayer.job.name == value) or xPlayer[key] == value then + xPlayers[value][#xPlayers[value] + 1] = xPlayer end end end @@ -293,20 +293,22 @@ end ---@param val? string|table ---@return table function ESX.GetExtendedPlayers(key, val) + if not key then + return ESX.Table.ToArray(ESX.Players) + end + local xPlayers = {} if type(val) == "table" then - for _, v in pairs(ESX.Players) do - checkTable(key, val, v, xPlayers) + for _, xPlayer in pairs(ESX.Players) do + checkTable(key, val, xPlayer, xPlayers) end - else - for _, v in pairs(ESX.Players) do - if key then - if (key == "job" and v.job.name == val) or v[key] == val then - xPlayers[#xPlayers + 1] = v - end - else - xPlayers[#xPlayers + 1] = v - end + + return xPlayers + end + + for _, xPlayer in pairs(ESX.Players) do + if (key == "job" and xPlayer.job.name == val) or xPlayer[key] == val then + xPlayers[#xPlayers + 1] = xPlayer end end diff --git a/[core]/es_extended/server/main.lua b/[core]/es_extended/server/main.lua index 1b9c75221..61fbe78ed 100644 --- a/[core]/es_extended/server/main.lua +++ b/[core]/es_extended/server/main.lua @@ -102,7 +102,7 @@ if not Config.Multichar then Wait(0) -- Required local identifier = ESX.GetIdentifier(playerId) - + -- luacheck: ignore if not SetEntityOrphanMode then return deferrals.done(("[ESX] ESX Requires a minimum Artifact version of 10188, Please update your server.")) end @@ -462,6 +462,7 @@ if not Config.CustomInventory then if not targetXPlayer.hasWeapon(itemName) then sourceXPlayer.showNotification(TranslateCap("gave_weapon_noweapon", targetXPlayer.name)) targetXPlayer.showNotification(TranslateCap("received_weapon_noweapon", sourceXPlayer.name, weapon.label)) + return end local _, weaponObject = ESX.GetWeapon(itemName) @@ -502,7 +503,8 @@ if not Config.CustomInventory then if itemCount == nil or itemCount < 1 then return xPlayer.showNotification(TranslateCap("imp_invalid_amount")) end - local account = xPlayer.getAccount(itemName) + + local account = xPlayer.getAccount(itemName) if itemCount > account.money or account.money < 1 then return xPlayer.showNotification(TranslateCap("imp_invalid_amount")) @@ -694,7 +696,7 @@ AddEventHandler("onResourceStart", function(key) StopResource(key) error(("WE STOPPED A RESOURCE THAT WILL BREAK ^1ESX^1, PLEASE REMOVE ^5%s^1"):format(key)) end - + -- luacheck: ignore if not SetEntityOrphanMode then CreateThread(function() while true do diff --git a/[core]/es_extended/server/modules/actions.lua b/[core]/es_extended/server/modules/actions.lua deleted file mode 100644 index 52eeeb5b1..000000000 --- a/[core]/es_extended/server/modules/actions.lua +++ /dev/null @@ -1,28 +0,0 @@ -RegisterServerEvent("esx:playerPedChanged") -RegisterServerEvent("esx:playerJumping") -RegisterServerEvent("esx:enteringVehicle") -RegisterServerEvent("esx:enteringVehicleAborted") -RegisterServerEvent("esx:enteredVehicle") -RegisterServerEvent("esx:exitedVehicle") - -if Config.EnableDebug then - AddEventHandler("esx:playerPedChanged", function(netId) - print("esx:playerPedChanged", source, netId) - end) - - AddEventHandler("esx:enteringVehicle", function(plate, seat, netId) - print("esx:enteringVehicle", "source", source, "plate", plate, "seat", seat, "netId", netId) - end) - - AddEventHandler("esx:enteringVehicleAborted", function() - print("esx:enteringVehicleAborted", source) - end) - - AddEventHandler("esx:enteredVehicle", function(plate, seat, displayName, netId) - print("esx:enteredVehicle", "source", source, "plate", plate, "seat", seat, "displayName", displayName, "netId", netId) - end) - - AddEventHandler("esx:exitedVehicle", function(plate, seat, displayName, netId) - print("esx:exitedVehicle", "source", source, "plate", plate, "seat", seat, "displayName", displayName, "netId", netId) - end) -end diff --git a/[core]/es_extended/server/modules/callback.lua b/[core]/es_extended/server/modules/callback.lua index 245b0987e..3301e6a6f 100644 --- a/[core]/es_extended/server/modules/callback.lua +++ b/[core]/es_extended/server/modules/callback.lua @@ -1,13 +1,24 @@ ---@diagnostic disable: duplicate-set-field +-- ============================================= +-- MARK: Variables +-- ============================================= + Callbacks = {} Callbacks.requests = {} Callbacks.storage = {} Callbacks.id = 0 -function Callbacks:Register(name, cb) - self.storage[name] = cb +-- ============================================= +-- MARK: Internal Functions +-- ============================================= + +function Callbacks:Register(name, resource, cb) + self.storage[name] = { + resource = resource, + cb = cb + } end function Callbacks:Execute(cb, ...) @@ -39,7 +50,7 @@ function Callbacks:ServerRecieve(player, event, requestId, invoker, ...) local returnCb = function(...) TriggerClientEvent("esx:serverCallback", player, requestId, invoker, ...) end - local callback = self.storage[event] + local callback = self.storage[event].cb self:Execute(callback, player, returnCb, ...) end @@ -57,15 +68,9 @@ function Callbacks:RecieveClient(requestId, invoker, ...) self.requests[requestId] = nil end -RegisterNetEvent("esx:clientCallback", function(requestId, invoker, ...) - Callbacks:RecieveClient(requestId, invoker, ...) -end) - -RegisterNetEvent("esx:triggerServerCallback", function(eventName, requestId, invoker, ...) - local source = source - Callbacks:ServerRecieve(source, eventName, requestId, invoker, ...) -end) - +-- ============================================= +-- MARK: ESX Functions +-- ============================================= ---@param player number playerId ---@param eventName string @@ -73,14 +78,44 @@ end) ---@param ... any function ESX.TriggerClientCallback(player, eventName, callback, ...) local invokingResource = GetInvokingResource() - local invoker = (invokingResource and invokingResource ~= "unknown") and invokingResource or "es_extended" + local invoker = (invokingResource and invokingResource ~= "Unknown") and invokingResource or "es_extended" Callbacks:Trigger(player, eventName, callback, invoker, ...) end ---@param eventName string ---@param callback function -ESX.RegisterServerCallback = function(eventName, callback) - Callbacks:Register(eventName, callback) +---@return nil +function ESX.RegisterServerCallback(eventName, callback) + local invokingResource = GetInvokingResource() + local invoker = (invokingResource and invokingResource ~= "Unknown") and invokingResource or "es_extended" + + Callbacks:Register(eventName, invoker, callback) +end + +---@param eventName string +---@return boolean +function ESX.DoesServerCallbackExist(eventName) + return Callbacks.storage[eventName] ~= nil end +-- ============================================= +-- MARK: Events +-- ============================================= + +RegisterNetEvent("esx:clientCallback", function(requestId, invoker, ...) + Callbacks:RecieveClient(requestId, invoker, ...) +end) + +RegisterNetEvent("esx:triggerServerCallback", function(eventName, requestId, invoker, ...) + local source = source + Callbacks:ServerRecieve(source, eventName, requestId, invoker, ...) +end) + +AddEventHandler("onResourceStop", function(resource) + for k, v in pairs(Callbacks.storage) do + if v.resource == resource then + Callbacks.storage[k] = nil + end + end +end) diff --git a/[core]/es_extended/server/modules/commands.lua b/[core]/es_extended/server/modules/commands.lua index dfb4baa5d..628e85ea8 100644 --- a/[core]/es_extended/server/modules/commands.lua +++ b/[core]/es_extended/server/modules/commands.lua @@ -95,10 +95,17 @@ ESX.RegisterCommand( }) end + local xRoutingBucket = GetPlayerRoutingBucket(xPlayer.source) + ESX.OneSync.SpawnVehicle(args.car, playerCoords, playerHeading, upgrades, function(networkId) if networkId then local vehicle = NetworkGetEntityFromNetworkId(networkId) - for _ = 1, 20 do + + if xRoutingBucket ~= 0 then + SetEntityRoutingBucket(vehicle, xRoutingBucket) + end + + for _ = 1, 100 do Wait(0) SetPedIntoVehicle(playerPed, vehicle, -1) @@ -106,6 +113,7 @@ ESX.RegisterCommand( break end end + if GetVehiclePedIsIn(playerPed, false) ~= vehicle then showError("[^1ERROR^7] The player could not be seated in the vehicle") end @@ -585,6 +593,12 @@ ESX.RegisterCommand( "admin", function(xPlayer, args) local targetCoords = args.playerId.getCoords() + local srcDim = GetPlayerRoutingBucket(xPlayer.source) + local targetDim = GetPlayerRoutingBucket(args.playerId.source) + + if srcDim ~= targetDim then + SetPlayerRoutingBucket(xPlayer.source, targetDim) + end xPlayer.setCoords(targetCoords) if Config.AdminLogging then ESX.DiscordLogFields("UserActions", "Admin Teleport /goto Triggered!", "pink", { @@ -611,6 +625,12 @@ ESX.RegisterCommand( function(xPlayer, args) local targetCoords = args.playerId.getCoords() local playerCoords = xPlayer.getCoords() + local targetDim = GetPlayerRoutingBucket(args.playerId.source) + local srcDim = GetPlayerRoutingBucket(xPlayer.source) + + if targetDim ~= srcDim then + SetPlayerRoutingBucket(args.playerId.source, srcDim) + end args.playerId.setCoords(playerCoords) if Config.AdminLogging then ESX.DiscordLogFields("UserActions", "Admin Teleport /bring Triggered!", "pink", { @@ -718,3 +738,28 @@ ESX.RegisterCommand("players", "admin", function() print(("^1[^2ID: ^5%s^0 | ^2Name : ^5%s^0 | ^2Group : ^5%s^0 | ^2Identifier : ^5%s^1]^0\n"):format(xPlayer.source, xPlayer.getName(), xPlayer.getGroup(), xPlayer.identifier)) end end, true) + +ESX.RegisterCommand( + {"setdim", "setbucket"}, + "admin", + function(xPlayer, args) + SetPlayerRoutingBucket(args.playerId.source, args.dimension) + if Config.AdminLogging then + ESX.DiscordLogFields("UserActions", "Admin Set Dim /setdim Triggered!", "pink", { + { name = "Player", value = xPlayer and xPlayer.name or "Server Console", inline = true }, + { name = "ID", value = xPlayer and xPlayer.source or "Unknown ID", inline = true }, + { name = "Target", value = args.playerId.name, inline = true }, + { name = "Dimension", value = args.dimension, inline = true }, + }) + end + end, + true, + { + help = TranslateCap("command_setdim"), + validate = true, + arguments = { + { name = "playerId", help = TranslateCap("commandgeneric_playerid"), type = "player" }, + { name = "dimension", help = TranslateCap("commandgeneric_dimension"), type = "number" }, + }, + } +) diff --git a/[core]/es_extended/server/modules/onesync.lua b/[core]/es_extended/server/modules/onesync.lua index cb9bfdfa2..de4f4eb8d 100644 --- a/[core]/es_extended/server/modules/onesync.lua +++ b/[core]/es_extended/server/modules/onesync.lua @@ -82,35 +82,58 @@ end ---@param coords vector3|table ---@param heading number ---@param properties table ----@param cb function +---@param cb? fun(netId: number) +---@return number? netId function ESX.OneSync.SpawnVehicle(model, coords, heading, properties, cb) + if cb and not ESX.IsFunctionReference(cb) then + error("Invalid callback function") + end + + local vehicleModel = joaat(model) local vehicleProperties = properties + local promise = not cb and promise.new() CreateThread(function() local xPlayer = ESX.OneSync.GetClosestPlayer(coords, 300) ESX.GetVehicleType(vehicleModel, xPlayer.id, function(vehicleType) - if vehicleType then - local createdVehicle = CreateVehicleServerSetter(vehicleModel, vehicleType, coords.x, coords.y, coords.z, heading) - local tries = 0 - - while not createdVehicle or createdVehicle == 0 or not GetEntityCoords(createdVehicle) do - Wait(200) - tries = tries + 1 - if tries > 20 then - return error(("Could not spawn vehicle - ^5%s^7!"):format(model)) + if not vehicleType then + if (promise) then + return promise:reject(("Tried to spawn invalid vehicle - ^5%s^7!"):format(model)) + end + error(("Tried to spawn invalid vehicle - ^5%s^7!"):format(model)) + end + + local createdVehicle = CreateVehicleServerSetter(vehicleModel, vehicleType, coords.x, coords.y, coords.z, heading) + local tries = 0 + + while not createdVehicle or createdVehicle == 0 or NetworkGetEntityOwner(createdVehicle) == -1 do + Wait(200) + tries = tries + 1 + if tries > 40 then + if promise then + return promise:reject(("Could not spawn vehicle - ^5%s^7!"):format(model)) end + error(("Could not spawn vehicle - ^5%s^7!"):format(model)) end + end - SetEntityOrphanMode(createdVehicle, 2) - local networkId = NetworkGetNetworkIdFromEntity(createdVehicle) - Entity(createdVehicle).state:set("VehicleProperties", vehicleProperties, true) + -- luacheck: ignore + SetEntityOrphanMode(createdVehicle, 2) + local networkId = NetworkGetNetworkIdFromEntity(createdVehicle) + Entity(createdVehicle).state:set("VehicleProperties", vehicleProperties, true) + + if promise then + promise:resolve(networkId) + elseif cb then cb(networkId) - else - error(("Tried to spawn invalid vehicle - ^5%s^7!"):format(model)) end end) end) + + if promise then + return Citizen.Await(promise) + end end ---@param model number|string diff --git a/[core]/es_extended/shared/config/main.lua b/[core]/es_extended/shared/config/main.lua index 7db1e472b..f769f758e 100644 --- a/[core]/es_extended/shared/config/main.lua +++ b/[core]/es_extended/shared/config/main.lua @@ -1,6 +1,6 @@ Config = {} --- for ox inventory, use Config.CustomInventory = "ox", for others, set to "resource_name" +-- for ox inventory, this will automatically be adjusted, do not change! for other inventories, change to "resource_name" Config.CustomInventory = false Config.Accounts = { @@ -51,9 +51,13 @@ Config.DistanceGive = 4.0 -- Max distance when giving items, weapons etc. Config.AdminLogging = false -- Logs the usage of certain commands by those with group.admin ace permissions (default is false) --------------------------------------------------------------------- --- DO NOT CHANGE BELOW THIS LINE UNLESS YOU KNOW WHAT YOU ARE DOING --------------------------------------------------------------------- +------------------------------------- +-- DO NOT CHANGE BELOW THIS LINE !!! +------------------------------------- +if GetResourceState("ox_inventory") ~= "missing" then + Config.CustomInventory = "ox" +end + Config.EnableDefaultInventory = Config.CustomInventory == false -- Display the default Inventory ( F2 ) local txAdminLocale = GetConvar("txAdmin-locale", "en") diff --git a/[core]/es_extended/shared/config/weapons.lua b/[core]/es_extended/shared/config/weapons.lua index cbeecb54d..e9392f305 100644 --- a/[core]/es_extended/shared/config/weapons.lua +++ b/[core]/es_extended/shared/config/weapons.lua @@ -8,6 +8,41 @@ Config.DefaultWeaponTints = { [6] = TranslateCap("tint_orange"), [7] = TranslateCap("tint_platinum"), } +Config.MK2WeaponTints = { + [0] = TranslateCap('tint_classic_black'), + [1] = TranslateCap('tint_classic_gray'), + [2] = TranslateCap('tint_classic_two_tone'), + [3] = TranslateCap('tint_classic_white'), + [4] = TranslateCap('tint_classic_beige'), + [5] = TranslateCap('tint_classic_green'), + [6] = TranslateCap('tint_classic_blue'), + [7] = TranslateCap('tint_classic_earth'), + [8] = TranslateCap('tint_classic_brown_black'), + [9] = TranslateCap('tint_contrast_red'), + [10] = TranslateCap('tint_contrast_blue'), + [11] = TranslateCap('tint_contrast_yellow'), + [12] = TranslateCap('tint_contrast_orange'), + [13] = TranslateCap('tint_bold_pink'), + [14] = TranslateCap('tint_bold_purple_yellow'), + [15] = TranslateCap('tint_bold_orange'), + [16] = TranslateCap('tint_bold_green_purple'), + [17] = TranslateCap('tint_bold_red_feat'), + [18] = TranslateCap('tint_bold_green_feat'), + [19] = TranslateCap('tint_bold_cyan_feat'), + [20] = TranslateCap('tint_bold_yellow_feat'), + [21] = TranslateCap('tint_bold_red_white'), + [22] = TranslateCap('tint_bold_blue_white'), + [23] = TranslateCap('tint_metallic_gold'), + [24] = TranslateCap('tint_metallic_platinum'), + [25] = TranslateCap('tint_metallic_gray_lilac'), + [26] = TranslateCap('tint_metallic_purple_lime'), + [27] = TranslateCap('tint_metallic_red'), + [28] = TranslateCap('tint_metallic_green'), + [29] = TranslateCap('tint_metallic_blue'), + [30] = TranslateCap('tint_metallic_white_aqua'), + [31] = TranslateCap('tint_metallic_orange_yellow'), + [32] = TranslateCap('tint_metallic_red_yellow') +} Config.Weapons = { -- Melee @@ -111,7 +146,7 @@ Config.Weapons = { name = "WEAPON_REVOLVER_MK2", label = TranslateCap("weapon_revolver_mk2"), ammo = { label = TranslateCap("ammo_rounds"), hash = `AMMO_PISTOL` }, - tints = Config.DefaultWeaponTints, + tints = Config.MK2WeaponTints, components = { { name = "clip_default", label = TranslateCap("component_clip_default"), hash = `COMPONENT_REVOLVER_MK2_CLIP_01` }, { name = "ammo_tracer", label = TranslateCap("component_ammo_tracer"), hash = `COMPONENT_REVOLVER_MK2_CLIP_TRACER` }, @@ -153,7 +188,7 @@ Config.Weapons = { name = "WEAPON_PISTOL_MK2", label = TranslateCap("weapon_pistol_mk2"), ammo = { label = TranslateCap("ammo_rounds"), hash = `AMMO_PISTOL` }, - tints = Config.DefaultWeaponTints, + tints = Config.MK2WeaponTints, components = { { name = "clip_default", label = TranslateCap("component_clip_default"), hash = `COMPONENT_PISTOL_MK2_CLIP_01` }, { name = "clip_extended", label = TranslateCap("component_clip_extended"), hash = `COMPONENT_PISTOL_MK2_CLIP_02` }, @@ -217,7 +252,7 @@ Config.Weapons = { name = "WEAPON_SNSPISTOL_MK2", label = TranslateCap("weapon_snspistol_mk2"), ammo = { label = TranslateCap("ammo_rounds"), hash = `AMMO_PISTOL` }, - tints = Config.DefaultWeaponTints, + tints = Config.MK2WeaponTints, components = { { name = "clip_default", label = TranslateCap("component_clip_default"), hash = `COMPONENT_SNSPISTOL_MK2_CLIP_01` }, { name = "clip_extended", label = TranslateCap("component_clip_extended"), hash = `COMPONENT_SNSPISTOL_MK2_CLIP_02` }, @@ -333,7 +368,7 @@ Config.Weapons = { name = "WEAPON_PUMPSHOTGUN_MK2", label = TranslateCap("weapon_pumpshotgun_mk2"), ammo = { label = TranslateCap("ammo_shells"), hash = `AMMO_SHOTGUN` }, - tints = Config.DefaultWeaponTints, + tints = Config.MK2WeaponTints, components = { { name = "shells_default", label = TranslateCap("component_shells_default"), hash = `COMPONENT_PUMPSHOTGUN_MK2_CLIP_01` }, { name = "shells_incendiary", label = TranslateCap("component_shells_incendiary"), hash = `COMPONENT_PUMPSHOTGUN_MK2_CLIP_INCENDIARY` }, @@ -400,7 +435,7 @@ Config.Weapons = { name = "WEAPON_COMBATMG_MK2", label = TranslateCap("weapon_combatmg_mk2"), ammo = { label = TranslateCap("ammo_rounds"), hash = `AMMO_MG` }, - tints = Config.DefaultWeaponTints, + tints = Config.MK2WeaponTints, components = { { name = "clip_default", label = TranslateCap("component_clip_default"), hash = `COMPONENT_COMBATMG_MK2_CLIP_01` }, { name = "clip_extended", label = TranslateCap("component_clip_extended"), hash = `COMPONENT_COMBATMG_MK2_CLIP_02` }, @@ -525,7 +560,7 @@ Config.Weapons = { name = "WEAPON_SMG_MK2", label = TranslateCap("weapon_smg_mk2"), ammo = { label = TranslateCap("ammo_rounds"), hash = `AMMO_SMG` }, - tints = Config.DefaultWeaponTints, + tints = Config.MK2WeaponTints, components = { { name = "clip_default", label = TranslateCap("component_clip_default"), hash = `COMPONENT_SMG_MK2_CLIP_01` }, { name = "clip_extended", label = TranslateCap("component_clip_extended"), hash = `COMPONENT_SMG_MK2_CLIP_02` }, @@ -596,7 +631,7 @@ Config.Weapons = { name = "WEAPON_ASSAULTRIFLE_MK2", label = TranslateCap("weapon_assaultrifle_mk2"), ammo = { label = TranslateCap("ammo_rounds"), hash = `AMMO_RIFLE` }, - tints = Config.DefaultWeaponTints, + tints = Config.MK2WeaponTints, components = { { name = "clip_default", label = TranslateCap("component_clip_default"), hash = `COMPONENT_ASSAULTRIFLE_MK2_CLIP_01` }, { name = "clip_extended", label = TranslateCap("component_clip_extended"), hash = `COMPONENT_ASSAULTRIFLE_MK2_CLIP_02` }, @@ -651,7 +686,7 @@ Config.Weapons = { name = "WEAPON_BULLPUPRIFLE_MK2", label = TranslateCap("weapon_bullpuprifle_mk2"), ammo = { label = TranslateCap("ammo_rounds"), hash = `AMMO_RIFLE` }, - tints = Config.DefaultWeaponTints, + tints = Config.MK2WeaponTints, components = { { name = "clip_default", label = TranslateCap("component_clip_default"), hash = `COMPONENT_BULLPUPRIFLE_MK2_CLIP_01` }, { name = "clip_extended", label = TranslateCap("component_clip_extended"), hash = `COMPONENT_BULLPUPRIFLE_MK2_CLIP_02` }, @@ -707,7 +742,7 @@ Config.Weapons = { name = "WEAPON_CARBINERIFLE_MK2", label = TranslateCap("weapon_carbinerifle_mk2"), ammo = { label = TranslateCap("ammo_rounds"), hash = `AMMO_RIFLE` }, - tints = Config.DefaultWeaponTints, + tints = Config.MK2WeaponTints, components = { { name = "clip_default", label = TranslateCap("component_clip_default"), hash = `COMPONENT_CARBINERIFLE_MK2_CLIP_01` }, { name = "clip_extended", label = TranslateCap("component_clip_extended"), hash = `COMPONENT_CARBINERIFLE_MK2_CLIP_02` }, @@ -788,7 +823,7 @@ Config.Weapons = { name = "WEAPON_SPECIALCARBINE_MK2", label = TranslateCap("weapon_specialcarbine_mk2"), ammo = { label = TranslateCap("ammo_rounds"), hash = `AMMO_RIFLE` }, - tints = Config.DefaultWeaponTints, + tints = Config.MK2WeaponTints, components = { { name = "clip_default", label = TranslateCap("component_clip_default"), hash = `COMPONENT_SPECIALCARBINE_MK2_CLIP_01` }, { name = "clip_extended", label = TranslateCap("component_clip_extended"), hash = `COMPONENT_SPECIALCARBINE_MK2_CLIP_02` }, @@ -854,7 +889,7 @@ Config.Weapons = { name = "WEAPON_HEAVYSNIPER_MK2", label = TranslateCap("weapon_heavysniper_mk2"), ammo = { label = TranslateCap("ammo_rounds"), hash = `AMMO_SNIPER` }, - tints = Config.DefaultWeaponTints, + tints = Config.MK2WeaponTints, components = { { name = "clip_default", label = TranslateCap("component_clip_default"), hash = `COMPONENT_HEAVYSNIPER_MK2_CLIP_01` }, { name = "clip_extended", label = TranslateCap("component_clip_extended"), hash = `COMPONENT_HEAVYSNIPER_MK2_CLIP_02` }, @@ -903,7 +938,7 @@ Config.Weapons = { name = "WEAPON_MARKSMANRIFLE_MK2", label = TranslateCap("weapon_marksmanrifle_mk2"), ammo = { label = TranslateCap("ammo_rounds"), hash = `AMMO_SNIPER` }, - tints = Config.DefaultWeaponTints, + tints = Config.MK2WeaponTints, components = { { name = "clip_default", label = TranslateCap("component_clip_default"), hash = `COMPONENT_MARKSMANRIFLE_MK2_CLIP_01` }, { name = "clip_extended", label = TranslateCap("component_clip_extended"), hash = `COMPONENT_MARKSMANRIFLE_MK2_CLIP_02` }, @@ -973,22 +1008,22 @@ Config.Weapons = { { name = "WEAPON_RPG", label = TranslateCap("weapon_rpg"), tints = Config.DefaultWeaponTints, components = {}, ammo = { label = TranslateCap("ammo_rockets"), hash = `AMMO_RPG` } }, { name = "WEAPON_RAYMINIGUN", label = TranslateCap("weapon_rayminigun"), tints = Config.DefaultWeaponTints, components = {}, ammo = { label = TranslateCap("ammo_rounds"), hash = `AMMO_MINIGUN` } }, -- Thrown - { name = "WEAPON_BALL", label = TranslateCap("weapon_ball"), components = {}, ammo = { label = TranslateCap("ammo_ball"), hash = `AMMO_BALL` } }, - { name = "WEAPON_BZGAS", label = TranslateCap("weapon_bzgas"), components = {}, ammo = { label = TranslateCap("ammo_bzgas"), hash = `AMMO_BZGAS` } }, - { name = "WEAPON_FLARE", label = TranslateCap("weapon_flare"), components = {}, ammo = { label = TranslateCap("ammo_flare"), hash = `AMMO_FLARE` } }, - { name = "WEAPON_GRENADE", label = TranslateCap("weapon_grenade"), components = {}, ammo = { label = TranslateCap("ammo_grenade"), hash = `AMMO_GRENADE` } }, - { name = "WEAPON_PETROLCAN", label = TranslateCap("weapon_petrolcan"), components = {}, ammo = { label = TranslateCap("ammo_petrol"), hash = `AMMO_PETROLCAN` } }, - { name = "WEAPON_HAZARDCAN", label = TranslateCap("weapon_hazardcan"), components = {}, ammo = { label = TranslateCap("ammo_petrol"), hash = `AMMO_PETROLCAN` } }, - { name = "WEAPON_MOLOTOV", label = TranslateCap("weapon_molotov"), components = {}, ammo = { label = TranslateCap("ammo_molotov"), hash = `AMMO_MOLOTOV` } }, - { name = "WEAPON_PROXMINE", label = TranslateCap("weapon_proxmine"), components = {}, ammo = { label = TranslateCap("ammo_proxmine"), hash = `AMMO_PROXMINE` } }, - { name = "WEAPON_PIPEBOMB", label = TranslateCap("weapon_pipebomb"), components = {}, ammo = { label = TranslateCap("ammo_pipebomb"), hash = `AMMO_PIPEBOMB` } }, - { name = "WEAPON_SNOWBALL", label = TranslateCap("weapon_snowball"), components = {}, ammo = { label = TranslateCap("ammo_snowball"), hash = `AMMO_SNOWBALL` } }, - { name = "WEAPON_STICKYBOMB", label = TranslateCap("weapon_stickybomb"), components = {}, ammo = { label = TranslateCap("ammo_stickybomb"), hash = `AMMO_STICKYBOMB` } }, - { name = "WEAPON_SMOKEGRENADE", label = TranslateCap("weapon_smokegrenade"), components = {}, ammo = { label = TranslateCap("ammo_smokebomb"), hash = `AMMO_SMOKEGRENADE` } }, + { name = "WEAPON_BALL", label = TranslateCap("weapon_ball"), components = {}, ammo = { label = TranslateCap("ammo_ball"), hash = `AMMO_BALL` }, throwable = true }, + { name = "WEAPON_BZGAS", label = TranslateCap("weapon_bzgas"), components = {}, ammo = { label = TranslateCap("ammo_bzgas"), hash = `AMMO_BZGAS` }, throwable = true }, + { name = "WEAPON_FLARE", label = TranslateCap("weapon_flare"), components = {}, ammo = { label = TranslateCap("ammo_flare"), hash = `AMMO_FLARE` }, throwable = true }, + { name = "WEAPON_GRENADE", label = TranslateCap("weapon_grenade"), components = {}, ammo = { label = TranslateCap("ammo_grenade"), hash = `AMMO_GRENADE` }, throwable = true }, + { name = "WEAPON_PETROLCAN", label = TranslateCap("weapon_petrolcan"), components = {}, ammo = { label = TranslateCap("ammo_petrol"), hash = `AMMO_PETROLCAN` }, throwable = true }, + { name = "WEAPON_HAZARDCAN", label = TranslateCap("weapon_hazardcan"), components = {}, ammo = { label = TranslateCap("ammo_petrol"), hash = `AMMO_PETROLCAN` }, throwable = true }, + { name = "WEAPON_MOLOTOV", label = TranslateCap("weapon_molotov"), components = {}, ammo = { label = TranslateCap("ammo_molotov"), hash = `AMMO_MOLOTOV` }, throwable = true }, + { name = "WEAPON_PROXMINE", label = TranslateCap("weapon_proxmine"), components = {}, ammo = { label = TranslateCap("ammo_proxmine"), hash = `AMMO_PROXMINE` }, throwable = true }, + { name = "WEAPON_PIPEBOMB", label = TranslateCap("weapon_pipebomb"), components = {}, ammo = { label = TranslateCap("ammo_pipebomb"), hash = `AMMO_PIPEBOMB` }, throwable = true }, + { name = "WEAPON_SNOWBALL", label = TranslateCap("weapon_snowball"), components = {}, ammo = { label = TranslateCap("ammo_snowball"), hash = `AMMO_SNOWBALL` }, throwable = true }, + { name = "WEAPON_STICKYBOMB", label = TranslateCap("weapon_stickybomb"), components = {}, ammo = { label = TranslateCap("ammo_stickybomb"), hash = `AMMO_STICKYBOMB` }, throwable = true }, + { name = "WEAPON_SMOKEGRENADE", label = TranslateCap("weapon_smokegrenade"), components = {}, ammo = { label = TranslateCap("ammo_smokebomb"), hash = `AMMO_SMOKEGRENADE` }, throwable = true }, -- Tools { name = "WEAPON_FIREEXTINGUISHER", label = TranslateCap("weapon_fireextinguisher"), components = {}, ammo = { label = TranslateCap("ammo_charge"), hash = `AMMO_FIREEXTINGUISHER` } }, { name = "WEAPON_DIGISCANNER", label = TranslateCap("weapon_digiscanner"), components = {} }, - { name = "GADGET_PARACHUTE", label = TranslateCap("gadget_parachute"), components = {} }, + { name = "GADGET_PARACHUTE", label = TranslateCap("gadget_parachute"), components = {}, throwable = true }, { name = "WEAPON_TACTICALRIFLE", label = TranslateCap("weapon_tactilerifle"), @@ -1022,7 +1057,7 @@ Config.Weapons = { { name = "suppressor", label = TranslateCap("component_suppressor"), hash = `COMPONENT_PISTOLXM3_SUPP` }, }, }, - { name = "WEAPON_ACIDPACKAGE", label = TranslateCap("weapon_acidpackage"), components = {} }, + { name = "WEAPON_ACIDPACKAGE", label = TranslateCap("weapon_acidpackage"), components = {}, throwable = true }, { name = "WEAPON_CANDYCANE", label = TranslateCap("weapon_candycane"), components = {} }, { name = "WEAPON_RAILGUNXM3", diff --git a/[core]/es_extended/shared/functions.lua b/[core]/es_extended/shared/functions.lua index 1a5d00900..184def1bd 100644 --- a/[core]/es_extended/shared/functions.lua +++ b/[core]/es_extended/shared/functions.lua @@ -170,4 +170,43 @@ function ESX.IsFunctionReference(val) local typeVal = type(val) return typeVal == "function" or (typeVal == "table" and type(getmetatable(val)?.__call) == "function") -end \ No newline at end of file +end + +---@param conditionFunc function A function that is repeatedly called until it returns a truthy value or the timeout is exceeded. +---@param errorMessage? string Optional. If set, an error will be thrown with this message if the condition is not met within the timeout. If not set, no error will be thrown. +---@param timeoutMs? number Optional. The maximum time to wait (in milliseconds) for the condition to be met. Defaults to 1000ms. +---@return boolean, any: Returns success status and the returned value of the condition function. +function ESX.Await(conditionFunc, errorMessage, timeoutMs) + timeoutMs = timeoutMs or 1000 + + if timeoutMs < 0 then + error("Timeout should be a positive number.") + end + + if not ESX.IsFunctionReference(conditionFunc) then + error("Condition Function should be a function reference.") + end + + -- since errorMessage is optional, we only validate it if the user provided it. + if errorMessage then + ESX.AssertType(errorMessage, "string", "errorMessage should be a string.") + end + + local invokingResource = GetInvokingResource() + local startTimeMs = GetGameTimer() + while GetGameTimer() - startTimeMs < timeoutMs do + local result = conditionFunc() + + if result then + return true, result + end + + Wait(0) + end + + if errorMessage then + error(("[%s] -> %s"):format(invokingResource, errorMessage)) + end + + return false +end diff --git a/[core]/es_extended/shared/main.lua b/[core]/es_extended/shared/main.lua index 0e78f0cb7..00f775b46 100644 --- a/[core]/es_extended/shared/main.lua +++ b/[core]/es_extended/shared/main.lua @@ -4,9 +4,12 @@ exports("getSharedObject", function() return ESX end) -AddEventHandler("esx:getSharedObject", function() - local Invoke = GetInvokingResource() - error(("Resource ^5%s^1 Used the ^5getSharedObject^1 Event, this event ^1no longer exists!^1 Visit https://documentation.esx-framework.org/tutorials/tutorials-esx/sharedevent for how to fix!"):format(Invoke)) +AddEventHandler("esx:getSharedObject", function(cb) + if ESX.IsFunctionReference(cb) then + cb(ESX) + end + local invokingResource = GetInvokingResource() + print(("^3[WARNING]^0 Resource ^5%s^0 used the ^5getSharedObject^0 event. This is not the recommended way to import ESX. Visit https://documentation.esx-framework.org/tutorials/tutorials-esx/sharedevent to find out why."):format(invokingResource)) end) -- backwards compatibility (DO NOT TOUCH !) diff --git a/[core]/es_extended/shared/modules/table.lua b/[core]/es_extended/shared/modules/table.lua index fc3452005..aacb25840 100644 --- a/[core]/es_extended/shared/modules/table.lua +++ b/[core]/es_extended/shared/modules/table.lua @@ -223,3 +223,11 @@ function ESX.Table.Sort(t, order) end end end + +function ESX.Table.ToArray(table) + local array = {} + for _, v in pairs(table) do + array[#array + 1] = v + end + return array +end diff --git a/[core]/esx_menu_default/html/css/app.css b/[core]/esx_menu_default/html/css/app.css index 4658b79de..a02d2a1d3 100644 --- a/[core]/esx_menu_default/html/css/app.css +++ b/[core]/esx_menu_default/html/css/app.css @@ -9,8 +9,9 @@ min-width: 350px; color: #fff; position: absolute; - background: rgba(33, 33, 33, 0); + background: rgba(15, 15, 15, 0.0); text-align: center; + border-radius: 5px; } .head { @@ -18,9 +19,9 @@ overflow: hidden; padding-bottom: 3px; text-align: center; - margin-bottom: 5px; white-space: nowrap; - background: rgba(10, 10, 10, 0.9); + background: rgba(10, 10, 10, 1); + border-bottom: 2px solid #fb9b04; } .menu .head { @@ -47,16 +48,14 @@ font-size: 13px; height: 16px; text-indent: 5px; - margin-top: 5px; - background: rgba(40, 40, 40, 0.8); - color: rgb(202, 202, 202); - border-radius: 5px; - margin-bottom: 6px; + background: rgba(30, 30, 30, 0.9); + color: rgb(243, 243, 243); } + .menu .menu-items .menu-item.selected { - border: 1px solid rgba(55, 55, 55, 0.9); - background: rgba(20, 20, 20, 0.9); + border: 1px solid #fb9c04ec; + background: rgba(15, 15, 15, 0.9); color: rgba(243, 243, 243); letter-spacing: 0.2px; font-weight: 500; @@ -68,7 +67,7 @@ } .menu.align-top-left { - left: 3rem; + left: 4rem; top: 0; } @@ -99,7 +98,7 @@ } .menu.align-bottom-left { - left: 3rem; + left: 4rem; bottom: 0; } diff --git a/[core]/esx_multicharacter/locales/pl.lua b/[core]/esx_multicharacter/locales/pl.lua new file mode 100644 index 000000000..b71f35fd6 --- /dev/null +++ b/[core]/esx_multicharacter/locales/pl.lua @@ -0,0 +1,33 @@ +Locales["pl"] = { + ["male"] = "Mężczyzna", + ["female"] = "Kobieta", + ["select_char"] = "Wybierz postać", + ["select_char_description"] = "Wybierz postać, którą chcesz grać.", + ["create_char"] = "Nowa postać", + ["char_play"] = "Graj", + ["char_play_description"] = "Przejdź do miasta.", + ["char_disabled"] = "Wyłączona", + ["char_disabled_description"] = "Ta postać jest niedostępna.", + ["char_delete"] = "Usuń", + ["char_delete_description"] = "Trwale usuń tę postać.", + ["char_delete_confirmation"] = "Potwierdz usunięcie", + ["char_delete_confirmation_description"] = "Czy na pewno chcesz usunąć wybraną postać?", + ["char_delete_yes_description"] = "Tak, jestem pewien, że chcę usunąć wybraną postać", + ["char_delete_no_description"] = "Nie, wróć do opcji postaci", + ["character"] = "Postać: %s", + ["return"] = "Powrót", + ["return_description"] = "Wróć do wyboru postaci.", + ["command_setslots"] = "Ustaw liczbę slotów dla wielu postaci", + ["command_remslots"] = "Usuń liczbę slotów dla wielu postaci", + ["command_enablechar"] = "Włącz określoną postać", + ["command_disablechar"] = "Wyłącz określoną postać", + ["command_charslot"] = "Numer slotu postaci", + ["command_identifier"] = "Identyfikator postaci", + ["command_slots"] = "# liczba slotów", + ["slotsadd"] = "Ustawiłeś %s slotów dla %s", + ["slotsrem"] = "Usunąłeś sloty dla %s", + ["charenabled"] = "Włączyłeś postać #%s gracza %s", + ["chardisabled"] = "Wyłączyłeś postać #%s gracza %s", + ["charnotfound"] = "Postać #%s gracza %s nie istnieje", + +} diff --git a/[core]/esx_multicharacter/server/modules/functions.lua b/[core]/esx_multicharacter/server/modules/functions.lua index 47aeb5b47..f1750e2fb 100644 --- a/[core]/esx_multicharacter/server/modules/functions.lua +++ b/[core]/esx_multicharacter/server/modules/functions.lua @@ -25,7 +25,8 @@ function Server:OnConnecting(source, deferrals) deferrals.defer() Wait(0) -- Required local identifier = self:GetIdentifier(source) - + + -- luacheck: ignore if not SetEntityOrphanMode then return deferrals.done(("[ESX] ESX Requires a minimum Artifact version of 10188, Please update your server.")) end diff --git a/[core]/esx_notify/nui/css/style.css b/[core]/esx_notify/nui/css/style.css index 08fc8c539..6dc292903 100644 --- a/[core]/esx_notify/nui/css/style.css +++ b/[core]/esx_notify/nui/css/style.css @@ -32,8 +32,8 @@ body { min-width: 20rem; width: fit-content; height: 3.5rem; - background: rgba(5, 5, 5, 0.9); - border-radius: 0.5rem; + background: rgba(15, 15, 15, 0.9); + border-radius: 0.4rem; margin-top: 0.5rem; animation: anim 300ms ease-in-out; align-items: center; @@ -47,24 +47,27 @@ body { #root .icon { float: left; - color: #fff; } #root .text { display: inline-block; + color: #fff; margin-left: 0.5rem; } #root .error { - border-bottom: 3px solid #c0392b; + color: #c0392b; + border: 2px solid #c0392b; } #root .success { - border-bottom: 3px solid #2ecc71; + color: #2ecc71; + border: 2px solid #2ecc71; } #root .info { - border-bottom: 3px solid #2980b9; + color: #fb9b04; + border: 2px solid #fb9b04; } .material-symbols-outlined { diff --git a/[core]/esx_notify/nui/js/script.js b/[core]/esx_notify/nui/js/script.js index edb90cb0f..640025219 100644 --- a/[core]/esx_notify/nui/js/script.js +++ b/[core]/esx_notify/nui/js/script.js @@ -15,15 +15,15 @@ const types = { // the color codes example `i ~r~love~s~ donuts` const codes = { - "~r~": "red", + "~r~": "#c0392b", "~b~": "#378cbf", - "~g~": "green", + "~g~": "#2ecc71", "~y~": "yellow", "~p~": "purple", "~c~": "grey", "~m~": "#212121", "~u~": "black", - "~o~": "orange", + "~o~": "#fb9b04", }; w.addEventListener("message", (event) => { @@ -57,8 +57,9 @@ notification = (data) => { } } + const id = Math.floor(Math.random() * Math.random()); const notification = $(` -
+
${types[data.type] ? types[data.type]["icon"] : types["info"]["icon"]}

${data["message"]}

@@ -67,8 +68,16 @@ notification = (data) => { `).appendTo(`#root`); setTimeout(() => { - notification.fadeOut(700); - }, data.length); + document.getElementById(id).classList.remove("fadeIn"); + }, 300); + + setTimeout(() => { + document.getElementById(id).classList.add("fadeOut"); + + setTimeout(() => { + document.getElementById(id).remove(); + }, 400); + },data.length); return notification; }; diff --git a/[core]/esx_progressbar/nui/index.html b/[core]/esx_progressbar/nui/index.html index 0ea3bd931..beb84d1b0 100644 --- a/[core]/esx_progressbar/nui/index.html +++ b/[core]/esx_progressbar/nui/index.html @@ -28,7 +28,7 @@ min-width: 15%; width: fit-content; height: 45px; - background-color: rgba(5, 5, 5, 0.8); + background-color: rgba(15, 15, 15, 0.9); border-radius: 5px; animation: growDown 300ms ease-in-out; padding-right: 10px; @@ -41,8 +41,8 @@ right: 0; height: 2px; width: 100%; - border-radius: 20px; - background: linear-gradient(to right, #0052d4, #4364f7, #6fb1fc); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */ + border-radius: 15px; + background: linear-gradient(to right, #b84f05, #de7301, #fb9b04); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */ } .icon { @@ -61,7 +61,7 @@ p { flex: auto; word-wrap: break-word; - margin-left: 30px; + margin-left: 35px; margin-top: 15px; } @@ -69,6 +69,7 @@ float: left; margin-left: 5px; font-size: 20px; + color: #fb9b04; } @keyframes growDown { diff --git a/[core]/esx_progressbar/nui/js/script.js b/[core]/esx_progressbar/nui/js/script.js index 330fefb33..9ea8ec273 100644 --- a/[core]/esx_progressbar/nui/js/script.js +++ b/[core]/esx_progressbar/nui/js/script.js @@ -1,13 +1,13 @@ const codes = { - "~r~": "red", + "~r~": "#c0392b", "~b~": "#378cbf", - "~g~": "green", + "~g~": "#2ecc71", "~y~": "yellow", "~p~": "purple", "~c~": "grey", "~m~": "#212121", "~u~": "black", - "~o~": "orange", + "~o~": "#fb9b04", }; const elems = { diff --git a/[core]/esx_skin/client/modules/menu.lua b/[core]/esx_skin/client/modules/menu.lua index 410146d0e..b6de67456 100644 --- a/[core]/esx_skin/client/modules/menu.lua +++ b/[core]/esx_skin/client/modules/menu.lua @@ -38,6 +38,7 @@ end function Menu:InsertElements() local playerPed = PlayerPedId() + self.elements = {} for i = 1, #self.components, 1 do local value = self.components[i].value local componentId = self.components[i].componentId @@ -51,15 +52,12 @@ function Menu:InsertElements() data.type = "slider" data.max = self.maxValues[self.components[i].name] - if not self.elements then - self.elements = {} - end self.elements[#self.elements + 1] = data end end function Menu:Submit(data, menu) - Skin.last = exports["skinchanger"]:GetSkin() + Skin.Last = exports["skinchanger"]:GetSkin() self.submitCb(data, menu) Camera:Destroy() end @@ -67,7 +65,7 @@ end function Menu:Cancel(data, menu) menu.close() Camera:Destroy() - TriggerEvent("skinchanger:loadSkin", Skin.last) + TriggerEvent("skinchanger:loadSkin", Skin.Last) if self.cancelCb then self.cancelCb(data, menu) @@ -125,7 +123,7 @@ function Menu:Open(submit, cancel, restrict) self.submitCb = submit self.cancelCb = cancel self.restricted = restrict - Skin.last = exports["skinchanger"]:GetSkin() + Skin.Last = exports["skinchanger"]:GetSkin() self.components, self.maxValues = exports["skinchanger"]:GetData() if restrict then @@ -134,15 +132,15 @@ function Menu:Open(submit, cancel, restrict) self:InsertElements() - self.zoomOffset = self.components[1].zoomOffset - self.camOffset = self.components[1].camOffset + Skin.zoomOffset = self.components[1].zoomOffset + Skin.camOffset = self.components[1].camOffset Camera:Create() self:ESXMenu() end function Menu:Saveable(submitCb, cancelCb, restrict) - Skin.last = exports["skinchanger"]:GetSkin() + Skin.Last = exports["skinchanger"]:GetSkin() self:Open(function(data, menu) menu.close() diff --git a/[core]/esx_skin/server/main.lua b/[core]/esx_skin/server/main.lua index 6538feb5b..60ec63dfe 100644 --- a/[core]/esx_skin/server/main.lua +++ b/[core]/esx_skin/server/main.lua @@ -1,4 +1,7 @@ RegisterNetEvent("esx_skin:save", function(skin) + if not skin or type(skin) ~= "table" then + return + end local xPlayer = ESX.GetPlayerFromId(source) if not ESX.GetConfig().CustomInventory then diff --git a/[core]/esx_textui/nui/css/style.css b/[core]/esx_textui/nui/css/style.css index 185fa8951..bf0d00b79 100644 --- a/[core]/esx_textui/nui/css/style.css +++ b/[core]/esx_textui/nui/css/style.css @@ -1,6 +1,6 @@ :root { --color: white; - --bgColor: #212121; + --bgColor: rgba(15, 15, 15, 0.9); } * { @@ -24,22 +24,32 @@ body { min-width: 15%; width: fit-content; height: 50px; - background: rgba(5, 5, 5, 0.9); + background: rgba(15, 15, 15, 0.9); border-radius: 0.5rem; - animation: growDown 300ms ease-in-out; align-items: center; } +.fadeIn { + animation: growUp 300ms ease-in-out; +} + +.fadeOut { + animation: growDown 300ms ease-in-out; +} + .error { - border-left: 5px solid #c0392b; + border-left: 3px solid #c0392b; + border-right: 3px solid #c0392b; } .success { - border-left: 5px solid #2ecc71; + border-left: 3px solid #2ecc71; + border-right: 3px solid #2ecc71; } .info { - border-left: 5px solid #2980b9; + border-left: 3px solid #fb9b04; + border-right: 3px solid #fb9b04; } .innerText { @@ -61,10 +71,22 @@ body { } @keyframes growDown { + 0% { + transform: scaleY(1); + } + 50% { + transform: scaleY(1.1); + } + 100% { + transform: scaleY(0); + } +} + +@keyframes growUp { 0% { transform: scaleY(0); } - 80% { + 50% { transform: scaleY(1.1); } 100% { diff --git a/[core]/esx_textui/nui/js/script.js b/[core]/esx_textui/nui/js/script.js index 2b625e7a9..ffc54faa1 100644 --- a/[core]/esx_textui/nui/js/script.js +++ b/[core]/esx_textui/nui/js/script.js @@ -1,6 +1,6 @@ const w = window; const doc = document; -let lastType = ""; +let lastType = {}; // Gets the current icon it needs to use. const types = { @@ -20,21 +20,21 @@ const types = { // the color codes example `i ~r~love~s~ donuts` const codes = { - "~r~": "red", + "~r~": "#c0392b", "~b~": "#378cbf", - "~g~": "green", + "~g~": "#2ecc71", "~y~": "yellow", "~p~": "purple", "~c~": "grey", "~m~": "#212121", "~u~": "black", - "~o~": "orange", + "~o~": "#fb9b04", }; w.addEventListener("message", (event) => { if (event.data.action === "show") { - if (lastType) { - doc.getElementById(lastType).style.display = "none"; + if (lastType.id !== undefined) { + doc.getElementById(lastType["id"]).style.display = "none"; notification({ type: event.data.type, message: event.data.message, @@ -47,7 +47,12 @@ w.addEventListener("message", (event) => { } } else if (event.data.action === "hide") { if (lastType !== "") { - doc.getElementById(lastType).style.display = "none"; + doc.getElementById(lastType["id"]).classList.add("fadeOut"); + setTimeout(() => { + doc.getElementById(lastType["id"]).classList.remove("fadeOut"); + doc.getElementById(lastType["id"]).style.display = "none"; + doc.getElementById(lastType["message"]).innerHTML = ""; + }, 300); } else { console.log("There isn't a textUI displaying!?"); } @@ -78,6 +83,10 @@ notification = (data) => { } doc.getElementById(types[data.type]["id"]).style.display = "block"; - lastType = types[data.type]["id"]; - doc.getElementById(types[data.type]["message"]).innerHTML = data["message"]; + doc.getElementById(types[data.type]["id"]).classList.add("fadeIn"); + setTimeout(() => { + doc.getElementById(types[data.type]["id"]).classList.remove("fadeIn"); + lastType = types[data.type]; + doc.getElementById(types[data.type]["message"]).innerHTML = data["message"]; + }, 300); };